Files
carmanagement/DOCKER.md
T
2026-05-15 12:44:12 -04:00

7.8 KiB

Docker Environments

Three Docker environments are available:

  • Dockerfile.dev with docker-compose.dev.yml
  • Dockerfile.test with docker-compose.test.yml
  • Dockerfile.production with docker-compose.production.yml
  • docker-compose.pgmanage.yml for a standalone pgManage container

Development

Use the full dev stack for local work with hot reload and bundled Postgres and Redis:

docker compose -f docker-compose.dev.yml --profile full up --build

Services:

  • marketplace: http://localhost:3000
  • dashboard: http://localhost:3001
  • admin: http://localhost:3002
  • public-site: http://localhost:3003
  • api: http://localhost:4000
  • pgAdmin: http://localhost:5050

Each dev app now runs in its own container and can be started independently with a profile tag:

docker compose -f docker-compose.dev.yml --profile api up --build
docker compose -f docker-compose.dev.yml --profile marketplace up --build
docker compose -f docker-compose.dev.yml --profile dashboard up --build
docker compose -f docker-compose.dev.yml --profile admin up --build
docker compose -f docker-compose.dev.yml --profile public-site up --build
docker compose -f docker-compose.dev.yml --profile tools up --build

Notes:

  • api starts postgres, redis, and migrate automatically through dependencies.
  • frontend profiles also start api and its dependencies automatically.
  • tools starts only pgadmin plus its required postgres dependency.

On startup, Docker now waits for Postgres to become healthy, runs a one-shot migrate service, and only then starts the selected app container. For development, that bootstrap runs db:generate every time, but db:deploy and db:seed only the first time for a persisted dev database, so your local data survives rebuilds and normal restarts.

Default dev platform administrator:

  • email: admin@rentaldrivego.com
  • password: changeme123

If you intentionally want a fresh dev bootstrap:

docker compose -f docker-compose.dev.yml down -v

If you want to keep the database and only apply new schema changes manually:

docker compose -f docker-compose.dev.yml run --rm migrate sh -c "npm run db:deploy"

pgAdmin dev login:

  • email: admin@rentaldrivego.local
  • email: admin@rentaldrivego.dev
  • password: admin

pgAdmin opens with the dev Postgres server pre-registered as RentalDriveGo Dev DB.

pgAdmin Postgres connection:

  • host: postgres
  • port: 5432
  • database: rentaldrivego
  • username: postgres
  • password: password

Standalone pgManage

If you want a standalone Postgres management UI without starting the full development stack:

docker compose -f docker-compose.pgmanage.yml up -d

It publishes http://localhost:8000 with a standard Docker port mapping and persists its data in the named Docker volume pgmanage_data. From inside the container, connect to the local Postgres service through host.docker.internal:5432.

Test

Use the test stack to run repeatable containerized verification:

docker compose -f docker-compose.test.yml up --build --abort-on-container-exit

The test container runs:

  • npm run db:deploy
  • npm run db:generate
  • npm run type-check
  • npm run build

Production

The production stack runs behind Traefik (reverse proxy + automatic HTTPS via Let's Encrypt). All services communicate over a private Docker network (internal). Traefik reaches public-facing services via a separate traefik-proxy network.

1. Point DNS to your server

Add an A record for every subdomain to your server's public IP before deploying so Let's Encrypt can issue certificates:

Subdomain Service
rentaldrivego.ma public site
app.rentaldrivego.ma marketplace
api.rentaldrivego.ma API
dashboard.rentaldrivego.ma dashboard
admin.rentaldrivego.ma admin panel
pgmanage.rentaldrivego.ma pgManage (DB admin)

2. Install Docker and clone the repo

# Install Docker (if not already installed)
curl -fsSL https://get.docker.com | sh

git clone <repo-url> rentaldrivego
cd rentaldrivego

3. Create the shared Traefik network

Only needs to be done once per server. If it already exists this is a no-op.

docker network create traefik-proxy

4. Configure environment variables

cp .env.docker.production.example .env.docker.production

Open .env.docker.production and fill in every value. The minimum required secrets are:

Variable What to set
POSTGRES_PASSWORD Strong random password
JWT_SECRET Long random string (e.g. openssl rand -hex 64)
ACME_EMAIL Your email for Let's Encrypt notifications
RESEND_API_KEY Resend API key (or configure SMTP vars instead)

The example file uses rentaldrivego.ma for the public site and app.rentaldrivego.ma for the marketplace. Adjust them only if you use different hostnames.

5. Start Traefik

Traefik must be running before the app stack so it can wire up routes at startup.

docker compose -f traefik.yaml up -d

6. Build and start the app stack

npm run docker:prod:up

Docker will:

  1. Build the monorepo image
  2. Run database migrations (migrate service)
  3. Start all app services (api, marketplace, dashboard, admin, public-site, pgmanage)

Traefik automatically picks up the containers and provisions TLS certificates. Services are live at their https:// URLs within ~30 seconds.

Updating after a code change

Pull the latest code and rebuild only the changed service:

git pull
docker compose -p rentaldrivego-prod --env-file .env.docker.production -f docker-compose.production.yml up --build -d --no-deps <service>
# e.g. to redeploy only the API:
docker compose -p rentaldrivego-prod --env-file .env.docker.production -f docker-compose.production.yml up --build -d --no-deps api

To rebuild everything:

npm run docker:prod:up

Apply database migrations without downtime

docker compose -p rentaldrivego-prod --env-file .env.docker.production -f docker-compose.production.yml run --rm api npm run db:deploy

View logs

# All services
npm run docker:prod:logs

# Single service
npm run docker:prod:logs:api

Stop the stack

# Stop containers but keep volumes (data is preserved)
npm run docker:prod:down

# Stop and delete all data (destructive — irreversible)
docker compose -p rentaldrivego-prod --env-file .env.docker.production -f docker-compose.production.yml down -v

pgManage (DB admin UI)

pgManage is available at https://pgmanage.rentaldrivego.ma. To connect to the production database, add a connection inside pgManage with:

  • Host: localhost
  • Port: 5432
  • Database: rentaldrivego
  • Username: postgres
  • Password: value of POSTGRES_PASSWORD from .env.docker.production

Notes

  • The production image builds the whole monorepo once, then each service overrides its runtime command.
  • The dev compose file bind-mounts the repo and keeps node_modules in a named volume.
  • API_INTERNAL_URL is used for server-side container-to-container calls, while NEXT_PUBLIC_API_URL is used by the browser.
  • The Dockerfiles activate the repo's pinned npm@10.5.0 with corepack before install so container builds do not depend on the npm version bundled with the base image.
  • The dev compose stack stores Postgres data in postgres_dev_data and the bootstrap marker in postgres_bootstrap_state, so up --build does not reseed an existing local database.
  • If you need database schema updates inside Docker, run:
docker compose -f docker-compose.dev.yml run --rm migrate

If a cached base image still fails during npm ci, refresh it and rebuild without cache:

docker pull node:20-bookworm
docker compose -f docker-compose.dev.yml build --no-cache dashboard