Files
zeavis-edu/docs/superpowers/specs/2026-05-22-docker-deployment-design.md
T
2026-05-22 20:08:13 +00:00

3.7 KiB

Docker Deployment Design

Goal

Deploy all ZeaVis Edu production services from GitHub Actions to GHCR and then to a VPS behind Traefik.

The deployment will use:

  • Deploy directory: /opt/ZeaVis-Edu
  • Shared Traefik Docker network: app-shared-net
  • Frontend domain: zeavisedu.asepharyana.tech
  • API domain: api.zeavisedu.asepharyana.tech
  • ML service domain: ml.zeavisedu.asepharyana.tech

Architecture

The repo will deploy as three independent production containers:

  1. zeavis-web

    • Builds the Vite React app from apps/web.
    • Serves static assets through Nginx.
    • Routes through Traefik at https://zeavisedu.asepharyana.tech.
    • Uses internal port 80.
  2. zeavis-api

    • Runs the Elysia API with Bun from apps/api.
    • Routes through Traefik at https://api.zeavisedu.asepharyana.tech.
    • Uses internal port 3000.
    • Calls the ML service through ML_SERVICE_URL=https://ml.zeavisedu.asepharyana.tech.
  3. zeavis-ml

    • Runs the FastAPI ML service from apps/ml-service with Uvicorn.
    • Routes through Traefik at https://ml.zeavisedu.asepharyana.tech.
    • Uses internal port 8000.
    • Loads the TensorFlow model from the path expected by the existing service code unless implementation inspection shows a supported environment override.

All containers join the external Docker network app-shared-net. Host ports are not published because Traefik is the public entrypoint.

Images

GitHub Actions will build and push three GHCR images on pushes to main and manual workflow dispatch:

  • ghcr.io/${{ github.repository }}/web:main
  • ghcr.io/${{ github.repository }}/api:main
  • ghcr.io/${{ github.repository }}/ml:main

Each image will also receive a SHA tag for traceability.

Compose deployment

The VPS will run docker compose from /opt/ZeaVis-Edu.

The compose file will define:

  • External network app-shared-net.
  • One service per image.
  • Stable container names: zeavis-web, zeavis-api, zeavis-ml.
  • restart: always for all services.
  • Traefik labels for each domain, using websecure, TLS enabled, and the letsencrypt cert resolver.
  • env_file: .env for runtime configuration.

GitHub Actions deployment flow

The workflow will:

  1. Check out the repository.
  2. Set up Docker Buildx.
  3. Log in to GHCR with GITHUB_TOKEN.
  4. Build and push the web, API, and ML images.
  5. SSH to the VPS after successful image pushes.
  6. Change directory to /opt/ZeaVis-Edu.
  7. Pull the latest main branch.
  8. Rewrite .env from GitHub repository secrets.
  9. Ensure app-shared-net exists.
  10. Run docker compose pull.
  11. Run docker compose up -d.
  12. Show docker compose ps and fail if any service is not up.

Required secrets

The workflow requires these repository secrets:

  • VPS_HOST
  • VPS_USER
  • VPS_PORT
  • VPS_SSH_KEY
  • DATABASE_URL

If frontend or API code requires public URL configuration at build time or runtime, implementation will add the exact required secrets after inspecting the existing environment variable names.

Verification

After deployment, verify:

  • docker compose ps shows all three services up.
  • docker logs --tail 100 zeavis-web has no startup errors.
  • docker logs --tail 100 zeavis-api has no startup errors.
  • docker logs --tail 100 zeavis-ml has no startup errors.
  • curl -I https://zeavisedu.asepharyana.tech/ returns a non-Traefik 404 response.
  • curl -I https://api.zeavisedu.asepharyana.tech/health returns the API health response or an expected application response.
  • curl -I https://ml.zeavisedu.asepharyana.tech/health returns the ML health response.

Out of scope

  • Provisioning Traefik itself.
  • Creating DNS records.
  • Migrating or seeding production database data.
  • Changing application behavior beyond what is required to run correctly in containers.