fix: align prod compose with coolify hoppscotch

This commit is contained in:
thibaud-leclere 2026-05-06 16:51:07 +02:00
parent 860000d0b3
commit 46dbec745f
4 changed files with 64 additions and 95 deletions

View file

@ -45,3 +45,12 @@ API_CLIENT_REGISTRY=forge.lclr.dev
API_CLIENT_NAMESPACE=thibaud-lclr API_CLIENT_NAMESPACE=thibaud-lclr
API_CLIENT_IMAGE_PREFIX=api-client API_CLIENT_IMAGE_PREFIX=api-client
API_CLIENT_TAG=latest API_CLIENT_TAG=latest
#-----------------------Coolify Prod Local Defaults----------------#
# Used only when running docker-compose.prod.yml locally.
# Coolify generates these SERVICE_* values itself in production.
SERVICE_FQDN_HOPPSCOTCH_80=http://localhost:3000
SERVICE_FQDN_HOPPSCOTCH=http://localhost:3000
SERVICE_URL_HOPPSCOTCH=localhost:3000
SERVICE_PASSWORD_POSTGRES=testpass
SERVICE_BASE64_DATA_ENCRYPTION_KEY=0123456789abcdef0123456789abcdef

View file

@ -8,9 +8,7 @@ NAMESPACE ?= thibaud-lclr
IMAGE_PREFIX ?= api-client IMAGE_PREFIX ?= api-client
TAG ?= latest TAG ?= latest
BACKEND_IMAGE := $(REGISTRY)/$(NAMESPACE)/$(IMAGE_PREFIX)-backend:$(TAG) AIO_IMAGE := $(REGISTRY)/$(NAMESPACE)/$(IMAGE_PREFIX)-aio:$(TAG)
APP_IMAGE := $(REGISTRY)/$(NAMESPACE)/$(IMAGE_PREFIX)-app:$(TAG)
SH_ADMIN_IMAGE := $(REGISTRY)/$(NAMESPACE)/$(IMAGE_PREFIX)-sh-admin:$(TAG)
PROD_ENV := API_CLIENT_REGISTRY=$(REGISTRY) API_CLIENT_NAMESPACE=$(NAMESPACE) API_CLIENT_IMAGE_PREFIX=$(IMAGE_PREFIX) API_CLIENT_TAG=$(TAG) PROD_ENV := API_CLIENT_REGISTRY=$(REGISTRY) API_CLIENT_NAMESPACE=$(NAMESPACE) API_CLIENT_IMAGE_PREFIX=$(IMAGE_PREFIX) API_CLIENT_TAG=$(TAG)
@ -52,13 +50,9 @@ ensure-env:
@test -f $(ENV_FILE) || cp $(ENV_EXAMPLE) $(ENV_FILE) @test -f $(ENV_FILE) || cp $(ENV_EXAMPLE) $(ENV_FILE)
docker-build-images: docker-build-images:
docker build --file prod.Dockerfile --target backend --tag $(BACKEND_IMAGE) . docker build --file prod.Dockerfile --target aio --tag $(AIO_IMAGE) .
docker build --file prod.Dockerfile --target app --tag $(APP_IMAGE) .
docker build --file prod.Dockerfile --target sh_admin --tag $(SH_ADMIN_IMAGE) .
docker-push-images: docker-push-images:
docker push $(BACKEND_IMAGE) docker push $(AIO_IMAGE)
docker push $(APP_IMAGE)
docker push $(SH_ADMIN_IMAGE)
docker-build-push-images: docker-build-images docker-push-images docker-build-push-images: docker-build-images docker-push-images

View file

