Skip to main content

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:

StackComposeImagesHost ports
Productiondocker-compose.prod.ymleacmlab-client:prod-latest, eacmlab-server:prod-latest45000 / 45001
Testdocker-compose.test.ymleacmlab-*-test-latest44000 / 44001
Docsdocker-compose.docs.ymleacmlab-docs:docs-latest46000 (loopback only)

Public names: eacmlab.org, test.eacmlab.org, docs.eacmlab.org. Nginx config source of truth: docs/nginx/eacmlab.conf.

Images​

DockerfileStagesRuntime
client/Dockerfiledeps → builder → runnerNext standalone server.js, port 3000
server/Dockerfiledeps → runnerentrypoint.sh → migrate + node index.js, port 4000
docs-site/DockerfileNode build → nginx:alpineStatic 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​

WorkflowTriggerWhat it does
.github/workflows/ci-pr.ymlPRs to test-deploy / prod-deployClient lint, typecheck, build; server lint + prisma generate
.github/workflows/deploy-test.ymlPush to test-deployBuild/push test images → SSH → docker compose -f docker-compose.test.yml
.github/workflows/deploy-prod.ymlPush to prod-deploySame for prod images / docker-compose.prod.yml
deploy-docs.yml (Phase 2)Path-filtered push to prod-deployDocs 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 — binds 127.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):

  1. DNS A/CNAME for docs → same IP as eacmlab.org
  2. Install Nginx config; ensure Block 5 (HTTP) is live; reload
  3. sudo certbot certonly --webroot -w /var/www/html -d docs.eacmlab.org (separate cert — do not expand the prod cert)
  4. Confirm Block 6 (HTTPS) paths exist; sudo nginx -t && sudo systemctl reload nginx
  5. 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.