Files
smoothschedule/DEPLOYMENT.md
poduck f8d8419622 Improve deployment process and add login redirect logic
Deployment improvements:
- Add template env files (.envs.example/) for documentation
- Create init-production.sh for one-time server setup
- Create build-activepieces.sh for building/deploying AP image
- Update deploy.sh with --deploy-ap flag
- Make custom-pieces-metadata.sql idempotent
- Update DEPLOYMENT.md with comprehensive instructions

Frontend:
- Redirect logged-in business owners from root domain to tenant dashboard
- Redirect logged-in users from /login to /dashboard on their tenant
- Log out customers on wrong subdomain instead of redirecting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 23:13:56 -05:00

12 KiB

SmoothSchedule Production Deployment Guide

This guide covers deploying SmoothSchedule to a production server.

Table of Contents

  1. Prerequisites
  2. Quick Reference
  3. Initial Server Setup
  4. Regular Deployments
  5. Activepieces Updates
  6. Troubleshooting
  7. Maintenance

Prerequisites

Server Requirements

  • Ubuntu 20.04+ or Debian 11+
  • 4GB RAM minimum (2GB works but cannot build Activepieces image)
  • 40GB disk space
  • Docker and Docker Compose v2 installed
  • Domain with wildcard DNS configured

Local Requirements (for deployment)

  • Git access to the repository
  • SSH access to the production server
  • Docker (for building Activepieces image)

Required Accounts/Services

  • DigitalOcean Spaces (for static/media files)
  • Stripe (for payments)
  • Twilio (for SMS/phone features)
  • OpenAI API (optional, for Activepieces AI copilot)

Quick Reference

# Regular deployment (after initial setup)
./deploy.sh

# Deploy with Activepieces image rebuild
./deploy.sh --deploy-ap

# Deploy specific services only
./deploy.sh django nginx

# Skip migrations (config changes only)
./deploy.sh --no-migrate

Initial Server Setup (First Time Only)

1. Server Preparation

# SSH into production server
ssh your-user@your-server

# Install Docker (if not already installed)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

# Logout and login again for group changes
exit
ssh your-user@your-server

2. Clone Repository

git clone https://your-repo-url ~/smoothschedule
cd ~/smoothschedule/smoothschedule

3. Create Environment Files

Copy the template files and fill in your values:

mkdir -p .envs/.production
cp .envs.example/.django .envs/.production/.django
cp .envs.example/.postgres .envs/.production/.postgres
cp .envs.example/.activepieces .envs/.production/.activepieces

Edit each file with your production values:

nano .envs/.production/.django
nano .envs/.production/.postgres
nano .envs/.production/.activepieces

Key values to configure:

File Variable Description
.django DJANGO_SECRET_KEY Generate: openssl rand -hex 32
.django DJANGO_ALLOWED_HOSTS .yourdomain.com
.django STRIPE_* Your Stripe keys (live keys for production)
.django TWILIO_* Your Twilio credentials
.django AWS_* DigitalOcean Spaces credentials
.postgres POSTGRES_USER Generate random username
.postgres POSTGRES_PASSWORD Generate: openssl rand -hex 32
.activepieces AP_JWT_SECRET Generate: openssl rand -hex 32
.activepieces AP_ENCRYPTION_KEY Generate: openssl rand -hex 16
.activepieces AP_POSTGRES_USERNAME Generate random username
.activepieces AP_POSTGRES_PASSWORD Generate: openssl rand -hex 32

Important: AP_JWT_SECRET must be copied to .django as well!

4. DNS Configuration

Configure these DNS records:

Type    Name                  Value                TTL
A       yourdomain.com        YOUR_SERVER_IP       300
A       *.yourdomain.com      YOUR_SERVER_IP       300
CNAME   www                   yourdomain.com       300

5. Build Activepieces Image (on your local machine)

The production server typically cannot build this image (requires 4GB+ RAM):

