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_IMAGE_PREFIX=api-client
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
TAG ?= latest
BACKEND_IMAGE := $(REGISTRY)/$(NAMESPACE)/$(IMAGE_PREFIX)-backend:$(TAG)
APP_IMAGE := $(REGISTRY)/$(NAMESPACE)/$(IMAGE_PREFIX)-app:$(TAG)
SH_ADMIN_IMAGE := $(REGISTRY)/$(NAMESPACE)/$(IMAGE_PREFIX)-sh-admin:$(TAG)
AIO_IMAGE := $(REGISTRY)/$(NAMESPACE)/$(IMAGE_PREFIX)-aio:$(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)
docker-build-images:
docker build --file prod.Dockerfile --target backend --tag $(BACKEND_IMAGE) .
docker build --file prod.Dockerfile --target app --tag $(APP_IMAGE) .
docker build --file prod.Dockerfile --target sh_admin --tag $(SH_ADMIN_IMAGE) .
docker build --file prod.Dockerfile --target aio --tag $(AIO_IMAGE) .
docker-push-images:
docker push $(BACKEND_IMAGE)
docker push $(APP_IMAGE)
docker push $(SH_ADMIN_IMAGE)
docker push $(AIO_IMAGE)
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.
Images utilisées en prod :
Image utilisée en prod :
```text
forge.lclr.dev/thibaud-lclr/api-client-backend:latest
forge.lclr.dev/thibaud-lclr/api-client-app:latest
forge.lclr.dev/thibaud-lclr/api-client-sh-admin:latest
forge.lclr.dev/thibaud-lclr/api-client-aio:latest
```
Targets Docker :
@ -29,6 +27,7 @@ Targets Docker :
backend -> backend + Caddy backend
app -> app web + webapp-server + Caddy app
sh_admin -> admin + Caddy admin
aio -> app, admin, backend et webapp-server derrière un Caddy unique
```
## Préparer l'environnement
@ -39,7 +38,7 @@ Créer `.env` si besoin :
make ensure-env
```
Variables importantes :
Variables importantes pour le compose dev :
```env
POSTGRES_PASSWORD=<mot-de-passe-fort>
@ -66,6 +65,10 @@ API_CLIENT_IMAGE_PREFIX=api-client
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
Se connecter au registry :
@ -74,13 +77,13 @@ Se connecter au registry :
docker login forge.lclr.dev
```
Builder les trois images en `latest` :
Builder l'image prod en `latest` :
```sh
make docker-build-images TAG=latest
```
Pousser les trois images :
Pousser l'image prod :
```sh
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.
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
services pour que Coolify les crée dans son UI au chargement du compose. Il ne
faut pas compter sur un fichier `.env` du dépôt en prod : il est ignoré par Git.
d'environnement. Les variables sont déclarées dans les blocs `environment:` pour
que Coolify les crée dans son UI au chargement du compose. Il ne faut pas
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 :
- `SERVICE_PASSWORD_POSTGRES` : mot de passe PostgreSQL partagé entre la base et le backend
- `SERVICE_BASE64_DATA_ENCRYPTION_KEY` : clé stable de 32 caractères pour `DATA_ENCRYPTION_KEY`
- `SERVICE_URL_HOPPSCOTCH_APP` : URL publique de l'app
- `SERVICE_URL_HOPPSCOTCH_ADMIN` : URL publique de l'admin
- `SERVICE_URL_HOPPSCOTCH_BACKEND` : URL publique du backend
- `SERVICE_FQDN_HOPPSCOTCH_BACKEND` : domaine du backend, utilisé pour `VITE_BACKEND_WS_URL`
- `SERVICE_FQDN_HOPPSCOTCH_80` : domaine public unique du service
- `SERVICE_FQDN_HOPPSCOTCH` : URL publique générée depuis le domaine
- `SERVICE_URL_HOPPSCOTCH` : domaine sans schéma, utilisé pour le WebSocket
- `SERVICE_PASSWORD_POSTGRES` : mot de passe PostgreSQL généré
- `SERVICE_BASE64_DATA_ENCRYPTION_KEY` : clé stable générée de 32 caractères pour `DATA_ENCRYPTION_KEY`
Après l'import du compose dans Coolify, vérifier au minimum que les trois URLs
publiques correspondent aux domaines assignés aux services app, admin et
backend.
Après l'import du compose dans Coolify, renseigner uniquement le domaine du
service `hoppscotch`. Les URLs app/admin/backend sont ensuite dérivées par
sous-chemins.
Démarrer avec le tag `latest` :
@ -155,16 +163,13 @@ make prod-down
Services prod :
- `hoppscotch-db` : PostgreSQL 15 avec volume persistant
- `hoppscotch-backend` : backend + migrations Prisma au démarrage
- `hoppscotch-app` : app web self-host
- `hoppscotch-sh-admin` : admin
- `hoppscotch` : app web, admin, backend, serveur de bundles et migrations Prisma au démarrage
Ports prod :
Routage prod :
- `3000` : app web
- `3100` : admin
- `3170` : backend
- `3200` : serveur de bundles webapp
- `/` : app web
- `/admin` : admin
- `/backend` : backend
## Développement local

View file

@ -4,7 +4,7 @@ services:
user: postgres
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES:-testpass}
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
- POSTGRES_DB=${POSTGRES_DB:-hoppscotch}
volumes:
- hoppscotch-db:/var/lib/postgresql/data
@ -18,74 +18,35 @@ services:
timeout: 5s
retries: 10
hoppscotch-backend:
container_name: hoppscotch-backend
hoppscotch:
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:
- DATABASE_URL=postgresql://postgres:${SERVICE_PASSWORD_POSTGRES:-testpass}@hoppscotch-db:5432/${POSTGRES_DB:-hoppscotch}
- DATA_ENCRYPTION_KEY=${SERVICE_BASE64_DATA_ENCRYPTION_KEY:-0123456789abcdef0123456789abcdef}
- 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
- SERVICE_FQDN_HOPPSCOTCH_80
- DATABASE_URL=postgresql://postgres:${SERVICE_PASSWORD_POSTGRES}@hoppscotch-db:5432/${POSTGRES_DB:-hoppscotch}
- DATA_ENCRYPTION_KEY=${SERVICE_BASE64_DATA_ENCRYPTION_KEY}
- REDIRECT_URL=${SERVICE_FQDN_HOPPSCOTCH}
- VITE_BASE_URL=${SERVICE_FQDN_HOPPSCOTCH}
- VITE_SHORTCODE_BASE_URL=${SERVICE_FQDN_HOPPSCOTCH}
- VITE_ADMIN_URL=${SERVICE_FQDN_HOPPSCOTCH}/admin
- 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_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}
- WHITELISTED_ORIGINS=${SERVICE_URL_HOPPSCOTCH_APP:-http://localhost:3000},${SERVICE_URL_HOPPSCOTCH_ADMIN:-http://localhost:3100}
- ENABLE_SUBPATH_BASED_ACCESS=true
- WHITELISTED_ORIGINS=${SERVICE_FQDN_HOPPSCOTCH}/backend,${SERVICE_FQDN_HOPPSCOTCH},${SERVICE_FQDN_HOPPSCOTCH}/admin
- TRUST_PROXY=${TRUST_PROXY:-true}
depends_on:
hoppscotch-db:
condition: service_healthy
command:
["sh", "-c", "pnpm exec prisma migrate deploy && node prod_run.mjs"]
ports:
- "3170:3170"
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"
[
"sh",
"-c",
"pnpm exec prisma migrate deploy && node /usr/src/app/aio_run.mjs",
]
volumes:
hoppscotch-db: