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>
This commit is contained in:
712
DEPLOYMENT.md
712
DEPLOYMENT.md
@@ -1,322 +1,381 @@
|
||||
# SmoothSchedule Production Deployment Guide
|
||||
|
||||
This guide covers deploying SmoothSchedule to a production server.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Prerequisites](#prerequisites)
|
||||
2. [Quick Reference](#quick-reference)
|
||||
3. [Initial Server Setup](#initial-server-setup-first-time-only)
|
||||
4. [Regular Deployments](#regular-deployments)
|
||||
5. [Activepieces Updates](#activepieces-updates)
|
||||
6. [Troubleshooting](#troubleshooting)
|
||||
7. [Maintenance](#maintenance)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Server Requirements
|
||||
- Ubuntu/Debian Linux server
|
||||
- Minimum 2GB RAM, 20GB disk space
|
||||
- Docker and Docker Compose installed
|
||||
- Domain name pointed to server IP: `smoothschedule.com`
|
||||
- DNS configured with wildcard subdomain: `*.smoothschedule.com`
|
||||
- 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
|
||||
- [x] DigitalOcean Spaces (already configured)
|
||||
- Access Key: DO801P4R8QXYMY4CE8WZ
|
||||
- Bucket: smoothschedule
|
||||
- Region: nyc3
|
||||
- [ ] Email service (optional - Mailgun or SMTP)
|
||||
- [ ] Sentry (optional - error tracking)
|
||||
- DigitalOcean Spaces (for static/media files)
|
||||
- Stripe (for payments)
|
||||
- Twilio (for SMS/phone features)
|
||||
- OpenAI API (optional, for Activepieces AI copilot)
|
||||
|
||||
## Pre-Deployment Checklist
|
||||
|
||||
### 1. DigitalOcean Spaces Setup
|
||||
## Quick Reference
|
||||
|
||||
```bash
|
||||
# Create the bucket (if not already created)
|
||||
aws --profile do-tor1 s3 mb s3://smoothschedule
|
||||
# Regular deployment (after initial setup)
|
||||
./deploy.sh
|
||||
|
||||
# Set bucket to public-read for static/media files
|
||||
aws --profile do-tor1 s3api put-bucket-acl \
|
||||
--bucket smoothschedule \
|
||||
--acl public-read
|
||||
# Deploy with Activepieces image rebuild
|
||||
./deploy.sh --deploy-ap
|
||||
|
||||
# Configure CORS (for frontend uploads)
|
||||
cat > cors.json <<EOF
|
||||
{
|
||||
"CORSRules": [
|
||||
{
|
||||
"AllowedOrigins": ["https://smoothschedule.com", "https://*.smoothschedule.com"],
|
||||
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
|
||||
"AllowedHeaders": ["*"],
|
||||
"MaxAgeSeconds": 3000
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
# Deploy specific services only
|
||||
./deploy.sh django nginx
|
||||
|
||||
aws --profile do-tor1 s3api put-bucket-cors \
|
||||
--bucket smoothschedule \
|
||||
--cors-configuration file://cors.json
|
||||
# Skip migrations (config changes only)
|
||||
./deploy.sh --no-migrate
|
||||
```
|
||||
|
||||
### 2. DNS Configuration
|
||||
## Initial Server Setup (First Time Only)
|
||||
|
||||
Configure these DNS records at your domain registrar:
|
||||
|
||||
```
|
||||
Type Name Value TTL
|
||||
A smoothschedule.com YOUR_SERVER_IP 300
|
||||
A *.smoothschedule.com YOUR_SERVER_IP 300
|
||||
CNAME www smoothschedule.com 300
|
||||
```
|
||||
|
||||
### 3. Environment Variables Review
|
||||
|
||||
**Backend** (`.envs/.production/.django`):
|
||||
- [x] DJANGO_SECRET_KEY - Set
|
||||
- [x] DJANGO_ALLOWED_HOSTS - Set to `.smoothschedule.com`
|
||||
- [x] DJANGO_AWS_ACCESS_KEY_ID - Set
|
||||
- [x] DJANGO_AWS_SECRET_ACCESS_KEY - Set
|
||||
- [x] DJANGO_AWS_STORAGE_BUCKET_NAME - Set to `smoothschedule`
|
||||
- [x] DJANGO_AWS_S3_ENDPOINT_URL - Set to `https://nyc3.digitaloceanspaces.com`
|
||||
- [x] DJANGO_AWS_S3_REGION_NAME - Set to `nyc3`
|
||||
- [ ] MAILGUN_API_KEY - Optional (for email)
|
||||
- [ ] MAILGUN_DOMAIN - Optional (for email)
|
||||
- [ ] SENTRY_DSN - Optional (for error tracking)
|
||||
|
||||
**Frontend** (`.env.production`):
|
||||
- [x] VITE_API_URL - Set to `https://smoothschedule.com/api`
|
||||
|
||||
## Deployment Steps
|
||||
|
||||
### Step 1: Server Preparation
|
||||
### 1. Server Preparation
|
||||
|
||||
```bash
|
||||
# SSH into production server
|
||||
ssh poduck@smoothschedule.com
|
||||
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
|
||||
|
||||
# Install Docker Compose
|
||||
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Logout and login again for group changes to take effect
|
||||
# Logout and login again for group changes
|
||||
exit
|
||||
ssh poduck@smoothschedule.com
|
||||
ssh your-user@your-server
|
||||
```
|
||||
|
||||
### Step 2: Deploy Backend (Django)
|
||||
### 2. Clone Repository
|
||||
|
||||
```bash
|
||||
# Create deployment directory
|
||||
mkdir -p ~/smoothschedule
|
||||
git clone https://your-repo-url ~/smoothschedule
|
||||
cd ~/smoothschedule/smoothschedule
|
||||
```
|
||||
|
||||
### 3. Create Environment Files
|
||||
|
||||
Copy the template files and fill in your values:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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):
|
||||
|
||||
```bash
|
||||
# On your LOCAL machine, not the server
|
||||
cd ~/smoothschedule
|
||||
|
||||
# Clone the repository (or upload files via rsync/git)
|
||||
# Option A: Clone from Git
|
||||
git clone <your-repo-url> .
|
||||
git checkout main
|
||||
|
||||
# Option B: Copy from local machine
|
||||
# From your local machine:
|
||||
# rsync -avz --exclude 'node_modules' --exclude '.venv' --exclude '__pycache__' \
|
||||
# /home/poduck/Desktop/smoothschedule2/ poduck@smoothschedule.com:~/smoothschedule/
|
||||
|
||||
# Navigate to backend
|
||||
cd smoothschedule
|
||||
|
||||
# Build and start containers
|
||||
docker compose -f docker-compose.production.yml build
|
||||
docker compose -f docker-compose.production.yml up -d
|
||||
|
||||
# Wait for containers to start
|
||||
sleep 10
|
||||
|
||||
# Check logs
|
||||
docker compose -f docker-compose.production.yml logs -f
|
||||
./scripts/build-activepieces.sh deploy
|
||||
```
|
||||
|
||||
### Step 3: Database Initialization
|
||||
Or manually:
|
||||
|
||||
```bash
|
||||
# Run migrations
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py migrate
|
||||
|
||||
# Create public schema (for multi-tenancy)
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py migrate_schemas --shared
|
||||
|
||||
# Create superuser
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py createsuperuser
|
||||
|
||||
# Collect static files (uploads to DigitalOcean Spaces)
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py collectstatic --noinput
|
||||
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'
|
||||
```
|
||||
|
||||
### Step 4: Create Initial Tenant
|
||||
### 6. Run Initialization Script
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
```bash
|
||||
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:
|
||||
```bash
|
||||
docker compose -f docker-compose.production.yml restart
|
||||
```
|
||||
|
||||
### 8. Create First Tenant
|
||||
|
||||
```bash
|
||||
# Access Django shell
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py shell
|
||||
|
||||
# In the shell, create your first business tenant:
|
||||
```
|
||||
|
||||
```python
|
||||
from core.models import Business
|
||||
from django.contrib.auth import get_user_model
|
||||
from smoothschedule.identity.core.models import Tenant, Domain
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
# Create a business
|
||||
business = Business.objects.create(
|
||||
# Create tenant
|
||||
tenant = Tenant.objects.create(
|
||||
name="Demo Business",
|
||||
subdomain="demo",
|
||||
schema_name="demo",
|
||||
schema_name="demo"
|
||||
)
|
||||
|
||||
# Verify it was created
|
||||
print(f"Created business: {business.name} at {business.subdomain}.smoothschedule.com")
|
||||
|
||||
# Create a business owner
|
||||
owner = User.objects.create_user(
|
||||
username="demo_owner",
|
||||
email="owner@demo.com",
|
||||
password="your_password_here",
|
||||
role="owner",
|
||||
business_subdomain="demo"
|
||||
# Create domain
|
||||
Domain.objects.create(
|
||||
tenant=tenant,
|
||||
domain="demo.yourdomain.com",
|
||||
is_primary=True
|
||||
)
|
||||
|
||||
print(f"Created owner: {owner.username}")
|
||||
exit()
|
||||
```
|
||||
|
||||
### Step 5: Deploy Frontend
|
||||
### 9. Provision Activepieces Connection
|
||||
|
||||
```bash
|
||||
# On your local machine
|
||||
cd /home/poduck/Desktop/smoothschedule2/frontend
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Build for production
|
||||
npm run build
|
||||
|
||||
# Upload build files to server
|
||||
rsync -avz dist/ poduck@smoothschedule.com:~/smoothschedule-frontend/
|
||||
|
||||
# On the server, set up nginx or serve via backend
|
||||
docker compose -f docker-compose.production.yml exec django \
|
||||
python manage.py provision_ap_connections --tenant demo
|
||||
```
|
||||
|
||||
**Option A: Serve via Django (simpler)**
|
||||
|
||||
The Django `collectstatic` command already handles static files. For serving the frontend:
|
||||
|
||||
1. Copy frontend build to Django static folder
|
||||
2. Django will serve it via Traefik
|
||||
|
||||
**Option B: Separate Nginx (recommended for production)**
|
||||
|
||||
```bash
|
||||
# Install nginx
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y nginx
|
||||
|
||||
# Create nginx config
|
||||
sudo nano /etc/nginx/sites-available/smoothschedule
|
||||
```
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name smoothschedule.com *.smoothschedule.com;
|
||||
|
||||
# Frontend (React)
|
||||
location / {
|
||||
root /home/poduck/smoothschedule-frontend;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Backend API (proxy to Traefik)
|
||||
location /api {
|
||||
proxy_pass http://localhost:80;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /admin {
|
||||
proxy_pass http://localhost:80;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
# Enable site
|
||||
sudo ln -s /etc/nginx/sites-available/smoothschedule /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### Step 6: SSL/HTTPS Setup
|
||||
|
||||
Traefik is configured to automatically obtain Let's Encrypt SSL certificates. Ensure:
|
||||
|
||||
1. DNS is pointed to your server
|
||||
2. Ports 80 and 443 are accessible
|
||||
3. Wait for Traefik to obtain certificates (check logs)
|
||||
|
||||
```bash
|
||||
# Monitor Traefik logs
|
||||
docker compose -f docker-compose.production.yml logs -f traefik
|
||||
|
||||
# You should see:
|
||||
# "Certificate obtained for domain smoothschedule.com"
|
||||
```
|
||||
|
||||
### Step 7: Verify Deployment
|
||||
### 10. Verify Deployment
|
||||
|
||||
```bash
|
||||
# Check all containers are running
|
||||
docker compose -f docker-compose.production.yml ps
|
||||
|
||||
# Should show:
|
||||
# - django (running)
|
||||
# - postgres (running)
|
||||
# - redis (running)
|
||||
# - traefik (running)
|
||||
# - celeryworker (running)
|
||||
# - celerybeat (running)
|
||||
# - flower (running)
|
||||
|
||||
# Test API endpoint
|
||||
curl https://smoothschedule.com/api/
|
||||
|
||||
# Test admin
|
||||
curl https://smoothschedule.com/admin/
|
||||
|
||||
# Access in browser:
|
||||
# https://smoothschedule.com - Main site
|
||||
# https://platform.smoothschedule.com - Platform dashboard
|
||||
# https://demo.smoothschedule.com - Demo business
|
||||
# https://smoothschedule.com:5555 - Flower (Celery monitoring)
|
||||
# Test endpoints
|
||||
curl https://yourdomain.com/api/
|
||||
curl https://platform.yourdomain.com/
|
||||
curl https://automations.yourdomain.com/api/v1/health
|
||||
```
|
||||
|
||||
## Post-Deployment
|
||||
## Regular Deployments
|
||||
|
||||
### 1. Monitoring
|
||||
After initial setup, deployments are simple:
|
||||
|
||||
```bash
|
||||
# View logs
|
||||
docker compose -f docker-compose.production.yml logs -f
|
||||
# From your local machine
|
||||
cd ~/smoothschedule
|
||||
|
||||
# View specific service logs
|
||||
docker compose -f docker-compose.production.yml logs -f django
|
||||
docker compose -f docker-compose.production.yml logs -f postgres
|
||||
# Commit and push your changes
|
||||
git add .
|
||||
git commit -m "Your changes"
|
||||
git push
|
||||
|
||||
# Monitor Celery tasks via Flower
|
||||
# Access: https://smoothschedule.com:5555
|
||||
# Login with credentials from .envs/.production/.django
|
||||
# Deploy
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
### 2. Backups
|
||||
### 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:
|
||||
```bash
|
||||
./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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py shell
|
||||
```
|
||||
|
||||
### Database Access
|
||||
|
||||
```bash
|
||||
# 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**
|
||||
```bash
|
||||
# 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**
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# Database backup
|
||||
@@ -329,121 +388,50 @@ docker compose -f docker-compose.production.yml exec postgres backups
|
||||
docker compose -f docker-compose.production.yml exec postgres restore backup_filename.sql.gz
|
||||
```
|
||||
|
||||
### 3. Updates
|
||||
### Monitoring
|
||||
|
||||
```bash
|
||||
# Pull latest code
|
||||
cd ~/smoothschedule/smoothschedule
|
||||
git pull origin main
|
||||
- **Flower Dashboard**: `https://yourdomain.com:5555` - Celery task monitoring
|
||||
- **Container Status**: `docker compose ps`
|
||||
- **Resource Usage**: `docker stats`
|
||||
|
||||
# Rebuild and restart
|
||||
docker compose -f docker-compose.production.yml build
|
||||
docker compose -f docker-compose.production.yml up -d
|
||||
### Security Checklist
|
||||
|
||||
# Run migrations
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py migrate
|
||||
|
||||
# Collect static files
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py collectstatic --noinput
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### SSL Certificate Issues
|
||||
```bash
|
||||
# Check Traefik logs
|
||||
docker compose -f docker-compose.production.yml logs traefik
|
||||
|
||||
# Verify DNS is pointing to server
|
||||
dig smoothschedule.com +short
|
||||
|
||||
# Ensure ports are open
|
||||
sudo ufw allow 80
|
||||
sudo ufw allow 443
|
||||
```
|
||||
|
||||
### Database Connection Issues
|
||||
```bash
|
||||
# Check PostgreSQL is running
|
||||
docker compose -f docker-compose.production.yml ps postgres
|
||||
|
||||
# Check database logs
|
||||
docker compose -f docker-compose.production.yml logs postgres
|
||||
|
||||
# Verify connection
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py dbshell
|
||||
```
|
||||
|
||||
### Static Files Not Loading
|
||||
```bash
|
||||
# Verify DigitalOcean Spaces credentials
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py shell
|
||||
>>> from django.conf import settings
|
||||
>>> print(settings.AWS_ACCESS_KEY_ID)
|
||||
>>> print(settings.AWS_STORAGE_BUCKET_NAME)
|
||||
|
||||
# Re-collect static files
|
||||
docker compose -f docker-compose.production.yml exec django python manage.py collectstatic --noinput
|
||||
|
||||
# Check Spaces bucket
|
||||
aws --profile do-tor1 s3 ls s3://smoothschedule/static/
|
||||
aws --profile do-tor1 s3 ls s3://smoothschedule/media/
|
||||
```
|
||||
|
||||
### Celery Not Running Tasks
|
||||
```bash
|
||||
# Check Celery worker logs
|
||||
docker compose -f docker-compose.production.yml logs celeryworker
|
||||
|
||||
# Access Flower dashboard
|
||||
# https://smoothschedule.com:5555
|
||||
|
||||
# Restart Celery
|
||||
docker compose -f docker-compose.production.yml restart celeryworker celerybeat
|
||||
```
|
||||
|
||||
## Security Checklist
|
||||
|
||||
- [x] SSL/HTTPS enabled via Let's Encrypt
|
||||
- [x] DJANGO_SECRET_KEY set to random value
|
||||
- [x] Database password set to random value
|
||||
- [x] Flower dashboard password protected
|
||||
- [ ] Firewall configured (UFW or iptables)
|
||||
- [ ] SSH key-based authentication enabled
|
||||
- [ ] Fail2ban installed for brute-force protection
|
||||
- [x] SSL/HTTPS enabled via Let's Encrypt (automatic with Traefik)
|
||||
- [x] All secret keys are unique random values
|
||||
- [x] Database passwords are strong
|
||||
- [x] Flower dashboard is password protected
|
||||
- [ ] Firewall configured (UFW)
|
||||
- [ ] SSH key-based authentication only
|
||||
- [ ] Regular backups configured
|
||||
- [ ] Sentry error monitoring (optional)
|
||||
- [ ] Monitoring/alerting set up
|
||||
|
||||
## Performance Optimization
|
||||
## File Structure
|
||||
|
||||
1. **Enable CDN for DigitalOcean Spaces**
|
||||
- In Spaces settings, enable CDN
|
||||
- Update `DJANGO_AWS_S3_CUSTOM_DOMAIN=smoothschedule.nyc3.cdn.digitaloceanspaces.com`
|
||||
|
||||
2. **Scale Gunicorn Workers**
|
||||
- Adjust `WEB_CONCURRENCY` in `.envs/.production/.django`
|
||||
- Formula: (2 x CPU cores) + 1
|
||||
|
||||
3. **Add Redis Persistence**
|
||||
- Update docker-compose.production.yml redis config
|
||||
- Enable AOF persistence
|
||||
|
||||
4. **Database Connection Pooling**
|
||||
- Already configured via `CONN_MAX_AGE=60`
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Weekly
|
||||
- Review error logs
|
||||
- Check disk space: `df -h`
|
||||
- Monitor Flower dashboard for failed tasks
|
||||
|
||||
### Monthly
|
||||
- Update Docker images: `docker compose pull`
|
||||
- Update dependencies: `uv sync`
|
||||
- Review backups
|
||||
|
||||
### As Needed
|
||||
- Scale resources (CPU/RAM)
|
||||
- Add more Celery workers
|
||||
- Optimize database queries
|
||||
```
|
||||
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/
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user