Files
omo-bot/DEPLOYMENT.md
T
zwitschi ff58566989
CI-CD / Dashboard Lint Build (push) Successful in 12s
CI-CD / Deploy to Coolify (push) Failing after 3s
CI-CD / Bot Lint Test Build (push) Successful in 1m21s
feat: Add validation for DISCORD_CLIENT_ID in command registration and update deployment guide for dashboard publish directory
2026-05-17 19:28:24 +02:00

5.9 KiB

Deployment Guide

This document covers production deployment for the omo-bot Coolify project with two separate resources:

  • omo-bot-backend (Node.js bot + Admin API)
  • omo-bot-dashboard (React/Vite static dashboard from admin-dashboard/)

Deployment Topology

Recommended domains:

  • api.openmicodyssey.com -> omo-bot-backend
  • admin.openmicodyssey.com -> omo-bot-dashboard

Recommended edge topology:

  • Internet -> Nginx reverse proxy -> Coolify resources
  • Nginx routes by hostname to backend/dashboard resource domains or internal ports

Optional same-origin pattern:

  • admin.openmicodyssey.com serves dashboard and reverse-proxies /admin/* + /health to backend.

1. Create Coolify Project and Resources

  1. In Coolify, create (or open) project omo-bot.
  2. Add resource omo-bot-backend from this repository:
    • Build context: repository root
    • Start command: npm start
    • Internal port: 8787 (Admin API)
  3. Add resource omo-bot-dashboard from this repository:
    • Base directory: admin-dashboard
    • Build command: npm run build
    • Publish directory: /
    • Internal port: 80 (typical static web port behind Coolify)
  4. Configure domains for each resource and enable TLS certificates.

1.1 Nginx Reverse Proxy in Front of Coolify

Use this pattern when you want one public edge server in front of Coolify-managed services.

Recommended flow:

  1. Public DNS for api.openmicodyssey.com and admin.openmicodyssey.com points to Nginx host.
  2. Nginx terminates TLS and forwards traffic to Coolify resource domains or private IP:port targets.
  3. Coolify resources stay private or restricted to internal network where possible.

Example host-based routing:

server {
  listen 80;
  server_name api.openmicodyssey.com;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name api.openmicodyssey.com;

  ssl_certificate /etc/letsencrypt/live/api.openmicodyssey.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/api.openmicodyssey.com/privkey.pem;

  location / {
    proxy_pass http://coolify-backend.internal:8787;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
  }
}

server {
  listen 80;
  server_name admin.openmicodyssey.com;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name admin.openmicodyssey.com;

  ssl_certificate /etc/letsencrypt/live/admin.openmicodyssey.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/admin.openmicodyssey.com/privkey.pem;

  location / {
    proxy_pass http://coolify-dashboard.internal:80;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
  }
}

If you prefer same-origin routing for dashboard + API through one public domain, proxy location /admin/ and location /health to backend while keeping / on dashboard.

Recommended OAuth callback route:

  • https://admin.openmicodyssey.com/oauth/discord/callback

If you use this callback path, make sure dashboard hosting serves the SPA entrypoint for that route instead of returning 404.

2. Configure Runtime Variables

Backend (omo-bot-backend) minimum:

  • DATABASE_URL
  • CONFIG_DB_ENABLED=true
  • Any temporary legacy vars needed for first-time db:seed

Dashboard (omo-bot-dashboard) minimum:

  • VITE_ADMIN_API_BASE_URL (for split-domain deployment, set to https://api.openmicodyssey.com)
  • VITE_DISCORD_CLIENT_ID
  • VITE_DISCORD_REDIRECT_URI (recommended: https://admin.openmicodyssey.com/oauth/discord/callback)

OAuth alignment:

  • Discord Developer Portal redirect URI must exactly match the dashboard callback URL.
  • Config DB key OAUTH_BRIDGE_REDIRECT_URI must match the same callback URL.
  • Dashboard env VITE_DISCORD_REDIRECT_URI must match the same callback URL.

Discord OAuth authorize URL shape:

https://discord.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=https%3A%2F%2Fadmin.openmicodyssey.com%2Foauth%2Fdiscord%2Fcallback&scope=identify%20guilds&prompt=consent

3. Get Coolify API Token and Resource UUIDs

  1. In Coolify, open Keys & Tokens -> API Tokens and create a token.
  2. Copy your Coolify base URL (example: https://coolify.yourdomain.com).
  3. Find resource UUID for:
  • omo-bot-backend
  • omo-bot-dashboard

Deploy API endpoint used by CI:

  • GET /api/v1/deploy?uuid=<resource_uuid>
  • Authorization: Bearer <COOLIFY_API_TOKEN>

4. Configure Gitea Action Secrets/Variables

In Gitea repository settings, add Actions secrets:

  • COOLIFY_BASE_URL
  • COOLIFY_API_TOKEN
  • COOLIFY_RESOURCE_UUID_BOT
  • COOLIFY_RESOURCE_UUID_DASHBOARD

Current workflow in .gitea/workflows/ci-cd.yml triggers backend and dashboard deploys separately via the Coolify Deploy API.

5. Domain and DNS Checklist

  1. Create DNS records to Nginx edge host (or directly to Coolify if no edge proxy):
  • A record for root/subdomain targets
  • CNAME where appropriate
  1. Verify certificates issued on Nginx or Coolify, depending on TLS termination point.
  2. Verify Nginx upstreams match deployed ports:
  • backend -> 8787
  • dashboard -> 80
  1. Verify OAuth callback route resolves through dashboard hosting:
  • https://admin.openmicodyssey.com/oauth/discord/callback
  1. Verify dashboard can call API at configured VITE_ADMIN_API_BASE_URL.
  2. Verify API health endpoint over TLS:
    • GET https://api.openmicodyssey.com/health

6. Post-Deploy Verification

  1. npm run register:commands (if bot app/guild IDs changed).
  2. Confirm bot online in Discord and slash commands visible.
  3. Open dashboard URL and run OAuth login flow.
  4. Confirm Discord redirects back to https://admin.openmicodyssey.com/oauth/discord/callback without 404.
  5. Validate Admin API auth behavior with and without bearer token.