Deployment

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:

EnvironmentPurposeNotes
devIndividual developer sandboxesRun via Docker Compose locally.
stagingQA and hotel preview contentMirror production integrations with sandbox Stripe keys.
productionLive customer trafficHigh 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 --build

Services:

  • backend: Django + Gunicorn (port 8000 exposed).
  • frontend: Next.js dev server (port 3000).
  • celery, celery-beat: Background jobs.
  • db: PostgreSQL (initializes via docker/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_permissions

Staging

  • 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 staging branch 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

OptionProsCons
RenderManaged Postgres/Redis add-ons, easy scalingLimited VPC control
Fly.ioGlobal apps, secrets managementRequires flyctl expertise
AWS ECS/FargateFull control, VPC integrationHeavier ops investment
Kubernetes (EKS/GKE)Integrate with existing platform teamRequires cluster management

Regardless of platform:

  1. Build a production image via CI (docker/backend/Dockerfile).
  2. Run migrations on deploy (python manage.py migrate).
  3. Run collectstatic if serving static assets via Django (or rely on CDN for frontend assets).
  4. Ensure Celery workers share the same image/config; scale to at least two workers for redundancy.
  5. Set up health checks (HTTP /healthz endpoint, 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.com to Vercel production deployment.

Documentation Site

  • Separate Vercel project pointing to the docs/ directory.
  • Environment variables are optional; add NEXT_PUBLIC_APP_URL if 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_PARAMETERS to 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 in backend/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_CONCURRENCY based 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.events or 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_dump to 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 sync or S3 replication.
  • Configuration: Version control docker-compose.yml, Helm charts, Terraform, and environment runbooks.

Recovery steps:

  1. Restore database snapshot to a new instance.
  2. Update DATABASE_URL secret and redeploy backend.
  3. Restore media bucket or fail over to replicated region.
  4. Re-run Celery workers to process any pending tasks.
  5. 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

ItemVerify
SSL certificates validhttps://app.gammacms.com loads without warnings.
Admin accessSuperusers and hotel owners can sign in and manage organizations.
API healthGET /api/v1/health/ returns 200 from monitoring location.
Webhook deliverySend test event and confirm response < 2 seconds.
BillingStripe webhook logs show invoice.paid for latest invoice.
BackupsLast snapshot timestamp < 24 hours.
Docsdocs.gammacms.com deploy shows latest content.

Keep this guide updated as infrastructure evolves. A reliable deployment pipeline keeps hotel clients confident in GammaCMS.