7.9 KiB
Docker Environments
Three Docker environments are available:
Dockerfile.devwithdocker-compose.dev.ymlDockerfile.testwithdocker-compose.test.ymlDockerfile.productionwithdocker-compose.production.ymldocker-compose.pgmanage.ymlfor 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:
apistartspostgres,redis, andmigrateautomatically through dependencies.- frontend profiles also start
apiand its dependencies automatically. toolsstarts onlypgadminplus its requiredpostgresdependency.
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:deploynpm run db:generatenpm run type-checknpm 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 |
marketplace and public site |
api.rentaldrivego.ma |
API |
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) |
Production now derives DATABASE_URL inside the app container from POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB, POSTGRES_USER, and POSTGRES_PASSWORD when DATABASE_URL_FROM_POSTGRES=true. That avoids Prisma auth failures when the database password contains reserved URL characters such as @, :, or /.
The example file uses rentaldrivego.ma for the marketplace and public site. The dashboard and admin panel are routed under that same host at /dashboard and /admin.
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:
- Build the monorepo image
- Start all app services (
api,marketplace,dashboard,admin,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_PASSWORDfrom.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_modulesin a named volume. API_INTERNAL_URLis used for server-side container-to-container calls, whileNEXT_PUBLIC_API_URLis used by the browser.- The Dockerfiles activate the repo's pinned
npm@10.5.0withcorepackbefore 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_dataand the bootstrap marker inpostgres_bootstrap_state, soup --builddoes 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