diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000..f01fb8b --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,33 @@ +# Déploiement front — VPS Hostinger + +Le front (`src/e`, `src/admin`, `src/vendor`) est servi par un container +`nginx:alpine` sur le VPS existant (celui de n8n), rattaché au réseau Docker +`n8n_default` pour que Traefik (déjà en place pour n8n) puisse le router. + +- **Domaine** : `photobooth.assistantaikev.eu` (DNS A → IP du VPS, cf. + `~/.claude/CLAUDE.md` pour l'IP à jour) +- **Emplacement sur le VPS** : `~/photobooth-qr/` (dossier de `kevin`, pas de + sudo requis — contrairement à `/docker/n8n/` qui est root) +- **Fichiers** : + - `docker-compose.yml` (ce dossier) — service `photobooth-front`, labels + Traefik pour le routage/SSL (réutilise le certresolver `mytlschallenge` + déjà configuré pour n8n) + - `nginx-photobooth.conf` (ce dossier) — réécriture `/e/` et + `/admin/` vers les `index.html` respectifs + - `site/` (non versionné ici, généré à partir de `src/`) — copie de + `src/e`, `src/admin`, `src/vendor`, **avec** les vrais `config.js` + (gitignorés dans le repo principal, à recréer sur le VPS à partir de + `src/e/config.example.js` / `src/admin/gallery/config.example.js`) + +## Redéployer après une modification du front + +Depuis la machine locale (pas besoin de sudo, `kevin` possède le dossier) : + +```bash +scp -r src/e src/admin src/vendor kevin@:~/photobooth-qr/site/ +# Recréer les config.js réels sur le VPS s'ils ont été écrasés par le scp +ssh kevin@ "cd ~/photobooth-qr && docker compose restart photobooth-front" +``` + +Aucun rebuild d'image nécessaire — c'est un bind-mount, nginx sert les +fichiers directement. diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml new file mode 100644 index 0000000..29b18dc --- /dev/null +++ b/deploy/docker-compose.yml @@ -0,0 +1,29 @@ +services: + photobooth-front: + image: nginx:alpine + restart: always + labels: + - traefik.enable=true + - traefik.http.routers.photobooth.rule=Host(`photobooth.assistantaikev.eu`) + - traefik.http.routers.photobooth.tls=true + - traefik.http.routers.photobooth.entrypoints=web,websecure + - traefik.http.routers.photobooth.tls.certresolver=mytlschallenge + - traefik.http.middlewares.photobooth.headers.SSLRedirect=true + - traefik.http.middlewares.photobooth.headers.STSSeconds=315360000 + - traefik.http.middlewares.photobooth.headers.browserXSSFilter=true + - traefik.http.middlewares.photobooth.headers.contentTypeNosniff=true + - traefik.http.middlewares.photobooth.headers.forceSTSHeader=true + - traefik.http.middlewares.photobooth.headers.SSLHost=assistantaikev.eu + - traefik.http.middlewares.photobooth.headers.STSIncludeSubdomains=true + - traefik.http.middlewares.photobooth.headers.STSPreload=true + - traefik.http.routers.photobooth.middlewares=photobooth@docker + - traefik.http.services.photobooth.loadbalancer.server.port=80 + volumes: + - ./site:/usr/share/nginx/html:ro + - ./nginx-photobooth.conf:/etc/nginx/conf.d/default.conf:ro + networks: + - n8n_default + +networks: + n8n_default: + external: true diff --git a/deploy/nginx-photobooth.conf b/deploy/nginx-photobooth.conf new file mode 100644 index 0000000..f142338 --- /dev/null +++ b/deploy/nginx-photobooth.conf @@ -0,0 +1,27 @@ +server { + listen 80; + server_name _; + root /usr/share/nginx/html; + index index.html; + + # /e/ -> page upload invité, le slug est lu côté client via + # window.location.pathname (cf. src/e/upload.js) + location /e/ { + try_files $uri $uri/ /e/index.html; + } + + # /admin/?token=... -> galerie admin, slug lu côté client. + # /admin/qrcode/ reste servi tel quel (fichier réel, try_files le trouve + # avant de tomber sur le fallback ci-dessous). + location /admin/ { + try_files $uri $uri/ /admin/gallery/index.html; + } + + location /vendor/ { + try_files $uri =404; + } + + location = / { + return 302 /e/; + } +} diff --git a/docs/decisions.md b/docs/decisions.md index c8476a7..96f3ead 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -48,6 +48,17 @@ par Kévin. adapté. Risque jugé faible : les slugs sont partagés via QR code, donc non secrets par nature. +## 2026-09-16 (ter) + +- **Domaine de production (V1)** : `photobooth.assistantaikev.eu`, sous-domaine + du domaine déjà utilisé pour n8n. Décision explicitement temporaire : à + déplacer vers un domaine dédié en V2/V3 si le produit est vendu sous sa + propre marque. Front servi par un container nginx sur le VPS existant + (Traefik/Let's Encrypt déjà en place pour n8n), config dans `deploy/`. + `APP_BASE_URL` configurée comme secret sur les 2 Edge Functions pour le + CORS. Déploiement testé en conditions réelles le 2026-09-16 (upload + + galerie admin fonctionnels depuis le domaine public). + ## 2026-09-16 (bis) - **Déclenchement de la purge Storage à J+7** : **option n8n retenue**