Deployment overview
How the foraging platform (and this docs site) is packaged and released.
Shape
Three Docker stacks on the host, fronted by host Nginx:
| Stack | Compose | Images | Host ports |
|---|---|---|---|
| Production | docker-compose.prod.yml | eacmlab-client:prod-latest, eacmlab-server:prod-latest | 45000 / 45001 |
| Test | docker-compose.test.yml | eacmlab-*-test-latest | 44000 / 44001 |
| Docs | docker-compose.docs.yml | eacmlab-docs:docs-latest | 46000 (loopback only) |
Public names: eacmlab.org, test.eacmlab.org, docs.eacmlab.org. Nginx config source of truth: docs/nginx/eacmlab.conf.
Images
| Dockerfile | Stages | Runtime |
|---|---|---|
client/Dockerfile | deps → builder → runner | Next standalone server.js, port 3000 |
server/Dockerfile | deps → runner | entrypoint.sh → migrate + node index.js, port 4000 |
docs-site/Dockerfile | Node build → nginx:alpine | Static site, port 80 in container |
Images are pushed to GHCR under ghcr.io/avier99/….
Server always migrates on start:
npx prisma migrate deploy
exec node index.js
Env files on the host (not in git): .env.prod, .env.test. Required names: ORIGIN_URL, WS_PORT, DATABASE_URL (see Local development).
CI/CD
| Workflow | Trigger | What it does |
|---|---|---|
.github/workflows/ci-pr.yml | PRs to test-deploy / prod-deploy | Client lint, typecheck, build; server lint + prisma generate |
.github/workflows/deploy-test.yml | Push to test-deploy | Build/push test images → SSH → docker compose -f docker-compose.test.yml |
.github/workflows/deploy-prod.yml | Push to prod-deploy | Same for prod images / docker-compose.prod.yml |
deploy-docs.yml (Phase 2) | Path-filtered push to prod-deploy | Docs image → ~/eacmlab-docs/ compose (avoids sharing the app checkout) |
Branch flow used by the team: feature work on private → merge toward test-deploy → prod-deploy. private may not exist on GitHub origin; Actions run from GitHub branches.
Docs site
Repo pieces:
docs-site/Dockerfile+docs-site/nginx.conf(container-internal)docker-compose.docs.yml— binds127.0.0.1:46000:80- Host Nginx Blocks 5–6 in
docs/nginx/eacmlab.conf
Local smoke test:
docker compose -f docker-compose.docs.yml up --build -d
curl -fsS http://127.0.0.1:46000/
Go-live on the prod host (manual until deploy-docs.yml):
- DNS
A/CNAMEfordocs→ same IP aseacmlab.org - Install Nginx config; ensure Block 5 (HTTP) is live; reload
sudo certbot certonly --webroot -w /var/www/html -d docs.eacmlab.org(separate cert — do not expand the prod cert)- Confirm Block 6 (HTTPS) paths exist;
sudo nginx -t && sudo systemctl reload nginx - Build/push
ghcr.io/avier99/eacmlab-docs:docs-latest, then on the host:docker compose -f docker-compose.docs.yml pull && docker compose -f docker-compose.docs.yml up -d
Full operator page: Phase 2 (deployment/docs-site).
What not to publish
Older files under docs/EC2-*.md, SSL-*.md, and SECURITY-SETUP.md contain outdated PM2-era steps and infra detail. Prefer this site + the current compose files and docs/nginx/eacmlab.conf.