Skip to content

Tenant Deployment Guide

Complete guide to deploying a new Campaign Brain tenant.

Overview

Deploying a tenant involves:

  1. Creating the tenant record
  2. Cloning the cbapp repository
  3. Setting up the environment
  4. Running database migrations
  5. Starting services
  6. Configuring Nginx (optional)

Prerequisites

  • Tenant Manager running
  • GitHub SSH access configured
  • Ports 32300+ available
  • Nginx installed (for production)

Step 1: Create Tenant

Via Dashboard

  1. Navigate to http://localhost:32200
  2. Click "New Tenant"
  3. Fill in details:
  4. Name: "My Campaign"
  5. Slug: "my-campaign" (used for services)
  6. Domain: "mycampaign.example.com"
  7. API Domain: "api.mycampaign.example.com"

Via API

# Get auth token
TOKEN=$(curl -s -X POST http://localhost:32201/api/auth/login \
  -d "username=admin&password=admin123" | jq -r '.access_token')

# Create tenant
curl -X POST http://localhost:32201/api/tenants \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Campaign",
    "slug": "my-campaign",
    "domain": "mycampaign.example.com",
    "api_domain": "api.mycampaign.example.com"
  }'

Step 2: Deploy

# Deploy the tenant
curl -X POST http://localhost:32201/api/tenants/{tenant_id}/deploy \
  -H "Authorization: Bearer $TOKEN"

The deployment process:

  1. Creates directory at /home/bisenbek/projects/nominate/{slug}/
  2. Clones cbapp from GitHub
  3. Creates Python virtual environment
  4. Installs dependencies
  5. Generates .env configuration
  6. Runs database migrations
  7. Creates systemd services
  8. Starts services

Step 3: Verify

# Check service status
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:32201/api/tenants/{tenant_id}/services/status

# Expected response:
{
  "api": "active",
  "frontend": "active"
}

# Test API
curl http://localhost:{api_port}/docs

Step 4: Configure Nginx (Production)

Create Nginx configuration:

# /etc/nginx/sites-available/my-campaign
server {
    listen 80;
    server_name mycampaign.example.com;

    location / {
        proxy_pass http://localhost:32300;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

server {
    listen 80;
    server_name api.mycampaign.example.com;

    location / {
        proxy_pass http://localhost:32301;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Enable and reload:

sudo ln -s /etc/nginx/sites-available/my-campaign /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Post-Deployment

1. Configure Branding

Upload logos and set theme colors. See Logo Guide.

2. Import Data

Use the List Loader to import voter/contact data. See List Loader Guide.

3. Create Users

Add users for the campaign team.

Troubleshooting

Services Won't Start

# Check logs
sudo journalctl -u {slug}-api -f
sudo journalctl -u {slug}-frontend -f

# Common issues:
# - Port already in use
# - Missing dependencies
# - Database permissions

Port Conflicts

# Find what's using a port
lsof -i :32300

# Kill and restart
sudo systemctl stop {slug}-api {slug}-frontend
sudo systemctl start {slug}-api {slug}-frontend

See Also