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