Deployment Guide
This playbook walks through preparing, launching, and operating GammaCMS for hotel customers. It covers infrastructure choices, environment configuration, monitoring, and recovery.
1. Architecture Overview
GammaCMS ships as a containerized monorepo:
- Backend: Django + Celery (API, web, admin).
- Worker tier: Celery and Celery Beat for async jobs (webhooks, usage aggregation, email).
- Frontend: Next.js dashboard (App Router) served via Vercel or static hosting.
- Docs: Nextra-powered site deployable on Vercel from the
docs/directory. - Persistence: PostgreSQL, Redis, S3-compatible object storage for media.
Recommended environment split:
| Environment | Purpose | Notes |
|---|---|---|
dev | Individual developer sandboxes | Run via Docker Compose locally. |
staging | QA and hotel preview content | Mirror production integrations with sandbox Stripe keys. |
production | Live customer traffic | High availability infrastructure, managed backups. |
2. Prerequisites
- Node.js 18.x (dashboard/docs builds).
- Python 3.11 (management commands during build jobs).
- Docker Engine ≥ 24 and Docker Compose plugin ≥ 2.20.
- Access to cloud providers (Render, Fly.io, AWS, or similar) or Kubernetes cluster.
- Managed PostgreSQL (e.g., RDS, Supabase) and Redis (e.g., Upstash, Elasticache).
- S3 bucket (DigitalOcean Spaces, AWS S3, Cloudflare R2) for media files.
- Stripe account for billing (test + production keys).
3. Environment Configuration
Create a .env per service based on backend/.env.example and frontend/.env.example. Critical variables:
# Backend
DJANGO_SECRET_KEY=... # unique per environment
DJANGO_SETTINGS_MODULE=config.settings.production
DATABASE_URL=postgres://...
REDIS_URL=redis://...
ALLOWED_HOSTS=app.gammacms.com
CSRF_TRUSTED_ORIGINS=https://app.gammacms.com
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_STORAGE_BUCKET_NAME=gammacms-media-prod
STRIPE_API_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
FRONTEND_URL=https://app.gammacms.com
CORS_ALLOWED_ORIGINS=https://app.gammacms.com,https://hotel1.com
# Frontend (Next.js)
NEXT_PUBLIC_APP_NAME=GammaCMS
NEXT_PUBLIC_API_URL=https://api.gammacms.com
NEXT_PUBLIC_DOCS_URL=https://docs.gammacms.com
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...Set secrets in your hosting provider (Render dashboard, Fly secrets, Kubernetes secrets) instead of committing .env files.
4. Local & Staging Deployments
Local (Docker Compose)
# From repo root
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env
cp docker/.env.example .env
# Start stack
docker compose up --buildServices:
backend: Django + Gunicorn (port 8000 exposed).frontend: Next.js dev server (port 3000).celery,celery-beat: Background jobs.db: PostgreSQL (initializes viadocker/db/init.sql).redis: Cache + rate limiting.
After containers start, run initial tasks:
docker compose exec backend python manage.py migrate
docker compose exec backend python manage.py createsuperuser
docker compose exec backend python manage.py initialize_permissions
docker compose exec backend python manage.py initialize_role_permissionsStaging
- Host backend on Render, Fly.io, Railway, or a managed Kubernetes deployment.
- Enable TLS (Render handles automatically; otherwise terminate with a reverse proxy / load balancer).
- Point a subdomain (e.g.,
staging.app.gammacms.com) to the frontend. - Configure CI (GitHub Actions) to build Docker images on push to
stagingbranch and deploy.
Example GitHub Actions snippet (.github/workflows/staging.yml):
name: Deploy Staging
on:
push:
branches: [staging]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build & push backend image
run: |
docker build -t ghcr.io/org/gammacms-backend:staging -f docker/backend/Dockerfile .
docker push ghcr.io/org/gammacms-backend:staging
- name: Trigger hosting provider deploy
run: curl -X POST ${{ secrets.RENDER_DEPLOY_HOOK }}5. Production Deployment
Backend Options
| Option | Pros | Cons |
|---|---|---|
| Render | Managed Postgres/Redis add-ons, easy scaling | Limited VPC control |
| Fly.io | Global apps, secrets management | Requires flyctl expertise |
| AWS ECS/Fargate | Full control, VPC integration | Heavier ops investment |
| Kubernetes (EKS/GKE) | Integrate with existing platform team | Requires cluster management |
Regardless of platform:
- Build a production image via CI (
docker/backend/Dockerfile). - Run migrations on deploy (
python manage.py migrate). - Run
collectstaticif serving static assets via Django (or rely on CDN for frontend assets). - Ensure Celery workers share the same image/config; scale to at least two workers for redundancy.
- Set up health checks (HTTP
/healthzendpoint, Celery beat status).
Frontend
- Deploy the Next.js dashboard via Vercel (root:
frontend/). - Configure environment variables in Vercel dashboard.
- Enable preview deployments for feature branches.
- Map
app.gammacms.comto Vercel production deployment.
Documentation Site
- Separate Vercel project pointing to the
docs/directory. - Environment variables are optional; add
NEXT_PUBLIC_APP_URLif linking back to app. - Custom domain
docs.gammacms.com→ CNAME to Vercel.
Media Storage
- Use S3-compatible storage with lifecycle rules (e.g., replicate to secondary region weekly).
- Configure public CDN (CloudFront, Cloudflare) for faster asset delivery.
- Set
AWS_S3_OBJECT_PARAMETERSto include cache headers (CacheControl: max-age=86400).
6. Background Workers & Scheduled Jobs
celery: handles webhooks, media processing, onboarding flows.celery-beat: schedules retry/cleanup tasks defined inbackend/config/celery_schedules.py.
Production tips:
- Run beat on a dedicated instance (avoid process restarts killing schedules).
- Monitor using Flower or health endpoints (
/api/v1/monitoring/celery/if exposed). - Set
CELERYD_CONCURRENCYbased on CPU cores (e.g., 4 workers per instance).
7. Monitoring & Alerting
Application Metrics
- Sentry for exception tracking — add DSN to backend and frontend envs.
- Prometheus + Grafana if self-hosting; otherwise, use Datadog / New Relic agents.
- Track:
- Request latency and error rates.
- Celery queue depth (
celery.eventsor Datadog integration). - Redis connection errors (rate limiter).
Logs
- Ship container logs to a centralized service (Datadog Logs, Logtail, CloudWatch).
- Tag logs with environment and organization ID for faster filtering.
Alerts
- 5xx rate > 2% for 5 minutes → page on-call.
- Celery queue older than 2 minutes → investigate worker health.
- Webhook failures > 10 consecutively → notify integrations team + hotel IT contact.
8. Backups & Disaster Recovery
- PostgreSQL: Enable automated snapshots (RDS) or schedule
pg_dumpto S3 daily. Test restores monthly. - Redis: Use managed service with persistence (AOF) or accept ephemeral cache loss.
- Media: Sync buckets to a secondary region weekly using
rclone syncor S3 replication. - Configuration: Version control
docker-compose.yml, Helm charts, Terraform, and environment runbooks.
Recovery steps:
- Restore database snapshot to a new instance.
- Update
DATABASE_URLsecret and redeploy backend. - Restore media bucket or fail over to replicated region.
- Re-run Celery workers to process any pending tasks.
- Communicate outage + resolution to hotel clients.
Run a game day every quarter covering simulated DB loss, webhook outages, and rate limiter exhaustion.
9. Release Management
- Feature branches → PR → preview deployment → QA → merge to
main. - Tag releases (
vYYYY.MM.DD) and record changelog entries. - Use feature flags (Zustand store + API toggles) for risky UI rollouts.
- Announce major changes with documentation updates and tutorial videos.
10. Post-Deployment Checklist
| Item | Verify |
|---|---|
| SSL certificates valid | https://app.gammacms.com loads without warnings. |
| Admin access | Superusers and hotel owners can sign in and manage organizations. |
| API health | GET /api/v1/health/ returns 200 from monitoring location. |
| Webhook delivery | Send test event and confirm response < 2 seconds. |
| Billing | Stripe webhook logs show invoice.paid for latest invoice. |
| Backups | Last snapshot timestamp < 24 hours. |
| Docs | docs.gammacms.com deploy shows latest content. |
Keep this guide updated as infrastructure evolves. A reliable deployment pipeline keeps hotel clients confident in GammaCMS.