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>
12 KiB
12 KiB
SmoothSchedule Production Deployment Guide
This guide covers deploying SmoothSchedule to a production server.
Table of Contents
- Prerequisites
- Quick Reference
- Initial Server Setup
- Regular Deployments
- Activepieces Updates
- Troubleshooting
- 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:
- Verify environment files
- Generate any missing security keys
- Start PostgreSQL and Redis
- Create the Activepieces database
- Start all services
- Run Django migrations
- Guide you through Activepieces platform setup
7. Complete Activepieces Platform Setup
After the init script completes:
- Visit
https://automations.yourdomain.com - Create an admin account (this creates the platform)
- 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" - Update
AP_PLATFORM_IDin both:.envs/.production/.activepieces.envs/.production/.django
- 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
- Checks for uncommitted changes
- Verifies changes are pushed to remote
- (If
--deploy-ap) Builds and transfers Activepieces image - SSHs to server and pulls latest code
- Backs up and restores
.envsdirectory - Builds Docker images
- Starts containers
- Sets up Activepieces database (if needed)
- Runs Django migrations (unless
--no-migrate) - Seeds platform plugins for all tenants
Activepieces Updates
When you modify custom pieces (in activepieces-fork/):
- Make your changes to piece code
- Commit and push
- Deploy with the image flag:
./deploy.sh --deploy-ap
The Activepieces container will:
- Start with the new image
- Run
publish-pieces.shto register custom pieces - Insert piece metadata into the database
Custom Pieces
Custom pieces are located in:
activepieces-fork/packages/pieces/community/smoothschedule/- Main SmoothSchedule pieceactivepieces-fork/packages/pieces/community/python-code/- Python code executionactivepieces-fork/packages/pieces/community/ruby-code/- Ruby code execution
Piece metadata is registered via:
activepieces-fork/custom-pieces-metadata.sql- Database registrationactivepieces-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_SECRETmatches in both.djangoand.activepieces - Verify
AP_PLATFORM_IDis set correctly in both files - Check
AP_EMBEDDING_ENABLED=truein.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/