hosting docs

This commit is contained in:
Alex Holliday committed 2026-07-09 10:55:04 -07:00
1 parent 312961e8c9
commit 91343f996b
4 files changed
+246

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
# checkmate.so hosting (demo + staging)
Config for BlueWave's hosted instances at `demo.checkmate.so` and
`staging.checkmate.so`: one host, one nginx gateway terminating TLS, two
independent Checkmate stacks running the mono image
(`ghcr.io/bluewave-labs/checkmate`), plus a shared
[Capture](https://github.com/bluewave-labs/capture) agent. It replaces the old
`docker/unified/` setup (nginx client images + separate backend images + a
republished Mongo image) and doubles as a worked example of running the mono
image behind a TLS reverse proxy.
## How deploys work
`.github/workflows/build-image.yml` builds and pushes the image, then SSHes in
and runs `docker compose pull && docker compose up -d` in this directory:
- push to `develop` → image tagged `:develop` → `checkmate-staging` recreated
- push to `demo` → image tagged `:demo` → `checkmate-demo` recreated
The host keeps a git checkout of this repo; the deploy does `git pull` first so
compose/gateway changes land with the code.
## Host-local files (not committed)
Kept next to this compose file on the host:
- `server-prod.env` / `server-staging.env` — Checkmate server env
(`DB_CONNECTION_STRING`, `JWT_SECRET`, `CLIENT_HOST=https://demo.checkmate.so`
etc.). The old `UPTIME_APP_*` client vars are no-ops now and can be removed.
- `mongo-prod.env` / `mongo-staging.env` — Mongo credentials.
- `mongo/data-prod` / `mongo/data-staging` — Mongo data directories.
TLS certs live in `/etc/letsencrypt` (see `certbot-compose.yaml`; certbot
answers ACME challenges on port 8080 behind the gateway).
## One-time migration from docker/unified
1. `cd ~/checkmate && git pull` (must be on a branch containing this directory).
2. Stop the old stack: `cd docker/unified && docker compose down`.
3. Move host-local files here:
`mv docker/unified/{server-prod.env,server-staging.env,mongo-prod.env,mongo-staging.env} docs/hosting/checkmate-so/`
`mv docker/unified/mongo docs/hosting/checkmate-so/mongo`
4. **Check the Mongo data version before first start.** The old
`checkmate:mongo-*` images were built `FROM mongo` (floating latest), so the
data files follow whatever version was current at their last image build. Run
`db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })`
against the old container first and make the compose's `mongo:` tag match
(checked 2026-07-09: both stacks report FCV 8.2, hence the `mongo:8.2` pin
here). A lower pin than the data's FCV will refuse to start; a higher one
should step up one release at a time.
5. `cd docs/hosting/checkmate-so && docker compose up -d`.
+19
View File
@@ -0,0 +1,19 @@
version: "3"
services:
webserver:
image: nginx:latest
ports:
- 80:80
- 443:443
restart: always
volumes:
- ./nginx/conf.d/:/etc/nginx/conf.d/:ro
- ./certbot/www/:/var/www/certbot/:ro
certbot:
image: certbot/certbot:latest
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
depends_on:
- webserver
@@ -0,0 +1,122 @@
# BlueWave's hosted demo + staging instances: one nginx gateway terminating TLS
# in front of two independent Checkmate stacks, both running the mono image
# (ghcr.io/bluewave-labs/checkmate). Doubles as a worked example of putting a
# TLS proxy in front of the image.
#
# Deployed by .github/workflows/build-image.yml (deploy-staging / deploy-demo
# jobs). Env files (server-prod.env, server-staging.env, mongo-prod.env,
# mongo-staging.env) live on the host next to this file and are not committed.
services:
# Gateway (single entry point)
gateway:
image: nginx:1.27.1-alpine
container_name: checkmate-gateway
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /etc/letsencrypt:/etc/nginx/ssl:ro
- ./gateway/nginx.conf:/etc/nginx/conf.d/default.conf:ro
# Demo: demo.checkmate.so -----
checkmate-demo:
image: ghcr.io/bluewave-labs/checkmate:demo
container_name: checkmate-demo
restart: always
env_file:
- server-prod.env
stop_grace_period: 60s
healthcheck:
test:
[
"CMD",
"node",
"-e",
"require('http').get('http://localhost:52346/livez',r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))",
]
interval: 15s
timeout: 3s
start_period: 60s
start_interval: 2s
retries: 3
depends_on:
mongodb-prod:
condition: service_healthy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
mongodb-prod:
image: mongo:8.2
container_name: mongodb-prod
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
volumes:
- ./mongo/data-prod:/data/db
env_file:
- mongo-prod.env
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
# Staging: staging.checkmate.so -----
checkmate-staging:
image: ghcr.io/bluewave-labs/checkmate:develop
container_name: checkmate-staging
restart: always
env_file:
- server-staging.env
stop_grace_period: 60s
healthcheck:
test:
[
"CMD",
"node",
"-e",
"require('http').get('http://localhost:52346/livez',r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))",
]
interval: 15s
timeout: 3s
start_period: 60s
start_interval: 2s
retries: 3
depends_on:
mongodb-staging:
condition: service_healthy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
mongodb-staging:
image: mongo:8.2
container_name: mongodb-staging
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
volumes:
- ./mongo/data-staging:/data/db
env_file:
- mongo-staging.env
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
# Shared utils
capture:
image: ghcr.io/bluewave-labs/capture:latest
container_name: capture
restart: unless-stopped
ports:
- "59232:59232"
environment:
- API_SECRET=my_secret
- GIN_MODE=release
volumes:
- /etc/os-release:/etc/os-release:ro
@@ -0,0 +1,54 @@
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 $scheme;
server {
listen 80;
server_name demo.checkmate.so staging.checkmate.so;
location /.well-known/acme-challenge/ {
# Forward the challenge to Certbot listening on 8080
proxy_pass http://172.17.0.1:8080;
}
location / {
return 301 https://$host$request_uri;
}
}
# --- DEMO: demo.checkmate.so ---
server {
listen 443 ssl;
server_name demo.checkmate.so;
ssl_certificate /etc/nginx/ssl/live/demo.checkmate.so/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/demo.checkmate.so/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
# The mono image serves both the SPA and the API
proxy_pass http://checkmate-demo:52345;
}
}
# --- STAGING: staging.checkmate.so ---
server {
listen 443 ssl;
server_name staging.checkmate.so;
ssl_certificate /etc/nginx/ssl/live/staging.checkmate.so/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/staging.checkmate.so/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
# The mono image serves both the SPA and the API
proxy_pass http://checkmate-staging:52345;
}
}