init
This commit is contained in:
116
Makefile
Normal file
116
Makefile
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
# ============================================================
|
||||||
|
# Makefile — Raccourcis pour le projet mb-app
|
||||||
|
# Usage : make <commande>
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
.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é"
|
||||||
163
README.md
Normal file
163
README.md
Normal file
@ -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/`.
|
||||||
32
docker-compose.dev.yml
Normal file
32
docker-compose.dev.yml
Normal file
@ -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
|
||||||
59
docker-compose.prod.yml
Normal file
59
docker-compose.prod.yml
Normal file
@ -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
|
||||||
20
env.example.txt
Normal file
20
env.example.txt
Normal file
@ -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=
|
||||||
Reference in New Issue
Block a user