From 6898649898a36e1f52d9051d07cd7aecc1cbd45d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karb=C3=A9=20Architect?= Date: Sat, 30 May 2026 18:36:38 +0000 Subject: [PATCH] feat(prod): co-deploy postgres and minio in production compose --- .env.production.example | 23 ++++++++------ README.md | 9 ++++-- docker-compose.prod.yml | 66 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 11 deletions(-) diff --git a/.env.production.example b/.env.production.example index 6666bac..7a6a12e 100644 --- a/.env.production.example +++ b/.env.production.example @@ -9,22 +9,27 @@ APP_URL=https://karbe.cosmolan.fr NEXTAUTH_SECRET=replace_with_random_secret AUTH_SECRET=replace_with_random_secret -# Database (managed PostgreSQL recommended) -DATABASE_URL=postgresql://user:password@db-host:5432/karbe?schema=public +# Co-deployed PostgreSQL (docker-compose.prod.yml) +POSTGRES_DB=karbe +POSTGRES_USER=karbe +POSTGRES_PASSWORD=replace_with_strong_password +DATABASE_URL=postgresql://karbe:replace_with_strong_password@postgres:5432/karbe?schema=public # Stripe TEST STRIPE_SECRET_KEY=sk_test_xxx STRIPE_WEBHOOK_SECRET=whsec_xxx STRIPE_OWNER_SUBSCRIPTION_PRICE_ID=price_xxx -# Storage S3 / MinIO -S3_ENDPOINT=https://s3.example.com -S3_REGION=eu-west-3 +# Co-deployed MinIO (docker-compose.prod.yml) +MINIO_ROOT_USER=karbe +MINIO_ROOT_PASSWORD=replace_with_strong_password +S3_ENDPOINT=http://minio:9000 +S3_REGION=us-east-1 S3_BUCKET=karbe-medias -S3_ACCESS_KEY_ID=replace_me -S3_SECRET_ACCESS_KEY=replace_me -S3_PUBLIC_URL=https://cdn.example.com/karbe-medias -S3_FORCE_PATH_STYLE=false +S3_ACCESS_KEY_ID=karbe +S3_SECRET_ACCESS_KEY=replace_with_strong_password +S3_PUBLIC_URL= +S3_FORCE_PATH_STYLE=true # Recommended for stable multi-instance deploys NEXT_SERVER_ACTIONS_ENCRYPTION_KEY=replace_with_base64_32_bytes diff --git a/README.md b/README.md index 756894a..10c9941 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ Copiez-le en `.env` et renseignez vos valeurs. Le repo inclut une stack de self-hosting Docker pour le MVP: - `Dockerfile` (build Next.js standalone) -- `docker-compose.prod.yml` (app + reverse proxy Caddy HTTPS) +- `docker-compose.prod.yml` (app + PostgreSQL + MinIO + reverse proxy Caddy HTTPS) - `docker/Caddyfile` - `.env.production.example` @@ -146,10 +146,15 @@ Le repo inclut une stack de self-hosting Docker pour le MVP: cp .env.production.example .env.production ``` -Renseigner toutes les variables, en particulier `DATABASE_URL`, +Renseigner toutes les variables, en particulier: +`POSTGRES_PASSWORD`, `MINIO_ROOT_PASSWORD`, +`DATABASE_URL`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_OWNER_SUBSCRIPTION_PRICE_ID`, `APP_URL` et `NEXT_PUBLIC_SITE_URL`. +`docker-compose.prod.yml` crée automatiquement le bucket MinIO défini par +`S3_BUCKET` au démarrage via le service `minio-init`. + ### 3) Appliquer les migrations Prisma Les migrations doivent être appliquées avant le premier démarrage : diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index e0d7a4f..7b6f5c3 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,4 +1,61 @@ services: + postgres: + image: postgres:16-alpine + container_name: karbe-postgres + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRES_DB:-karbe} + POSTGRES_USER: ${POSTGRES_USER:-karbe} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set} + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"] + interval: 10s + timeout: 5s + retries: 10 + start_period: 20s + networks: + - karbe + + minio: + image: minio/minio:RELEASE.2026-05-24T17-08-30Z + container_name: karbe-minio + restart: unless-stopped + environment: + MINIO_ROOT_USER: ${MINIO_ROOT_USER:-karbe} + MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?MINIO_ROOT_PASSWORD must be set} + command: server /data --console-address ":9001" + volumes: + - minio_data:/data + healthcheck: + test: ["CMD", "curl", "-fsS", "http://127.0.0.1:9000/minio/health/live"] + interval: 30s + timeout: 5s + retries: 5 + start_period: 20s + networks: + - karbe + + minio-init: + image: minio/mc:RELEASE.2026-05-21T01-59-54Z + container_name: karbe-minio-init + depends_on: + minio: + condition: service_healthy + restart: "no" + entrypoint: > + /bin/sh -c " + mc alias set karbe http://minio:9000 $$MINIO_ROOT_USER $$MINIO_ROOT_PASSWORD && + mc mb -p karbe/$$S3_BUCKET || true + " + environment: + MINIO_ROOT_USER: ${MINIO_ROOT_USER:-karbe} + MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:?MINIO_ROOT_PASSWORD must be set} + S3_BUCKET: ${S3_BUCKET:-karbe-medias} + networks: + - karbe + app: build: context: . @@ -7,6 +64,13 @@ services: restart: unless-stopped env_file: - .env.production + depends_on: + postgres: + condition: service_healthy + minio: + condition: service_healthy + minio-init: + condition: service_completed_successfully networks: - karbe healthcheck: @@ -38,5 +102,7 @@ networks: name: karbe-net volumes: + postgres_data: + minio_data: caddy_data: caddy_config: