feat: Update CI/CD workflow to trigger separate backend and dashboard deployments; enhance deployment documentation with Nginx proxy details and OAuth callback URLs
This commit is contained in:
+105
-61
@@ -9,12 +9,17 @@ This document covers production deployment for the `omo-bot` Coolify project wit
|
||||
|
||||
Recommended domains:
|
||||
|
||||
- `api.yourdomain.com` -> `omo-bot-backend`
|
||||
- `admin.yourdomain.com` -> `omo-bot-dashboard`
|
||||
- `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.yourdomain.com` serves dashboard and reverse-proxies `/admin/*` + `/health` to backend.
|
||||
- `admin.openmicodyssey.com` serves dashboard and reverse-proxies `/admin/*` + `/health` to backend.
|
||||
|
||||
## 1. Create Coolify Project and Resources
|
||||
|
||||
@@ -22,13 +27,80 @@ Optional same-origin pattern:
|
||||
2. Add resource `omo-bot-backend` from this repository:
|
||||
- Build context: repository root
|
||||
- Start command: `npm start`
|
||||
- Port: `8787` (Admin API) if exposed
|
||||
- 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: `dist`
|
||||
- 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:
|
||||
|
||||
```nginx
|
||||
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:
|
||||
@@ -39,14 +111,21 @@ Backend (`omo-bot-backend`) minimum:
|
||||
|
||||
Dashboard (`omo-bot-dashboard`) minimum:
|
||||
|
||||
- `VITE_ADMIN_API_BASE_URL` (for split-domain deployment, set to `https://api.yourdomain.com`)
|
||||
- `VITE_ADMIN_API_BASE_URL` (for split-domain deployment, set to `https://api.openmicodyssey.com`)
|
||||
- `VITE_DISCORD_CLIENT_ID`
|
||||
- `VITE_DISCORD_REDIRECT_URI` (must match Discord OAuth2 redirect list)
|
||||
- `VITE_DISCORD_REDIRECT_URI` (recommended: `https://admin.openmicodyssey.com/oauth/discord/callback`)
|
||||
|
||||
OAuth alignment:
|
||||
|
||||
- Discord Developer Portal redirect URI must match dashboard redirect domain.
|
||||
- Config DB key `OAUTH_BRIDGE_REDIRECT_URI` must match the same URI.
|
||||
- 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:
|
||||
|
||||
```text
|
||||
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 Deployment Hooks and Tokens
|
||||
|
||||
@@ -71,68 +150,33 @@ In Gitea repository settings, add Actions secrets:
|
||||
- `COOLIFY_DEPLOY_HOOK_URL_DASHBOARD`
|
||||
- `COOLIFY_DEPLOY_TOKEN_DASHBOARD` (optional)
|
||||
|
||||
Current workflow in `.gitea/workflows/ci-cd.yml` uses a single pair:
|
||||
Current workflow in `.gitea/workflows/ci-cd.yml` triggers backend and dashboard deploys separately using these four secrets.
|
||||
|
||||
- `COOLIFY_DEPLOY_HOOK_URL`
|
||||
- `COOLIFY_DEPLOY_TOKEN`
|
||||
## 5. Domain and DNS Checklist
|
||||
|
||||
If you use separate resources with separate hooks, update workflow deploy step to call both hooks.
|
||||
1. Create DNS records to Nginx edge host (or directly to Coolify if no edge proxy):
|
||||
|
||||
## 5. Example Deploy Step for Two Coolify Resources
|
||||
- `A` record for root/subdomain targets
|
||||
- `CNAME` where appropriate
|
||||
|
||||
```yaml
|
||||
deploy-coolify:
|
||||
name: Deploy to Coolify
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- bot-checks
|
||||
- dashboard-checks
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
steps:
|
||||
- name: Trigger backend deploy
|
||||
env:
|
||||
HOOK_URL: ${{ secrets.COOLIFY_DEPLOY_HOOK_URL_BOT }}
|
||||
HOOK_TOKEN: ${{ secrets.COOLIFY_DEPLOY_TOKEN_BOT }}
|
||||
run: |
|
||||
if [ -z "$HOOK_URL" ]; then
|
||||
echo "Missing COOLIFY_DEPLOY_HOOK_URL_BOT"
|
||||
exit 1
|
||||
fi
|
||||
if [ -n "$HOOK_TOKEN" ]; then
|
||||
curl --fail --show-error --silent -X POST -H "Authorization: Bearer $HOOK_TOKEN" "$HOOK_URL"
|
||||
else
|
||||
curl --fail --show-error --silent -X POST "$HOOK_URL"
|
||||
fi
|
||||
2. Verify certificates issued on Nginx or Coolify, depending on TLS termination point.
|
||||
3. Verify Nginx upstreams match deployed ports:
|
||||
|
||||
- name: Trigger dashboard deploy
|
||||
env:
|
||||
HOOK_URL: ${{ secrets.COOLIFY_DEPLOY_HOOK_URL_DASHBOARD }}
|
||||
HOOK_TOKEN: ${{ secrets.COOLIFY_DEPLOY_TOKEN_DASHBOARD }}
|
||||
run: |
|
||||
if [ -z "$HOOK_URL" ]; then
|
||||
echo "Missing COOLIFY_DEPLOY_HOOK_URL_DASHBOARD"
|
||||
exit 1
|
||||
fi
|
||||
if [ -n "$HOOK_TOKEN" ]; then
|
||||
curl --fail --show-error --silent -X POST -H "Authorization: Bearer $HOOK_TOKEN" "$HOOK_URL"
|
||||
else
|
||||
curl --fail --show-error --silent -X POST "$HOOK_URL"
|
||||
fi
|
||||
```
|
||||
- backend -> `8787`
|
||||
- dashboard -> `80`
|
||||
|
||||
## 6. Domain and DNS Checklist
|
||||
4. Verify OAuth callback route resolves through dashboard hosting:
|
||||
|
||||
1. Create DNS records to Coolify host:
|
||||
- `A` record for root/subdomain targets
|
||||
- `CNAME` where appropriate
|
||||
2. Verify certificates issued for both domains.
|
||||
3. Verify dashboard can call API at configured `VITE_ADMIN_API_BASE_URL`.
|
||||
4. Verify API health endpoint over TLS:
|
||||
- `GET https://api.yourdomain.com/health`
|
||||
- `https://admin.openmicodyssey.com/oauth/discord/callback`
|
||||
|
||||
## 7. Post-Deploy Verification
|
||||
5. Verify dashboard can call API at configured `VITE_ADMIN_API_BASE_URL`.
|
||||
6. 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. Validate Admin API auth behavior with and without bearer token.
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user