This commit is contained in:
root
2026-05-17 15:36:17 -04:00
parent 58a3787f29
commit d81565ca71
2 changed files with 69 additions and 40 deletions
+3 -7
View File
@@ -112,11 +112,8 @@ Add an A record for every subdomain to your server's public IP before deploying
| Subdomain | Service | | Subdomain | Service |
|---|---| |---|---|
| `rentaldrivego.ma` | public site | | `rentaldrivego.ma` | marketplace and public site |
| `app.rentaldrivego.ma` | marketplace |
| `api.rentaldrivego.ma` | API | | `api.rentaldrivego.ma` | API |
| `dashboard.rentaldrivego.ma` | dashboard |
| `admin.rentaldrivego.ma` | admin panel |
| `pgmanage.rentaldrivego.ma` | pgManage (DB admin) | | `pgmanage.rentaldrivego.ma` | pgManage (DB admin) |
#### 2. Install Docker and clone the repo #### 2. Install Docker and clone the repo
@@ -154,7 +151,7 @@ Open `.env.docker.production` and fill in every value. The minimum required secr
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 `/`. 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 public site and `app.rentaldrivego.ma` for the marketplace. Adjust them only if you use different hostnames. 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 #### 5. Start Traefik
@@ -172,8 +169,7 @@ npm run docker:prod:up
Docker will: Docker will:
1. Build the monorepo image 1. Build the monorepo image
2. Run database migrations (`migrate` service) 2. Start all app services (`api`, `marketplace`, `dashboard`, `admin`, `pgmanage`)
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. Traefik automatically picks up the containers and provisions TLS certificates. Services are live at their `https://` URLs within ~30 seconds.
+66 -33
View File
@@ -55,13 +55,13 @@ services:
restart: unless-stopped restart: unless-stopped
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.api.rule=Host(`api.rentaldrivego.ma`) - traefik.http.routers.api.rule=Host(`${API_DOMAIN}`)
- traefik.http.routers.api.entrypoints=websecure - traefik.http.routers.api.entrypoints=websecure
- traefik.http.routers.api.tls=true - traefik.http.routers.api.tls=true
- traefik.http.routers.api.tls.certresolver=letsencrypt - traefik.http.routers.api.tls.certresolver=letsencrypt
- traefik.http.services.api.loadbalancer.server.port=4000 - traefik.http.services.api.loadbalancer.server.port=4000
frontend: marketplace:
build: build:
context: . context: .
dockerfile: Dockerfile.production dockerfile: Dockerfile.production
@@ -70,14 +70,7 @@ services:
NEXT_PUBLIC_MARKETPLACE_URL: ${NEXT_PUBLIC_MARKETPLACE_URL} NEXT_PUBLIC_MARKETPLACE_URL: ${NEXT_PUBLIC_MARKETPLACE_URL}
NEXT_PUBLIC_DASHBOARD_URL: ${NEXT_PUBLIC_DASHBOARD_URL} NEXT_PUBLIC_DASHBOARD_URL: ${NEXT_PUBLIC_DASHBOARD_URL}
NEXT_PUBLIC_ADMIN_URL: ${NEXT_PUBLIC_ADMIN_URL} NEXT_PUBLIC_ADMIN_URL: ${NEXT_PUBLIC_ADMIN_URL}
command: command: ["npm", "run", "start", "--workspace", "@rentaldrivego/marketplace"]
- bash
- -c
- |
npm run start --workspace @rentaldrivego/marketplace &
npm run start --workspace @rentaldrivego/dashboard &
npm run start --workspace @rentaldrivego/admin &
wait -n
networks: networks:
- internal - internal
- traefik-proxy - traefik-proxy
@@ -88,29 +81,69 @@ services:
restart: unless-stopped restart: unless-stopped
labels: labels:
- traefik.enable=true - traefik.enable=true
# /dashboard and /admin route to their respective ports (higher priority) - traefik.http.routers.marketplace.rule=Host(`${PUBLIC_SITE_DOMAIN}`) || Host(`www.${PUBLIC_SITE_DOMAIN}`)
- traefik.http.routers.frontend-dashboard.rule=(Host(`${PUBLIC_SITE_DOMAIN}`) || Host(`www.${PUBLIC_SITE_DOMAIN}`)) && PathPrefix(`/dashboard`) - traefik.http.routers.marketplace.entrypoints=websecure
- traefik.http.routers.frontend-dashboard.entrypoints=websecure - traefik.http.routers.marketplace.tls=true
- traefik.http.routers.frontend-dashboard.tls=true - traefik.http.routers.marketplace.tls.certresolver=letsencrypt
- traefik.http.routers.frontend-dashboard.tls.certresolver=letsencrypt - traefik.http.routers.marketplace.service=marketplace-svc
- traefik.http.routers.frontend-dashboard.service=frontend-dashboard-svc - traefik.http.routers.marketplace.priority=10
- traefik.http.routers.frontend-dashboard.priority=20 - traefik.http.services.marketplace-svc.loadbalancer.server.port=3000
- traefik.http.services.frontend-dashboard-svc.loadbalancer.server.port=3001
- traefik.http.routers.frontend-admin.rule=(Host(`${PUBLIC_SITE_DOMAIN}`) || Host(`www.${PUBLIC_SITE_DOMAIN}`)) && PathPrefix(`/admin`) dashboard:
- traefik.http.routers.frontend-admin.entrypoints=websecure build:
- traefik.http.routers.frontend-admin.tls=true context: .
- traefik.http.routers.frontend-admin.tls.certresolver=letsencrypt dockerfile: Dockerfile.production
- traefik.http.routers.frontend-admin.service=frontend-admin-svc args:
- traefik.http.routers.frontend-admin.priority=20 NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
- traefik.http.services.frontend-admin-svc.loadbalancer.server.port=3002 NEXT_PUBLIC_MARKETPLACE_URL: ${NEXT_PUBLIC_MARKETPLACE_URL}
# marketplace catches everything else (root and all other paths) NEXT_PUBLIC_DASHBOARD_URL: ${NEXT_PUBLIC_DASHBOARD_URL}
- traefik.http.routers.frontend-marketplace.rule=Host(`${PUBLIC_SITE_DOMAIN}`) || Host(`www.${PUBLIC_SITE_DOMAIN}`) NEXT_PUBLIC_ADMIN_URL: ${NEXT_PUBLIC_ADMIN_URL}
- traefik.http.routers.frontend-marketplace.entrypoints=websecure command: ["npm", "run", "start", "--workspace", "@rentaldrivego/dashboard"]
- traefik.http.routers.frontend-marketplace.tls=true networks:
- traefik.http.routers.frontend-marketplace.tls.certresolver=letsencrypt - internal
- traefik.http.routers.frontend-marketplace.service=frontend-marketplace-svc - traefik-proxy
- traefik.http.routers.frontend-marketplace.priority=10 depends_on:
- traefik.http.services.frontend-marketplace-svc.loadbalancer.server.port=3000 - api
env_file:
- .env.docker.production
restart: unless-stopped
labels:
- traefik.enable=true
- traefik.http.routers.dashboard.rule=(Host(`${PUBLIC_SITE_DOMAIN}`) || Host(`www.${PUBLIC_SITE_DOMAIN}`)) && PathPrefix(`/dashboard`)
- traefik.http.routers.dashboard.entrypoints=websecure
- traefik.http.routers.dashboard.tls=true
- traefik.http.routers.dashboard.tls.certresolver=letsencrypt
- traefik.http.routers.dashboard.service=dashboard-svc
- traefik.http.routers.dashboard.priority=20
- traefik.http.services.dashboard-svc.loadbalancer.server.port=3001
admin:
build:
context: .
dockerfile: Dockerfile.production
args:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
NEXT_PUBLIC_MARKETPLACE_URL: ${NEXT_PUBLIC_MARKETPLACE_URL}
NEXT_PUBLIC_DASHBOARD_URL: ${NEXT_PUBLIC_DASHBOARD_URL}
NEXT_PUBLIC_ADMIN_URL: ${NEXT_PUBLIC_ADMIN_URL}
command: ["npm", "run", "start", "--workspace", "@rentaldrivego/admin"]
networks:
- internal
- traefik-proxy
depends_on:
- api
env_file:
- .env.docker.production
restart: unless-stopped
labels:
- traefik.enable=true
- traefik.http.routers.admin.rule=(Host(`${PUBLIC_SITE_DOMAIN}`) || Host(`www.${PUBLIC_SITE_DOMAIN}`)) && PathPrefix(`/admin`)
- traefik.http.routers.admin.entrypoints=websecure
- traefik.http.routers.admin.tls=true
- traefik.http.routers.admin.tls.certresolver=letsencrypt
- traefik.http.routers.admin.service=admin-svc
- traefik.http.routers.admin.priority=20
- traefik.http.services.admin-svc.loadbalancer.server.port=3002
pgmanage: pgmanage:
image: cmdpromptinc/pgmanage-enterprise:latest image: cmdpromptinc/pgmanage-enterprise:latest