# On your LOCAL machine, not the server
cd ~/smoothschedule
./scripts/build-activepieces.sh deploy

Or manually:

cd activepieces-fork
docker build -t smoothschedule_production_activepieces .
docker save smoothschedule_production_activepieces | gzip > /tmp/ap.tar.gz
scp /tmp/ap.tar.gz your-user@your-server:/tmp/
ssh your-user@your-server 'gunzip -c /tmp/ap.tar.gz | docker load'

6. Run Initialization Script

# On the server
cd ~/smoothschedule/smoothschedule
chmod +x scripts/init-production.sh
./scripts/init-production.sh

This script will:

  1. Verify environment files
  2. Generate any missing security keys
  3. Start PostgreSQL and Redis
  4. Create the Activepieces database
  5. Start all services
  6. Run Django migrations
  7. Guide you through Activepieces platform setup

7. Complete Activepieces Platform Setup

After the init script completes:

  1. Visit https://automations.yourdomain.com
  2. Create an admin account (this creates the platform)
  3. Get the platform ID:
    docker compose -f docker-compose.production.yml exec postgres \
      psql -U <ap_db_user> -d activepieces -c "SELECT id FROM platform"
    
  4. Update AP_PLATFORM_ID in both:
    • .envs/.production/.activepieces
    • .envs/.production/.django
  5. Restart services:
    docker compose -f docker-compose.production.yml restart
    

8. Create First Tenant

docker compose -f docker-compose.production.yml exec django python manage.py shell
from smoothschedule.identity.core.models import Tenant, Domain

# Create tenant
tenant = Tenant.objects.create(
    name="Demo Business",
    subdomain="demo",
    schema_name="demo"
)

# Create domain
Domain.objects.create(
    tenant=tenant,
    domain="demo.yourdomain.com",
    is_primary=True
)

9. Provision Activepieces Connection

docker compose -f docker-compose.production.yml exec django \
  python manage.py provision_ap_connections --tenant demo

10. Verify Deployment

# Check all containers are running
docker compose -f docker-compose.production.yml ps

# Test endpoints
curl https://yourdomain.com/api/
curl https://platform.yourdomain.com/
curl https://automations.yourdomain.com/api/v1/health

Regular Deployments

After initial setup, deployments are simple:

# From your local machine
cd ~/smoothschedule

# Commit and push your changes
git add .
git commit -m "Your changes"
git push

# Deploy
./deploy.sh

Deployment Options

Command Description
./deploy.sh Full deployment with migrations
./deploy.sh --no-migrate Deploy without running migrations
./deploy.sh --deploy-ap Rebuild and deploy Activepieces image
./deploy.sh django Rebuild only Django container
./deploy.sh nginx traefik Rebuild specific services

What the Deploy Script Does

  1. Checks for uncommitted changes
  2. Verifies changes are pushed to remote
  3. (If --deploy-ap) Builds and transfers Activepieces image
  4. SSHs to server and pulls latest code
  5. Backs up and restores .envs directory
  6. Builds Docker images
  7. Starts containers
  8. Sets up Activepieces database (if needed)
  9. Runs Django migrations (unless --no-migrate)
  10. Seeds platform plugins for all tenants

Activepieces Updates

When you modify custom pieces (in activepieces-fork/):

  1. Make your changes to piece code
  2. Commit and push
  3. Deploy with the image flag:
    ./deploy.sh --deploy-ap
    

The Activepieces container will:

  1. Start with the new image
  2. Run publish-pieces.sh to register custom pieces
  3. Insert piece metadata into the database

Custom Pieces

Custom pieces are located in:

  • activepieces-fork/packages/pieces/community/smoothschedule/ - Main SmoothSchedule piece
  • activepieces-fork/packages/pieces/community/python-code/ - Python code execution
  • activepieces-fork/packages/pieces/community/ruby-code/ - Ruby code execution

