From 7b3e50ff297efc016196778fa9b8acb26a51350a Mon Sep 17 00:00:00 2001 From: Bastien COIGNOUX Date: Sun, 3 May 2026 22:17:48 +0200 Subject: [PATCH] init --- Makefile | 116 ++++++++++++++++++++++++++++ README.md | 163 ++++++++++++++++++++++++++++++++++++++++ docker-compose.dev.yml | 32 ++++++++ docker-compose.prod.yml | 59 +++++++++++++++ env.example.txt | 20 +++++ 5 files changed, 390 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 docker-compose.dev.yml create mode 100644 docker-compose.prod.yml create mode 100644 env.example.txt diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8e4a5d7 --- /dev/null +++ b/Makefile @@ -0,0 +1,116 @@ +# ============================================================ +# Makefile — Raccourcis pour le projet mb-app +# Usage : make +# ============================================================ + +.PHONY: help dev dev-stop prod prod-stop logs status setup-nas deploy + +# Affiche l'aide +help: + @echo "" + @echo " Développement local" + @echo " ─────────────────────────────────────────" + @echo " make dev → Lance PocketBase en local" + @echo " make dev-stop → Arrête le conteneur local" + @echo " make logs → Logs PocketBase en temps réel" + @echo " make status → État des conteneurs" + @echo "" + @echo " Production NAS" + @echo " ─────────────────────────────────────────" + @echo " make prod → Lance la stack complète NAS" + @echo " make prod-stop → Arrête tout" + @echo " make deploy → git pull + restart (sur le NAS)" + @echo "" + @echo " Setup" + @echo " ─────────────────────────────────────────" + @echo " make setup → Crée les dossiers manquants" + @echo " make ssl → Obtient le certificat SSL (1ère fois)" + @echo " make renew-ssl → Renouvelle le certificat SSL" + @echo "" + +# ── DÉVELOPPEMENT LOCAL ────────────────────────────────────── + +dev: + @echo "🚀 Lancement PocketBase en local..." + @[ -f .env.local ] || (echo "❌ Fichier .env.local manquant ! Copier .env.example" && exit 1) + docker compose -f docker/docker-compose.dev.yml up -d + @echo "✅ PocketBase : http://localhost:8090" + @echo "✅ Admin : http://localhost:8090/_/" + +dev-stop: + docker compose -f docker/docker-compose.dev.yml down + +dev-reset: + @echo "⚠️ Supprime les données locales de dev !" + @read -p "Confirmer ? (oui/non) : " c; [ "$$c" = "oui" ] || exit 1 + docker compose -f docker/docker-compose.dev.yml down + rm -rf pocketbase/pb_data + @echo "✅ Données supprimées" + +# ── PRODUCTION NAS ─────────────────────────────────────────── + +prod: + @echo "🚀 Lancement stack production..." + @[ -f .env.production ] || (echo "❌ Fichier .env.production manquant !" && exit 1) + docker compose -f docker/docker-compose.prod.yml up -d + @echo "✅ Stack lancée" + +prod-stop: + docker compose -f docker/docker-compose.prod.yml down + +deploy: + @echo "📦 Déploiement en cours..." + git pull origin main + docker compose -f docker/docker-compose.prod.yml restart pocketbase + @echo "✅ Déployé" + +# ── LOGS & STATUS ──────────────────────────────────────────── + +logs: + docker compose -f docker/docker-compose.dev.yml logs -f pocketbase + +logs-prod: + docker compose -f docker/docker-compose.prod.yml logs -f pocketbase + +status: + docker compose -f docker/docker-compose.dev.yml ps + +# ── SETUP ──────────────────────────────────────────────────── + +setup: + @echo "📁 Création des dossiers..." + mkdir -p pocketbase/pb_data + mkdir -p pocketbase/pb_hooks + mkdir -p pocketbase/pb_migrations + @[ -f .env.local ] || cp .env.example .env.local + @echo "✅ Structure prête" + @echo "👉 Éditer .env.local avec votre clé Anthropic" + +setup-nas: + @echo "📁 Création des dossiers sur le NAS..." + mkdir -p /volume1/docker/mb-app/pb_data + mkdir -p /volume1/docker/mb-app/ssl + mkdir -p /volume1/docker/mb-app/duckdns + @[ -f .env.production ] || cp .env.example .env.production + @echo "✅ Dossiers NAS créés" + @echo "👉 Éditer .env.production" + +ssl: + @echo "🔐 Obtention certificat SSL..." + @[ -f .env.production ] || (echo "❌ .env.production manquant" && exit 1) + @source .env.production && docker run --rm \ + -v /volume1/docker/mb-app/ssl:/etc/letsencrypt \ + -v /tmp/certbot-webroot:/var/www/certbot \ + -p 80:80 \ + certbot/certbot certonly --standalone \ + -d $$DUCKDNS_SUBDOMAINS.duckdns.org \ + --non-interactive --agree-tos \ + --email admin@example.com + @echo "✅ Certificat obtenu" + +renew-ssl: + docker run --rm \ + -v /volume1/docker/mb-app/ssl:/etc/letsencrypt \ + certbot/certbot renew --quiet + docker compose -f docker/docker-compose.prod.yml restart nginx + @echo "✅ Certificat renouvelé" diff --git a/README.md b/README.md new file mode 100644 index 0000000..f26b1ec --- /dev/null +++ b/README.md @@ -0,0 +1,163 @@ +# mb-app — Application Marchand de Biens + +Application mobile et web pour la gestion quotidienne d'une activité de marchand de biens immobiliers. + +**Stack :** React Native (Expo) + PocketBase (self-hosted sur NAS Synology) + IA Claude + +--- + +## Démarrage rapide + +### Prérequis +- Docker Desktop (Mac/Windows) ou Docker Engine (Linux/NAS) +- Node.js 18+ +- Un compte DuckDNS (gratuit) pour l'accès distant + +### 1. Cloner le projet + +```bash +git clone https://github.com/VOUS/mb-app.git +cd mb-app +``` + +### 2. Setup initial + +```bash +make setup +# → Crée les dossiers nécessaires +# → Copie .env.example en .env.local +``` + +Éditer `.env.local` : +``` +EXPO_PUBLIC_PB_URL=http://localhost:8090 +ANTHROPIC_API_KEY=sk-ant-VOTRE_CLE +``` + +### 3. Lancer en développement + +```bash +# Terminal 1 — Backend PocketBase +make dev +# → PocketBase sur http://localhost:8090 +# → Admin sur http://localhost:8090/_/ + +# Terminal 2 — App Expo +cd app +npm install +npx expo start +``` + +**Première fois :** Aller sur http://localhost:8090/_/ → créer le compte admin +→ Settings → Import collections → coller le contenu de `pocketbase/pb_collections.json` + +--- + +## Déploiement sur le NAS Synology + +### 1. Cloner sur le NAS + +```bash +# Se connecter en SSH au NAS +ssh admin@IP_DU_NAS + +# Cloner le projet +git clone https://github.com/VOUS/mb-app.git /volume1/docker/mb-app +cd /volume1/docker/mb-app +``` + +### 2. Configurer l'environnement production + +```bash +make setup-nas +# Puis éditer .env.production : +nano .env.production +``` + +``` +EXPO_PUBLIC_PB_URL=https://mon-sous-domaine.duckdns.org +ANTHROPIC_API_KEY=sk-ant-VOTRE_CLE +DUCKDNS_SUBDOMAINS=mon-sous-domaine +DUCKDNS_TOKEN=VOTRE_TOKEN_DUCKDNS +``` + +### 3. Ouvrir les ports sur votre box internet +- Port 80 → IP du NAS, port 80 +- Port 443 → IP du NAS, port 443 + +### 4. Obtenir le certificat SSL + +```bash +make ssl +``` + +### 5. Lancer la stack + +```bash +make prod +``` + +### Mettre à jour après un git push + +```bash +# Sur le NAS : +make deploy +# → git pull + restart PocketBase (les hooks sont rechargés) +``` + +--- + +## Workflow de développement + +``` +[Local] Coder + tester + ↓ +git add . && git commit -m "feat: module visites" + ↓ +git push origin main + ↓ +[NAS] make deploy +``` + +Les **données** (`pb_data/`) restent sur chaque machine et ne sont jamais dans Git. +Le **code** (hooks, migrations, app) est versionné et déployé via Git. + +--- + +## Structure du projet + +``` +mb-app/ +├── app/ ← Code React Native (Expo Router) +├── pocketbase/ +│ ├── pb_hooks/ ← Hooks JS côté serveur (IA, etc.) +│ ├── pb_migrations/ ← Migrations auto PocketBase +│ └── pb_collections.json ← Schéma des collections +├── docker/ +│ ├── docker-compose.dev.yml +│ ├── docker-compose.prod.yml +│ └── nginx.prod.conf +├── .cursorrules ← Contexte pour Cursor AI +├── AGENTS.md ← Suivi des sessions de développement +└── Makefile ← Raccourcis commandes +``` + +--- + +## Commandes utiles + +| Commande | Description | +|---|---| +| `make dev` | Lance PocketBase en local | +| `make dev-stop` | Arrête le dev | +| `make logs` | Logs en temps réel | +| `make prod` | Lance la stack NAS | +| `make deploy` | git pull + redémarre (sur NAS) | +| `make renew-ssl` | Renouvelle le certificat SSL | + +--- + +## Backup des données + +Les données PocketBase sont dans `pb_data/` (exclu du Git). +Configurer une tâche Synology Hyper Backup sur `/volume1/docker/mb-app/pb_data/`. diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..d9b6d69 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,32 @@ +version: '3.8' + +# ============================================================ +# DÉVELOPPEMENT LOCAL — docker compose -f docker/docker-compose.dev.yml up +# PocketBase accessible sur http://localhost:8090 +# Admin PocketBase : http://localhost:8090/_/ +# ============================================================ + +services: + + pocketbase: + image: ghcr.io/muchobien/pocketbase:latest + container_name: mb-pocketbase-dev + restart: unless-stopped + ports: + - "8090:8090" # Accès direct sans Nginx en dev + volumes: + # Données locales (dans .gitignore) + - ../pocketbase/pb_data:/pb/pb_data + # Hooks JS versionnés dans Git ✅ + - ../pocketbase/pb_hooks:/pb/pb_hooks + # Migrations versionnées dans Git ✅ + - ../pocketbase/pb_migrations:/pb/pb_migrations + env_file: + - ../.env.local # Clé Anthropic en local + environment: + - TZ=Europe/Paris + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8090/api/health"] + interval: 15s + timeout: 5s + retries: 3 diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..3cd94a0 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,59 @@ +version: '3.8' + +# ============================================================ +# PRODUCTION NAS — docker compose -f docker/docker-compose.prod.yml up -d +# Accessible sur https://VOTRE_SOUS_DOMAINE.duckdns.org +# ============================================================ + +services: + + pocketbase: + image: ghcr.io/muchobien/pocketbase:latest + container_name: mb-pocketbase + restart: unless-stopped + # Pas de port exposé directement : Nginx fait le proxy + expose: + - "8090" + volumes: + # Données persistantes NAS (dans .gitignore) + - /volume1/docker/mb-app/pb_data:/pb/pb_data + # Hooks et migrations versionnés dans Git ✅ + - ../pocketbase/pb_hooks:/pb/pb_hooks + - ../pocketbase/pb_migrations:/pb/pb_migrations + env_file: + - ../.env.production + environment: + - TZ=Europe/Paris + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8090/api/health"] + interval: 30s + timeout: 10s + retries: 3 + + nginx: + image: nginx:alpine + container_name: mb-nginx + restart: unless-stopped + ports: + - "80:80" + - "443:443" + volumes: + - ./nginx.prod.conf:/etc/nginx/nginx.conf:ro + - /volume1/docker/mb-app/ssl:/etc/nginx/ssl:ro + depends_on: + pocketbase: + condition: service_healthy + + duckdns: + image: lscr.io/linuxserver/duckdns:latest + container_name: mb-duckdns + restart: unless-stopped + environment: + - TZ=Europe/Paris + - SUBDOMAINS=${DUCKDNS_SUBDOMAINS} + - TOKEN=${DUCKDNS_TOKEN} + - LOG_FILE=true + env_file: + - ../.env.production + volumes: + - /volume1/docker/mb-app/duckdns:/config diff --git a/env.example.txt b/env.example.txt new file mode 100644 index 0000000..b010147 --- /dev/null +++ b/env.example.txt @@ -0,0 +1,20 @@ +# ============================================================ +# .env.example — Copier en .env.local (dev) ou .env.production +# NE PAS mettre de vraies valeurs dans ce fichier +# ============================================================ + +# ── URL PocketBase ─────────────────────────────────────────── +# Dev local : +EXPO_PUBLIC_PB_URL=http://localhost:8090 +# Production NAS : +# EXPO_PUBLIC_PB_URL=https://VOTRE_SOUS_DOMAINE.duckdns.org + +# ── PocketBase (côté serveur Docker) ───────────────────────── +ANTHROPIC_API_KEY=sk-ant-VOTRE_CLE_ICI + +# ── DuckDNS (production uniquement) ────────────────────────── +DUCKDNS_SUBDOMAINS=VOTRE_SOUS_DOMAINE +DUCKDNS_TOKEN=VOTRE_TOKEN_DUCKDNS + +# ── Expo (optionnel, pour EAS Build) ───────────────────────── +# EXPO_TOKEN=