Files
the-collective-hub/.github/instructions/deployment-guide.instructions.md
T
KungRaseri b192cd53ba docs(copilot): add Copilot instructions for The Collective Hub
- Add comprehensive project overview and core philosophy
- Document file structure reference for the codebase
- Create key files reference table for task-specific guidance
- Include multi-tenant guidelines and site resolution flow
2026-06-05 23:46:15 -07:00

5.2 KiB


description: 'Use when deploying a new site instance, setting up Coolify, configuring Docker, managing migrations, or troubleshooting deployment issues for The Collective Hub.' applyTo: 'Dockerfile', 'docker-compose.yml', '.dockerignore', 'Coolify'

Deployment Guide

Deployment Model

The Collective Hub uses multiple Coolify deployments from a single Git repository. Each deployment runs the same Docker image but is configured with different environment variables — most importantly, a different SITE_SLUG.

Git Repo (main branch)
    │
    ├── Coolify Deployment "bad-movies-theater"
    │   ├── SITE_SLUG=bad-movies-theater
    │   ├── PUBLIC_SITE_URL=https://badmovies.example.com
    │   ├── OWNER_DISCORD_ID=... (site owner)
    │   └── RUN_MIGRATIONS=false
    │
    ├── Coolify Deployment "garbage-day"
    │   ├── SITE_SLUG=garbage-day
    │   ├── PUBLIC_SITE_URL=https://garbageday.example.com
    │   ├── OWNER_DISCORD_ID=... (site owner)
    │   └── RUN_MIGRATIONS=false
    │
    └── Coolify Deployment "primary" (migration runner)
        ├── SITE_SLUG=primary
        ├── PUBLIC_SITE_URL=https://primary.example.com
        ├── OWNER_DISCORD_ID=... (David's Discord ID)
        └── RUN_MIGRATIONS=true

Docker

The project uses a multi-stage Docker build (see Dockerfile):

# Stage 1: Build
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:22-alpine AS runner
WORKDIR /app
COPY --from=builder /app/build build/
COPY --from=builder /app/node_modules node_modules/
COPY package.json .
EXPOSE 3000
CMD ["node", "build"]

Local Development with Docker Compose

See docker-compose.yml for local development setup, which includes:

  • Postgres database container
  • The SvelteKit app container
  • Proper environment variables for local dev
docker compose up

Adding a New Site

To add a new community/theater site:

  1. Insert a site row in the database:

    INSERT INTO sites (slug, name) VALUES ('new-community', 'New Community');
    INSERT INTO site_settings (site_id, settings) VALUES (
        (SELECT id FROM sites WHERE slug = 'new-community'),
        '{"branding":{"siteName":"New Community","tagline":"Coming soon"},"theme":{"preset":"dark","accentColor":"#e63946","backgroundColor":"#1a1a2e","textColor":"#eaeaea"},"homepage":{"heroTitle":"Welcome","heroSubtitle":"","aboutText":"","primaryButtonText":"Join us on Discord","primaryButtonLink":"","showNextEvent":true,"showSchedule":true},"layout":{"preset":"standard"}}'
    );
    

    Or use the seed script pattern.

  2. Create a new Coolify deployment:

    • Point to the same Git repo + branch
    • Set SITE_SLUG=new-community
    • Set PUBLIC_SITE_URL=https://newcommunity.example.com
    • Set OWNER_DISCORD_ID to the site owner's Discord user ID
    • Set RUN_MIGRATIONS=false (unless this is the designated migration runner)
  3. Configure DNS: Point the domain to the Coolify deployment's IP/URL

Environment Variables Per Deployment

Each deployment needs its own set of env vars. See docs/04-environment-variables.md for the full reference.

Rules:

  • Shared vars (DATABASE_URL, DISCORD_CLIENT_ID, CDN_BASE_URL) must be identical across all deployments
  • Per-site vars (SITE_SLUG, PUBLIC_SITE_URL, OWNER_DISCORD_ID) are unique per deployment
  • RUN_MIGRATIONS=true on exactly one deployment (the primary/migration runner)

Migration Runner

The migration runner deployment is critical:

  • It runs RUN_MIGRATIONS=true and executes schema migrations on startup
  • It must be deployed first when schema changes are included in a release
  • Other deployments should be deployed after the migration completes
  • If the migration runner is down, other deployments still serve traffic (they just won't have schema changes)

Coolify Configuration

In Coolify, each deployment:

  • Uses the same Git repository and branch
  • Has its own unique environment variables
  • Can have its own domain/SSL configuration
  • Is deployed independently (zero-downtime per deployment)

Deploy Strategy

  1. Deploy the migration runner first (RUN_MIGRATIONS=true)
  2. Wait for it to be healthy (migrations complete)
  3. Deploy other sites in any order
  4. Each deployment is independent — one failing doesn't affect others

Troubleshooting

Symptom Likely Cause Fix
"Site not found" on load No matching row in sites table for SITE_SLUG Insert the site row or fix SITE_SLUG env var
Login redirects to wrong URL PUBLIC_SITE_URL / BETTER_AUTH_URL mismatch Ensure both match the deployment's actual URL
"Already exists" errors on deploy Two deployments running migrations simultaneously Check only one has RUN_MIGRATIONS=true
Images not loading CDN_BASE_URL missing or wrong, or cdnKey starts with / Ensure no leading slash on CDN keys
Auth callbacks failing Discord OAuth redirect URI doesn't match deployment URL Add the correct URL to Discord Developer Portal