@ -15,12 +15,10 @@ Fork interne de Hoppscotch pour déploiement self-host.
Les images sont buildées en local puis poussées à la main sur le registry. Les images sont buildées en local puis poussées à la main sur le registry.
Images utilisées en prod : Image utilisée en prod :
```text ```text
forge.lclr.dev/thibaud-lclr/api-client-backend:latest forge.lclr.dev/thibaud-lclr/api-client-aio:latest
forge.lclr.dev/thibaud-lclr/api-client-app:latest
forge.lclr.dev/thibaud-lclr/api-client-sh-admin:latest
``` ```
Targets Docker : Targets Docker :
@ -29,6 +27,7 @@ Targets Docker :
backend -> backend + Caddy backend backend -> backend + Caddy backend
app -> app web + webapp-server + Caddy app app -> app web + webapp-server + Caddy app
sh_admin -> admin + Caddy admin sh_admin -> admin + Caddy admin
aio -> app, admin, backend et webapp-server derrière un Caddy unique
``` ```
## Préparer l'environnement ## Préparer l'environnement
@ -39,7 +38,7 @@ Créer `.env` si besoin :
make ensure-env make ensure-env
``` ```
Variables importantes : Variables importantes pour le compose dev :
```env ```env
POSTGRES_PASSWORD=<mot-de-passe-fort> POSTGRES_PASSWORD=<mot-de-passe-fort>
@ -66,6 +65,10 @@ API_CLIENT_IMAGE_PREFIX=api-client
API_CLIENT_TAG=latest API_CLIENT_TAG=latest
``` ```
Le compose prod local utilise aussi les valeurs `SERVICE_*` présentes dans
`.env.example`. En production Coolify, ces valeurs sont générées par Coolify à
partir de `docker-compose.prod.yml`.
## Build et push registry ## Build et push registry
Se connecter au registry : Se connecter au registry :
@ -74,13 +77,13 @@ Se connecter au registry :
docker login forge.lclr.dev docker login forge.lclr.dev
``` ```
Builder les trois images en `latest` : Builder l'image prod en `latest` :
```sh ```sh
make docker-build-images TAG=latest make docker-build-images TAG=latest
``` ```
Pousser les trois images : Pousser l'image prod :
```sh ```sh
make docker-push-images TAG=latest make docker-push-images TAG=latest
@ -105,22 +108,27 @@ La prod utilise uniquement `docker-compose.prod.yml`.
Ce compose ne contient pas de `build:`. Il tire les images du registry. Ce compose ne contient pas de `build:`. Il tire les images du registry.
Sur Coolify, `docker-compose.prod.yml` est la source de vérité des variables Sur Coolify, `docker-compose.prod.yml` est la source de vérité des variables
d'environnement. Les variables sont déclarées dans les blocs `environment:` des d'environnement. Les variables sont déclarées dans les blocs `environment:` pour
services pour que Coolify les crée dans son UI au chargement du compose. Il ne que Coolify les crée dans son UI au chargement du compose. Il ne faut pas
faut pas compter sur un fichier `.env` du dépôt en prod : il est ignoré par Git. compter sur un fichier `.env` du dépôt en prod : il est ignoré par Git.
Le compose prod utilise l'image AIO et un seul domaine Coolify :
- `/` : app web
- `/admin` : admin
- `/backend` : backend GraphQL/API
Variables générées/préremplies pour Coolify : Variables générées/préremplies pour Coolify :
- `SERVICE_PASSWORD_POSTGRES` : mot de passe PostgreSQL partagé entre la base et le backend - `SERVICE_FQDN_HOPPSCOTCH_80` : domaine public unique du service
- `SERVICE_BASE64_DATA_ENCRYPTION_KEY` : clé stable de 32 caractères pour `DATA_ENCRYPTION_KEY` - `SERVICE_FQDN_HOPPSCOTCH` : URL publique générée depuis le domaine
- `SERVICE_URL_HOPPSCOTCH_APP` : URL publique de l'app - `SERVICE_URL_HOPPSCOTCH` : domaine sans schéma, utilisé pour le WebSocket
- `SERVICE_URL_HOPPSCOTCH_ADMIN` : URL publique de l'admin - `SERVICE_PASSWORD_POSTGRES` : mot de passe PostgreSQL généré
- `SERVICE_URL_HOPPSCOTCH_BACKEND` : URL publique du backend - `SERVICE_BASE64_DATA_ENCRYPTION_KEY` : clé stable générée de 32 caractères pour `DATA_ENCRYPTION_KEY`
- `SERVICE_FQDN_HOPPSCOTCH_BACKEND` : domaine du backend, utilisé pour `VITE_BACKEND_WS_URL`
Après l'import du compose dans Coolify, vérifier au minimum que les trois URLs Après l'import du compose dans Coolify, renseigner uniquement le domaine du
publiques correspondent aux domaines assignés aux services app, admin et service `hoppscotch`. Les URLs app/admin/backend sont ensuite dérivées par
backend. sous-chemins.
Démarrer avec le tag `latest` : Démarrer avec le tag `latest` :
@ -155,16 +163,13 @@ make prod-down
Services prod : Services prod :
- `hoppscotch-db` : PostgreSQL 15 avec volume persistant - `hoppscotch-db` : PostgreSQL 15 avec volume persistant
- `hoppscotch-backend` : backend + migrations Prisma au démarrage - `hoppscotch` : app web, admin, backend, serveur de bundles et migrations Prisma au démarrage
- `hoppscotch-app` : app web self-host
- `hoppscotch-sh-admin` : admin
Ports prod : Routage prod :
- `3000` : app web - `/` : app web
- `3100` : admin - `/admin` : admin
- `3170` : backend - `/backend` : backend
- `3200` : serveur de bundles webapp
## Développement local ## Développement local

