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
133 lines
5.2 KiB
Markdown
133 lines
5.2 KiB
Markdown
---
|
|
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`](Dockerfile)):
|
|
|
|
```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`](docker-compose.yml) for local development setup, which includes:
|
|
- Postgres database container
|
|
- The SvelteKit app container
|
|
- Proper environment variables for local dev
|
|
|
|
```bash
|
|
docker compose up
|
|
```
|
|
|
|
## Adding a New Site
|
|
|
|
To add a new community/theater site:
|
|
|
|
1. **Insert a site row in the database:**
|
|
```sql
|
|
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`](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 |
|