Skip to main content

Environment map

Note on API domains: Render supports custom domains on the free plan. Attach api.muzemus.online to the production service and stage-api.muzemus.online to the staging service under Settings → Custom Domains (see Domains).

Deployment architecture

Development workflow

  1. Create branch — feature branches off main (e.g. feat/..., fix/...).
  2. Implement — code changes in backend/ and/or frontend/.
  3. Test locally — pnpm dev, pnpm --filter backend test, pnpm --filter frontend test.
  4. Push branch — the ci.yml workflow runs the quality gate on every push/PR.
  5. Deploy to stage — merge the branch into staging (or push directly); deploy.yml migrates the staging database, deploys the staging backend to Render, then the staging frontend to Firebase.
  6. Verify stage — check stage.muzemus.online and the staging health endpoint.
  7. Merge to main — open a PR from staging (or the feature branch) into main.
  8. Production — deploy.yml migrates the production database, deploys the production backend, frontend, and landing page.

CI/CD pipelines

ci.yml — pull request verification

Runs on every pull request and every push to a non-main/staging branch:
  • Format check, typecheck, lint, build, and unit tests for backend and frontend.

deploy.yml — staging and production

Triggered on push to staging or main. Jobs are gated by the shared quality gate and use GitHub Environments (staging / production) so the same secret names hold environment-specific values. After each backend deploy, the pipeline polls GET /api/v1/health until the service responds.

Backend deployment (Render)

Service configuration

Two services are defined in backend/render.yaml:
  • muze-uniform-backend — production
  • muze-uniform-backend-stage — staging

Build and start commands

Migrations are applied by the CI pipeline before the new backend version is activated, so the database schema is always current when a new version deploys.

Database connections

The backend uses two connection strings against Neon: Staging uses its own Neon database with its own DATABASE_URL / DIRECT_URL (stored in the staging GitHub Environment and the staging Render service).

Frontend deployment (Firebase Hosting)

Firebase sites

The frontend firebase.json declares "site": "muze-mus"; CI passes the explicit site name to firebase deploy --only hosting:<site>.

Landing page

The landing page is a static site in landing/ (plain HTML/CSS, no build step). It is deployed to the muze-mus-landing Firebase site on every push to main.

Deployment checklist

Before deploying:
  • All tests pass locally
  • No TypeScript errors
  • Environment variables are set in the Render dashboard and GitHub Environments
  • Database migrations are compatible with running code
  • No secrets in committed code
After deploying:
  • Backend health check returns 200 (GET /api/v1/health)
  • Frontend loads and login works
  • API calls from the frontend succeed with no CORS errors
  • Staging verified before merging to main

Rollback