3.9 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:
-
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.
- Builds the Vite React app from
-
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.
- Runs the Elysia API with Bun from
-
zeavis-ml- Runs the FastAPI ML service from
apps/ml-servicewith 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.
- Runs the FastAPI ML service from
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:mainghcr.io/${{ github.repository }}/api:mainghcr.io/${{ github.repository }}/ml:main
Each image will also receive a SHA tag for traceability.
Compose deployment
Catatan (2026-08-02): port produksi sekarang API 4006, nginx 4011, ML 4012; deploy Nix+systemd+Caddy.
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: alwaysfor all services.- Traefik labels for each domain, using
websecure, TLS enabled, and theletsencryptcert resolver. env_file: .envfor runtime configuration.
GitHub Actions deployment flow
The workflow will:
- Check out the repository.
- Set up Docker Buildx.
- Log in to GHCR with
GITHUB_TOKEN. - Build and push the web, API, and ML images.
- SSH to the VPS after successful image pushes.
- Change directory to
/opt/ZeaVis-Edu. - Pull the latest
mainbranch. - Rewrite
.envfrom GitHub repository secrets. - Ensure
app-shared-netexists. - Run
docker compose pull. - Run
docker compose up -d. - Show
docker compose psand fail if any service is not up.
Required secrets
The workflow requires these repository secrets:
VPS_HOSTVPS_USERVPS_PORTVPS_SSH_KEYDATABASE_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 psshows all three services up.docker logs --tail 100 zeavis-webhas no startup errors.docker logs --tail 100 zeavis-apihas no startup errors.docker logs --tail 100 zeavis-mlhas no startup errors.curl -I https://zeavisedu.asepharyana.tech/returns a non-Traefik 404 response.curl -I https://api.zeavisedu.asepharyana.tech/healthreturns the API health response or an expected application response.curl -I https://ml.zeavisedu.asepharyana.tech/healthreturns 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.