diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 000000000..00ca421d1 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,187 @@ +# Deployment Runbook + +This document explains how deployments work for the EDR platform using Docker, GitHub Actions, and self-hosted runners. + +## Overview + +- Monorepo contains 6 deployable services: + - `freight-api` + - `freight-portal` + - `freight-backoffice` + - `passenger-api` + - `passenger-portal` + - `passenger-backoffice` +- Deployments run through one workflow: `.github/workflows/deploy.yml` +- Each service is built/deployed independently in parallel (matrix jobs). +- Docker Compose project names are branch-aware to avoid environment collisions on the same host. + +## Prerequisites + +- Docker Engine with Compose plugin on the self-hosted runner. +- GitHub self-hosted runner registered for this repository. +- Repository secret configured: + - `NPM_TOKEN` (for private `@tria-plc/*` package install during Docker build) +- Server-side env files created for each branch/environment. + +## Server Environment Files + +`sync-env-from-server.sh` reads env files from: + +`/home//environment/edr///` + +Where: + +- `` defaults to `tria` (overridable by `DEPLOY_USER`) +- `` is derived from Git branch (lowercase, non-alphanumeric replaced with `-`) +- `` is `edr-freight` or `edr-passenger` + +### Required files per project + +For `edr-freight`: + +- `freight-api.env` +- `freight-portal.env` +- `freight-backoffice.env` +- optional: `freight-web.build.env` + +For `edr-passenger`: + +- `passenger-api.env` +- `passenger-portal.env` +- `passenger-backoffice.env` +- optional: `passenger-web.build.env` + +### Required env key + +Each service env file must contain: + +- `PORT=` + +The sync script validates this and fails if missing. + +### Build env files (optional) + +Used for build-time variables (example: Vite API URLs), with `export` syntax: + +```bash +export FREIGHT_VITE_API_URL=https://freight-api.example.com/api +export PASSENGER_VITE_API_URL=https://passenger-api.example.com +``` + +These are injected into `GITHUB_ENV` during workflow execution. + +## Docker Compose Port Mapping + +`docker-compose.yaml` uses per-service env variables for host/container port mappings: + +- `FREIGHT_API_PORT` +- `PASSENGER_API_PORT` +- `FREIGHT_PORTAL_PORT` +- `FREIGHT_BACKOFFICE_PORT` +- `PASSENGER_PORTAL_PORT` +- `PASSENGER_BACKOFFICE_PORT` + +`scripts/deploy/sync-env-from-server.sh` extracts `PORT` from each synced `.env` and exports the corresponding `*_PORT` variable to `GITHUB_ENV`. + +## GitHub Actions Deployment Flow + +Workflow file: `.github/workflows/deploy.yml` + +### 1) `prepare` job + +- Checks out repository once. +- Creates workspace artifact (`workspace.tgz`) and uploads it. + +### 2) `deploy` matrix job (parallel) + +For each service: + +- Downloads and extracts workspace artifact. +- Syncs that service env file from server path. +- Computes branch slug and sets: + - `COMPOSE_PROJECT_NAME=-` +- Creates `.npmrc`/`.npmrc_temp` from `NPM_TOKEN`. +- Runs: + - `docker compose --project-name "$COMPOSE_PROJECT_NAME" build ` + - `docker compose --project-name "$COMPOSE_PROJECT_NAME" up -d ` +- Cleans `.npmrc`/`.npmrc_temp`. + +## Branch/Environment Isolation + +Compose project name is generated as: + +`-` + +Examples: + +- `edr-freight-main` +- `edr-freight-staging` +- `edr-passenger-dev` + +This prevents container/network/volume name collisions between branches. + +## Local Manual Deployment (Optional) + +From repo root: + +```bash +DOCKER_BUILDKIT=1 docker compose build +docker compose up -d +``` + +If private packages are required locally, create `.npmrc`: + +```bash +cat < .npmrc +@tria-plc:registry=https://npm.pkg.github.com +//npm.pkg.github.com/:_authToken= +always-auth=true +EOF +``` + +## Passenger API Startup Behavior + +Passenger container entrypoint runs on startup: + +1. `npm run prisma:generate` +2. `npm run prisma:migrate` (deploy mode) +3. `npm run prisma:seed` +4. starts API process + +## Troubleshooting + +### Missing env file + +Error: + +- `Missing env file: ...` + +Fix: + +- Create the required file in the server env directory for that project/branch slug. + +### Missing PORT in env file + +Error: + +- `Missing required PORT in env file: ...` + +Fix: + +- Add `PORT=` to that service env file. + +### Private package install fails + +Check: + +- `NPM_TOKEN` exists in repo secrets. +- Workflow created `.npmrc` successfully. + +### Prisma seed/migrate failures (passenger) + +Check: + +- `DATABASE_URL` in `passenger-api.env` +- DB reachability from runner host/container network +- migration history consistency + diff --git a/checkpoint.md b/checkpoint.md new file mode 100644 index 000000000..31eb86b2b --- /dev/null +++ b/checkpoint.md @@ -0,0 +1,63 @@ +# Checkpoint + +## Major Tasks Completed + +1. Docker deployment scaffolded for all 6 apps in the monorepo. +2. Split API images into app-specific Dockerfiles: + - `apps/edr-freight-api/Dockerfile` + - `apps/edr-passenger-api/Dockerfile` +3. Kept shared Vite/nginx image: + - `infrastructure/docker/Dockerfile.web` + - `infrastructure/nginx/spa.conf` +4. Updated `docker-compose.yaml` to run all 6 services (apps only, no Postgres service in compose). +5. Added/updated deployment scripts: + - `scripts/deploy/create-npmrc.sh` + - `scripts/deploy/sync-env-from-server.sh` +6. Added self-hosted GitHub Actions deployment workflow: + - Consolidated into one file: `.github/workflows/deploy.yml` +7. Deployment workflow now: + - uses a single checkout (`prepare` job), + - deploys services via parallel matrix, + - sets compose project names per branch/environment, + - passes explicit `docker compose --project-name`. +8. Environment sync script now: + - supports branch slug paths, + - validates each service env file exists, + - requires `PORT` in each env file, + - exports per-service port vars to `GITHUB_ENV`. +9. `docker-compose.yaml` now reads per-service ports via variables exported from env sync. +10. Passenger startup flow fixed to run: + - `prisma:generate`, + - `prisma:migrate`, + - `prisma:seed`, + before API startup. +11. Passenger seed TypeScript issues fixed in `apps/edr-passenger-api/prisma/seed.ts` so it compiles under strict checks. +12. Added deployment runbook: + - `DEPLOYMENT.md` + +## Key Files to Review + +- `.github/workflows/deploy.yml` +- `docker-compose.yaml` +- `scripts/deploy/sync-env-from-server.sh` +- `scripts/deploy/create-npmrc.sh` +- `apps/edr-passenger-api/docker-entrypoint.sh` +- `apps/edr-passenger-api/prisma/seed.ts` +- `DEPLOYMENT.md` + +## Next Actions + +1. Run full CI on all target branches (`main`, `dev`, `staging`) and verify matrix job behavior. +2. Validate server env directory layout matches script expectations: + - `/home//environment/edr///...` +3. Confirm each service env file includes valid `PORT` and service-specific runtime vars. +4. Verify branch-specific compose project names produce isolated containers/networks/volumes on runner. +5. Smoke test all 6 deployed services behind real environment URLs. + +## Open Risks / Notes + +1. Passenger seed runs on every container start; confirm this is desired for production-like environments. +2. Prisma warns about `package.json#prisma` deprecation (Prisma 7 migration pending). +3. Matrix parallelism increases runner load; ensure self-hosted runner capacity is sufficient. +4. Port collisions are prevented by env-driven mapping, but bad env values can still cause runtime conflicts. +