Piece metadata is registered via:

  • activepieces-fork/custom-pieces-metadata.sql - Database registration
  • activepieces-fork/publish-pieces.sh - Container startup script

Troubleshooting

View Logs

# All services
docker compose -f docker-compose.production.yml logs -f

# Specific service
docker compose -f docker-compose.production.yml logs -f django
docker compose -f docker-compose.production.yml logs -f activepieces
docker compose -f docker-compose.production.yml logs -f traefik

Restart Services

# All services
docker compose -f docker-compose.production.yml restart

# Specific service
docker compose -f docker-compose.production.yml restart django
docker compose -f docker-compose.production.yml restart activepieces

Django Shell

docker compose -f docker-compose.production.yml exec django python manage.py shell

Database Access

# SmoothSchedule database
docker compose -f docker-compose.production.yml exec postgres \
  psql -U <postgres_user> -d smoothschedule

# Activepieces database
docker compose -f docker-compose.production.yml exec postgres \
  psql -U <ap_user> -d activepieces

Common Issues

1. Activepieces pieces not showing up

# Check if platform exists
docker compose -f docker-compose.production.yml exec postgres \
  psql -U <ap_user> -d activepieces -c "SELECT id FROM platform"

# Restart to re-run piece registration
docker compose -f docker-compose.production.yml restart activepieces

# Check logs for errors
docker compose -f docker-compose.production.yml logs activepieces | grep -i error

2. 502 Bad Gateway

  • Service is still starting, wait a moment
  • Check container health: docker compose ps
  • Check logs for errors

3. Database connection errors

  • Verify credentials in .envs/.production/
  • Ensure PostgreSQL is running: docker compose ps postgres

4. Activepieces embedding not working

  • Verify AP_JWT_SECRET matches in both .django and .activepieces
  • Verify AP_PLATFORM_ID is set correctly in both files
  • Check AP_EMBEDDING_ENABLED=true in .activepieces

5. SSL certificate issues

# Check Traefik logs
docker compose -f docker-compose.production.yml logs traefik

# Verify DNS is pointing to server
dig yourdomain.com +short

# Ensure ports 80 and 443 are open
sudo ufw allow 80
sudo ufw allow 443

Maintenance

Backups

# Database backup
docker compose -f docker-compose.production.yml exec postgres backup

# List backups
docker compose -f docker-compose.production.yml exec postgres backups

# Restore from backup
docker compose -f docker-compose.production.yml exec postgres restore backup_filename.sql.gz

Monitoring

  • Flower Dashboard: https://yourdomain.com:5555 - Celery task monitoring
  • Container Status: docker compose ps
  • Resource Usage: docker stats

Security Checklist

  • SSL/HTTPS enabled via Let's Encrypt (automatic with Traefik)
  • All secret keys are unique random values
  • Database passwords are strong
  • Flower dashboard is password protected
  • Firewall configured (UFW)
  • SSH key-based authentication only
  • Regular backups configured
  • Monitoring/alerting set up

File Structure

smoothschedule/
├── deploy.sh                    # Main deployment script
├── DEPLOYMENT.md                # This file
├── scripts/
│   └── build-activepieces.sh    # Activepieces image builder
├── smoothschedule/
│   ├── docker-compose.production.yml
│   ├── scripts/
│   │   └── init-production.sh   # One-time initialization
│   ├── .envs/
│   │   └── .production/         # Production secrets (NOT in git)
│   │       ├── .django
│   │       ├── .postgres
│   │       └── .activepieces
│   └── .envs.example/           # Template files (in git)
│       ├── .django
│       ├── .postgres
│       └── .activepieces
└── activepieces-fork/
    ├── Dockerfile
    ├── custom-pieces-metadata.sql
    ├── publish-pieces.sh
    └── packages/pieces/community/
        ├── smoothschedule/      # Main custom piece
        ├── python-code/
        └── ruby-code/