View file

@ -4,7 +4,7 @@ services:
user: postgres user: postgres
environment: environment:
- POSTGRES_USER=postgres - POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES:-testpass} - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
- POSTGRES_DB=${POSTGRES_DB:-hoppscotch} - POSTGRES_DB=${POSTGRES_DB:-hoppscotch}
volumes: volumes:
- hoppscotch-db:/var/lib/postgresql/data - hoppscotch-db:/var/lib/postgresql/data
@ -18,74 +18,35 @@ services:
timeout: 5s timeout: 5s
retries: 10 retries: 10
hoppscotch-backend: hoppscotch:
container_name: hoppscotch-backend
restart: unless-stopped restart: unless-stopped
image: ${API_CLIENT_REGISTRY:-forge.lclr.dev}/${API_CLIENT_NAMESPACE:-thibaud-lclr}/${API_CLIENT_IMAGE_PREFIX:-api-client}-backend:${API_CLIENT_TAG:-latest} image: ${API_CLIENT_REGISTRY:-forge.lclr.dev}/${API_CLIENT_NAMESPACE:-thibaud-lclr}/${API_CLIENT_IMAGE_PREFIX:-api-client}-aio:${API_CLIENT_TAG:-latest}
environment: environment:
- DATABASE_URL=postgresql://postgres:${SERVICE_PASSWORD_POSTGRES:-testpass}@hoppscotch-db:5432/${POSTGRES_DB:-hoppscotch} - SERVICE_FQDN_HOPPSCOTCH_80
- DATA_ENCRYPTION_KEY=${SERVICE_BASE64_DATA_ENCRYPTION_KEY:-0123456789abcdef0123456789abcdef} - DATABASE_URL=postgresql://postgres:${SERVICE_PASSWORD_POSTGRES}@hoppscotch-db:5432/${POSTGRES_DB:-hoppscotch}
- VITE_BASE_URL=${SERVICE_URL_HOPPSCOTCH_APP:-http://localhost:3000} - DATA_ENCRYPTION_KEY=${SERVICE_BASE64_DATA_ENCRYPTION_KEY}
- VITE_SHORTCODE_BASE_URL=${SERVICE_URL_HOPPSCOTCH_APP:-http://localhost:3000} - REDIRECT_URL=${SERVICE_FQDN_HOPPSCOTCH}
- VITE_ADMIN_URL=${SERVICE_URL_HOPPSCOTCH_ADMIN:-http://localhost:3100} - VITE_BASE_URL=${SERVICE_FQDN_HOPPSCOTCH}
- VITE_BACKEND_GQL_URL=${SERVICE_URL_HOPPSCOTCH_BACKEND:-http://localhost:3170}/graphql - VITE_SHORTCODE_BASE_URL=${SERVICE_FQDN_HOPPSCOTCH}
- VITE_BACKEND_WS_URL=wss://${SERVICE_FQDN_HOPPSCOTCH_BACKEND:-localhost:3170}/graphql - VITE_ADMIN_URL=${SERVICE_FQDN_HOPPSCOTCH}/admin
- VITE_BACKEND_API_URL=${SERVICE_URL_HOPPSCOTCH_BACKEND:-http://localhost:3170}/v1 - VITE_BACKEND_GQL_URL=${SERVICE_FQDN_HOPPSCOTCH}/backend/graphql
- VITE_BACKEND_WS_URL=wss://${SERVICE_URL_HOPPSCOTCH}/backend/graphql
- VITE_BACKEND_API_URL=${SERVICE_FQDN_HOPPSCOTCH}/backend/v1
- VITE_APP_TOS_LINK=${VITE_APP_TOS_LINK:-https://docs.hoppscotch.io/support/terms} - VITE_APP_TOS_LINK=${VITE_APP_TOS_LINK:-https://docs.hoppscotch.io/support/terms}
- VITE_APP_PRIVACY_POLICY_LINK=${VITE_APP_PRIVACY_POLICY_LINK:-https://docs.hoppscotch.io/support/privacy} - VITE_APP_PRIVACY_POLICY_LINK=${VITE_APP_PRIVACY_POLICY_LINK:-https://docs.hoppscotch.io/support/privacy}
- VITE_PROXYSCOTCH_ACCESS_TOKEN=${VITE_PROXYSCOTCH_ACCESS_TOKEN:-} - VITE_PROXYSCOTCH_ACCESS_TOKEN=${VITE_PROXYSCOTCH_ACCESS_TOKEN:-}
- ENABLE_SUBPATH_BASED_ACCESS=${ENABLE_SUBPATH_BASED_ACCESS:-false} - ENABLE_SUBPATH_BASED_ACCESS=true
- WHITELISTED_ORIGINS=${SERVICE_URL_HOPPSCOTCH_APP:-http://localhost:3000},${SERVICE_URL_HOPPSCOTCH_ADMIN:-http://localhost:3100} - WHITELISTED_ORIGINS=${SERVICE_FQDN_HOPPSCOTCH}/backend,${SERVICE_FQDN_HOPPSCOTCH},${SERVICE_FQDN_HOPPSCOTCH}/admin
- TRUST_PROXY=${TRUST_PROXY:-true} - TRUST_PROXY=${TRUST_PROXY:-true}
depends_on: depends_on:
hoppscotch-db: hoppscotch-db:
condition: service_healthy condition: service_healthy
command: command:
["sh", "-c", "pnpm exec prisma migrate deploy && node prod_run.mjs"] [
ports: "sh",
- "3170:3170" "-c",
"pnpm exec prisma migrate deploy && node /usr/src/app/aio_run.mjs",
hoppscotch-app: ]
container_name: hoppscotch-app
restart: unless-stopped
image: ${API_CLIENT_REGISTRY:-forge.lclr.dev}/${API_CLIENT_NAMESPACE:-thibaud-lclr}/${API_CLIENT_IMAGE_PREFIX:-api-client}-app:${API_CLIENT_TAG:-latest}
environment:
- VITE_BASE_URL=${SERVICE_URL_HOPPSCOTCH_APP:-http://localhost:3000}
- VITE_SHORTCODE_BASE_URL=${SERVICE_URL_HOPPSCOTCH_APP:-http://localhost:3000}
- VITE_ADMIN_URL=${SERVICE_URL_HOPPSCOTCH_ADMIN:-http://localhost:3100}
- VITE_BACKEND_GQL_URL=${SERVICE_URL_HOPPSCOTCH_BACKEND:-http://localhost:3170}/graphql
- VITE_BACKEND_WS_URL=wss://${SERVICE_FQDN_HOPPSCOTCH_BACKEND:-localhost:3170}/graphql
- VITE_BACKEND_API_URL=${SERVICE_URL_HOPPSCOTCH_BACKEND:-http://localhost:3170}/v1
- VITE_APP_TOS_LINK=${VITE_APP_TOS_LINK:-https://docs.hoppscotch.io/support/terms}
- VITE_APP_PRIVACY_POLICY_LINK=${VITE_APP_PRIVACY_POLICY_LINK:-https://docs.hoppscotch.io/support/privacy}
- VITE_PROXYSCOTCH_ACCESS_TOKEN=${VITE_PROXYSCOTCH_ACCESS_TOKEN:-}
- ENABLE_SUBPATH_BASED_ACCESS=${ENABLE_SUBPATH_BASED_ACCESS:-false}
depends_on:
hoppscotch-backend:
condition: service_started
ports:
- "3000:3000"
- "3200:3200"
hoppscotch-sh-admin:
container_name: hoppscotch-sh-admin
restart: unless-stopped
image: ${API_CLIENT_REGISTRY:-forge.lclr.dev}/${API_CLIENT_NAMESPACE:-thibaud-lclr}/${API_CLIENT_IMAGE_PREFIX:-api-client}-sh-admin:${API_CLIENT_TAG:-latest}
environment:
- VITE_BASE_URL=${SERVICE_URL_HOPPSCOTCH_APP:-http://localhost:3000}
- VITE_SHORTCODE_BASE_URL=${SERVICE_URL_HOPPSCOTCH_APP:-http://localhost:3000}
- VITE_ADMIN_URL=${SERVICE_URL_HOPPSCOTCH_ADMIN:-http://localhost:3100}
- VITE_BACKEND_GQL_URL=${SERVICE_URL_HOPPSCOTCH_BACKEND:-http://localhost:3170}/graphql
- VITE_BACKEND_API_URL=${SERVICE_URL_HOPPSCOTCH_BACKEND:-http://localhost:3170}/v1
- VITE_APP_TOS_LINK=${VITE_APP_TOS_LINK:-https://docs.hoppscotch.io/support/terms}
- VITE_APP_PRIVACY_POLICY_LINK=${VITE_APP_PRIVACY_POLICY_LINK:-https://docs.hoppscotch.io/support/privacy}
- VITE_PROXYSCOTCH_ACCESS_TOKEN=${VITE_PROXYSCOTCH_ACCESS_TOKEN:-}
- ENABLE_SUBPATH_BASED_ACCESS=${ENABLE_SUBPATH_BASED_ACCESS:-false}
depends_on:
hoppscotch-backend:
condition: service_started
ports:
- "3100:3100"
volumes: volumes:
hoppscotch-db: hoppscotch-db: