Files
mixmaker/deployments/coolify.md
lemintare 6b189bfce4
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / compose (push) Has been cancelled
Add global role synchronization for Discord with configurable interval
This commit introduces a new feature for global role synchronization in Discord, allowing for periodic reconciliation of managed roles. A new environment variable, `DISCORD_GLOBAL_SYNC_INTERVAL`, has been added to configure the synchronization interval, defaulting to 5 minutes. The `RoleWorker` has been updated to schedule global sync jobs, ensuring that missing managed roles are restored and extra assignments are removed without affecting unrelated server roles. Database schema changes support the new synchronization logic, and tests have been added to validate the functionality of the global reconciliation process.
2026-07-19 12:04:33 +03:00

66 lines
3.9 KiB
Markdown

# Coolify deployment
## Resource
Create a project and add this repository as a Docker Compose resource. Use the root `compose.yaml`. Assign the public domain to the `web` service on port 80.
Do not add custom Compose networks or Traefik labels. Coolify creates the deployment network and connects its proxy. The `web` service proxies `/api` and the SSE stream to `api`; `api` and `db` remain internal.
## Required variables
Set these as production variables in Coolify:
- `PUBLIC_URL=https://mix.example.com`
- `POSTGRES_DB`
- `POSTGRES_USER`
- `POSTGRES_PASSWORD` — generate a unique value
- `DATABASE_URL=postgres://<user>:<password>@db:5432/<database>?sslmode=disable`
- `DISCORD_CLIENT_ID`
- `DISCORD_CLIENT_SECRET`
- `DISCORD_REDIRECT_URL=https://mix.example.com/api/auth/discord/callback`
- `ADMIN_DISCORD_IDS` — comma-separated Discord user IDs
- `DISCORD_BOT_TOKEN` — bot token from the Developer Portal; never expose it to the frontend
- `DISCORD_ANNOUNCEMENT_CHANNEL_ID` — numeric ID of the text channel for new mix announcements
- `DISCORD_ANNOUNCEMENT_LOCALE=ru` — announcement language, `ru` or `en`
- `DISCORD_GUILD_ID` — numeric ID of the server where roster roles are synchronized
- `DISCORD_GLOBAL_SYNC_INTERVAL=5m` — interval for exact managed-role reconciliation
Do not copy production values into `.env` in the repository.
## Discord
In the Discord Developer Portal:
1. Create an application.
2. Add the exact production callback URL.
3. Use only the `identify` OAuth scope.
4. Store the client secret only in Coolify.
For event announcements, add the bot to the server with the `bot` scope. In the announcement channel grant only `View Channel`, `Send Messages`, `Embed Links`, and `Mention Everyone`. Copy the channel ID with Discord Developer Mode and store it in `DISCORD_ANNOUNCEMENT_CHANNEL_ID`. The bot token is separate from the OAuth client secret and must also remain only in Coolify. If either the token or channel ID is omitted, announcements stay disabled.
For role synchronization, grant the bot `Manage Roles`, copy the server ID to `DISCORD_GUILD_ID`, and place the bot's own role above all roles it creates. The bot creates event-specific RSVP status roles, global `Tank`, `Damage`, and `Support` roles, plus temporary team and team-captain roles after roster confirmation. It does not need `Administrator`. Role synchronization stays disabled when `DISCORD_GUILD_ID` is empty.
Enable **Server Members Intent** under Developer Portal → Bot → Privileged Gateway Intents. The five-minute global reconciliation uses the guild member inventory to restore missing managed assignments and remove extra managed assignments without touching unrelated server roles. `Message Content Intent` and `Presence Intent` remain disabled.
## Storage and backups
PostgreSQL uses the `postgres_data` named volume. Confirm that Coolify recognizes it as persistent storage before accepting users.
Persistent storage is not a backup. Schedule an encrypted `pg_dump` to storage outside the VPS, define retention, and test restoration before launch. Back up before schema migrations.
## Deployment verification
1. Ensure `migrations` exits successfully.
2. Ensure `db`, `api`, and `web` become healthy.
3. Open `/health` through the public domain.
4. Complete Discord login and verify the admin role.
5. Create a test event and RSVP.
6. Confirm the bot posts one announcement with an `@everyone` mention and a working registration button.
7. Confirm test rosters and verify dynamic team, captain, and slot roles in Discord.
8. Rename a live team and verify both managed role names change.
9. Complete or cancel the test event and verify temporary roles are removed.
10. Restart/redeploy and confirm the event remains.
11. Verify SSE remains connected through the proxy.
Rollback application images only when the database migration is backward-compatible. Otherwise restore the matching database backup.