diff --git a/DOCKER.md b/DOCKER.md index 3ae3e41..b3ddfa9 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -104,23 +104,128 @@ The test container runs: ### Production -1. Copy `.env.docker.production.example` to `.env.docker.production` -2. Fill in real secrets and domain values -3. Start the stack: +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 + public site | +| `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 + +```bash +# Install Docker (if not already installed) +curl -fsSL https://get.docker.com | sh + +git clone 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. + +```bash +docker network create traefik-proxy +``` + +#### 4. Configure environment variables + +```bash +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) | + +All domain vars are pre-filled with `rentaldrivego.ma` subdomains and do not need changing unless you use a different domain. + +#### 5. Start Traefik + +Traefik must be running before the app stack so it can wire up routes at startup. + +```bash +docker compose -f traefik.yaml up -d +``` + +#### 6. Build and start the app stack ```bash docker compose -f docker-compose.production.yml up --build -d ``` -Production compose starts separate containers for: +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) -- postgres -- redis -- api -- marketplace -- dashboard -- admin -- public-site +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: + +```bash +git pull +docker compose -f docker-compose.production.yml up --build -d --no-deps +# e.g. to redeploy only the API: +docker compose -f docker-compose.production.yml up --build -d --no-deps api +``` + +To rebuild everything: + +```bash +docker compose -f docker-compose.production.yml up --build -d +``` + +#### Apply database migrations without downtime + +```bash +docker compose -f docker-compose.production.yml run --rm migrate +``` + +#### View logs + +```bash +# All services +docker compose -f docker-compose.production.yml logs -f + +# Single service +docker compose -f docker-compose.production.yml logs -f api +``` + +#### Stop the stack + +```bash +# Stop containers but keep volumes (data is preserved) +docker compose -f docker-compose.production.yml down + +# Stop and delete all data (destructive — irreversible) +docker compose -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