diff --git a/.env.example b/.env.example index 9b573dd..1408f16 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,26 @@ -DATABASE_URL=postgresql+asyncpg://homehub:homehub@db:5432/homehub -UPLOAD_DIR=/uploads -CORS_ORIGINS=http://localhost:3001,http://localhost:3000 -MCP_API_KEY= +# ── HomeHub — variables d'environnement ── +# Copier en .env et compléter. Ne JAMAIS committer le .env réel. + +# PostgreSQL +POSTGRES_USER=homehub +POSTGRES_PASSWORD=change-me +POSTGRES_DB=homehub + +# Connexion backend (alignée sur les valeurs PostgreSQL ci-dessus) +DATABASE_URL=postgresql+asyncpg://homehub:change-me@db:5432/homehub + +# Stockage médias / données +UPLOAD_DIR=/data/uploads +DATA_DIR=/data + +# Redis +REDIS_URL=redis://redis:6379 + +# CORS — réseau local autorisé (séparés par des virgules) +CORS_ORIGINS=http://localhost:3001,http://10.0.0.50:3001 + +# Clé Bearer du serveur MCP (générer une valeur aléatoire forte) +MCP_API_KEY=change-me + +# Port exposé du frontend (déploiement) +FRONTEND_PORT=3001 diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..fb777f4 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,54 @@ +name: Build & Push OCI + +# Construit et publie les images HomeHub sur le registre OCI Gitea. +# - push sur main -> tags -latest +# - tag git vX.Y.Z -> tags -latest + -X.Y.Z +on: + push: + branches: [main] + tags: ["v*"] + +env: + REGISTRY: git.maison43gil.com + IMAGE: git.maison43gil.com/gilles/home_hub + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - role: backend + context: ./backend + - role: frontend + context: ./frontend + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login au registre OCI Gitea + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Déduire les tags + id: tags + run: | + TAGS="${IMAGE}:${{ matrix.role }}-latest" + if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then + VERSION="${GITHUB_REF#refs/tags/v}" + TAGS="${TAGS},${IMAGE}:${{ matrix.role }}-${VERSION}" + fi + echo "tags=${TAGS}" >> "$GITHUB_OUTPUT" + + - name: Build & push ${{ matrix.role }} + uses: docker/build-push-action@v6 + with: + context: ${{ matrix.context }} + push: true + tags: ${{ steps.tags.outputs.tags }} diff --git a/README.md b/README.md index 306dad2..47f0f06 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,64 @@ docker compose up -d # homehub.local/mcp → backend:8000/mcp (pour les agents IA) ``` +## Déploiement via registre OCI Gitea + +Les images finales sont publiées sur le registre OCI privé `git.maison43gil.com` +(source unique de vérité). Deux images sous le paquet `home_hub`, distinguées par tag : + +| Image | Tag | +|-------|-----| +| Backend (FastAPI) | `git.maison43gil.com/gilles/home_hub:backend-latest` | +| Frontend (Nginx) | `git.maison43gil.com/gilles/home_hub:frontend-latest` | + +### Construction & publication (manuel) + +```bash +docker login git.maison43gil.com + +# Backend +docker build -t git.maison43gil.com/gilles/home_hub:backend-latest ./backend +docker push git.maison43gil.com/gilles/home_hub:backend-latest + +# Frontend +docker build -t git.maison43gil.com/gilles/home_hub:frontend-latest ./frontend +docker push git.maison43gil.com/gilles/home_hub:frontend-latest +``` + +> Le registre est derrière Nginx Proxy Manager : pour les gros blobs (image +> backend ~1.3 Go), régler `client_max_body_size 0;` dans l'onglet Advanced +> du proxy host `git.maison43gil.com` (sinon erreur `413 Payload Too Large`). + +### Construction automatique (Gitea Actions) + +`.gitea/workflows/build.yml` build et push les deux images : +- push sur `main` → tags `*-latest` +- tag git `vX.Y.Z` → tags `*-latest` + `*-X.Y.Z` + +### Déploiement sur le serveur + +```bash +# Sur le serveur de production +git pull # récupère docker-compose.deploy.yml + .env.example +cp .env.example .env # compléter les secrets (POSTGRES_PASSWORD, MCP_API_KEY…) + +docker login git.maison43gil.com +docker compose -f docker-compose.deploy.yml pull +docker compose -f docker-compose.deploy.yml up -d +``` + +Le service `backend-migrate` applique automatiquement les migrations Alembic +(`alembic upgrade head`) avant le démarrage du backend. Aucune image n'est +reconstruite en production (pas de `build:`). + +### Environnements + +| Fichier | Usage | Images | +|---------|-------|--------| +| `docker-compose.yml` | Dev (build local) | `build:` | +| `docker-compose.dev.yml` | Override dev (HMR + `--reload`) | `build:` | +| `docker-compose.deploy.yml` | **Production** | `image:` (OCI Gitea) | + ## Évolutions prévues - **Phase 5** — Scan code-barres (zxing-js) + enrichissement catalogue via OpenFoodFacts diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..aee29e5 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,11 @@ +.venv/ +__pycache__/ +*.pyc +*.pyo +.pytest_cache/ +tests/ +.env +.env.* +*.dump +.mypy_cache/ +.ruff_cache/ diff --git a/docker-compose.deploy.yml b/docker-compose.deploy.yml new file mode 100644 index 0000000..053fbc6 --- /dev/null +++ b/docker-compose.deploy.yml @@ -0,0 +1,109 @@ +# Environnement de PRODUCTION — images publiées sur le registre OCI Gitea. +# Aucune image n'est reconstruite ici (pas de build:). Source unique de vérité : +# git.maison43gil.com/gilles/home_hub +# +# Utilisation : +# docker login git.maison43gil.com +# docker compose -f docker-compose.deploy.yml pull +# docker compose -f docker-compose.deploy.yml up -d +# +# Les secrets proviennent du fichier .env (voir .env.example). +services: + db: + image: postgres:16-alpine + container_name: home_hub_db + restart: unless-stopped + environment: + POSTGRES_USER: ${POSTGRES_USER:-homehub} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD requis} + POSTGRES_DB: ${POSTGRES_DB:-homehub} + volumes: + - db_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-homehub}"] + interval: 5s + timeout: 5s + retries: 10 + + redis: + image: redis:7-alpine + container_name: home_hub_redis + restart: unless-stopped + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 5s + retries: 10 + + # Applique les migrations Alembic puis se termine. Le backend attend son succès. + backend-migrate: + image: git.maison43gil.com/gilles/home_hub:backend-latest + container_name: home_hub_migrate + user: "1000:1000" + command: alembic upgrade head + environment: + DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-homehub}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD requis}@db:5432/${POSTGRES_DB:-homehub} + DATA_DIR: /data + volumes: + - ./data:/data + depends_on: + db: + condition: service_healthy + + backend: + image: git.maison43gil.com/gilles/home_hub:backend-latest + container_name: home_hub_backend + restart: unless-stopped + user: "1000:1000" + environment: + DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-homehub}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD requis}@db:5432/${POSTGRES_DB:-homehub} + UPLOAD_DIR: /data/uploads + DATA_DIR: /data + REDIS_URL: redis://redis:6379 + CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3001} + MCP_API_KEY: ${MCP_API_KEY:?MCP_API_KEY requis} + volumes: + - ./data:/data + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + backend-migrate: + condition: service_completed_successfully + + backend-worker: + image: git.maison43gil.com/gilles/home_hub:backend-latest + container_name: home_hub_worker + restart: unless-stopped + user: "1000:1000" + command: arq app.workers.notes_worker.WorkerSettings + environment: + DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-homehub}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD requis}@db:5432/${POSTGRES_DB:-homehub} + UPLOAD_DIR: /data/uploads + DATA_DIR: /data + REDIS_URL: redis://redis:6379 + volumes: + - ./data:/data + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + backend-migrate: + condition: service_completed_successfully + + frontend: + image: git.maison43gil.com/gilles/home_hub:frontend-latest + container_name: home_hub_frontend + restart: unless-stopped + ports: + - "${FRONTEND_PORT:-3001}:80" + depends_on: + - backend + +volumes: + db_data: + redis_data: diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..301a5a0 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,6 @@ +node_modules/ +dist/ +.env +.env.* +*.log +.vite/