b192cd53ba
- 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
5.2 KiB
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:
-
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.
-
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_IDto the site owner's Discord user ID - Set
RUN_MIGRATIONS=false(unless this is the designated migration runner)
-
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=trueon exactly one deployment (the primary/migration runner)
Migration Runner
The migration runner deployment is critical:
- It runs
RUN_MIGRATIONS=trueand 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
- Deploy the migration runner first (
RUN_MIGRATIONS=true) - Wait for it to be healthy (migrations complete)
- Deploy other sites in any order
- 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 |