Files
photoBooth/docs/INSTALL-FROM-SCRATCH.md
T
admin 3de55821b7
🚀 Deploy — JH Photomaton / 🔍 Vérification (push) Has been cancelled
🚀 Deploy — JH Photomaton / 🍓 Deploy sur le Pi (push) Has been cancelled
all
2026-07-17 01:13:57 +02:00

675 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Guide d'installation from scratch — JH Photomaton
**Raspberry Pi 4 (2 Go) · Pi Camera Module V3 · Pi OS Lite 64-bit + cage (kiosk Wayland)**
*Les Sapins Du Web — juillet 2026*
---
## Vue d'ensemble du stack
```
Internet / réseau local
[Zoraxy] :443 / :80 — reverse proxy HTTPS
[RaspAP] — point d'accès WiFi "Photomaton"
┌──────┴──────────────────────┐
│ photobooth-app :8000 │ — kiosque, caméra, frames
│ JH Photomaton :8090 │ — admin, LEDs, bouton, imprimantes
│ CUPS :631 │ — Canon Selphy CP1300 x2
└─────────────────────────────┘
```
**Matériel :**
- Raspberry Pi 4 (2 Go RAM), carte SD 32 Go+
- Pi Camera Module V3 (Sony IMX708, 12 MP)
- Anneau LED WS2812b — 35 LEDs — GPIO 18
- Bouton arcade — GPIO 23 / Relay — GPIO 12
- 2× Canon Selphy CP1300
---
## Étape 1 — Flasher la carte SD
Utiliser **Raspberry Pi Imager** sur ton PC :
- OS : **Raspberry Pi OS Lite (64-bit)** — sans bureau *(choisir "Raspberry Pi OS (other)" → "Lite")*
- Activer SSH, définir utilisateur `pi` et mot de passe dans les options avancées
- Hostname : `photomaton`
- WiFi : **ne pas configurer** (RaspAP va le prendre en charge)
> **Pourquoi Lite ?**
> Le bureau complet (PIXEL) consomme ~450600 Mo RAM à l'idle.
> Lite + cage + Chromium consomme ~150250 Mo — soit ~300 Mo libérés pour picamera2
> et le reste du stack.
> **Bookworm vs Trixie :** Bookworm est plus stable pour picamera2 et rpi-ws281x.
> Si l'ancienne carte tournait sur Trixie sans problème, reste sur Trixie.
Flasher, insérer dans le Pi, brancher en Ethernet, démarrer.
---
## Étape 2 — Premier démarrage et préparation système
```bash
# Trouver l'IP du Pi sur ton réseau local (depuis ton PC)
# Puis se connecter
ssh pi@<IP_DU_PI>
# Mise à jour complète
sudo apt update && sudo apt full-upgrade -y
sudo apt autoremove -y
# Outils essentiels
sudo apt install -y git curl wget vim rsync python3-pip python3-venv \
python3-dev build-essential gcc make
# Redémarrer pour appliquer les mises à jour du noyau
sudo reboot
```
---
## Étape 3 — Désactiver l'audio (requis pour les LEDs WS2812b)
Les LEDs WS2812b utilisent le PWM sur GPIO 18, qui entre en conflit avec la carte son intégrée.
```bash
sudo nano /boot/firmware/config.txt
```
Trouver la ligne `dtparam=audio=on` et la remplacer par :
```
dtparam=audio=off
```
Ajouter aussi en bas du fichier (si pas déjà présent) :
```
# Désactive le Bluetooth pour libérer l'UART si besoin
dtoverlay=disable-bt
```
Sauvegarder et redémarrer :
```bash
sudo reboot
```
---
## Étape 4 — Installer l'environnement kiosk (cage + Chromium)
Sur Pi OS Lite, il n'y a pas de bureau. On installe uniquement ce qu'il faut pour afficher Chromium en mode kiosque via le compositeur Wayland minimal **cage**.
```bash
sudo apt install -y \
cage \
chromium-browser \
xdg-utils \
fonts-liberation \
fonts-noto \
dbus-user-session \
libcap2-bin
```
### Auto-login console
```bash
sudo raspi-config
# → System Options → Boot / Auto Login → Console Autologin
```
### Service kiosk systemd
Ce service démarre cage + Chromium automatiquement au boot, après que photobooth-app soit prêt.
```bash
sudo nano /etc/systemd/system/photobooth-kiosk.service
```
```ini
[Unit]
Description=Photobooth Kiosk (cage + Chromium)
After=photobooth-app.service network.target
Wants=photobooth-app.service
[Service]
Type=simple
User=pi
PAMName=login
TTYPath=/dev/tty1
StandardInput=tty
Environment=XDG_RUNTIME_DIR=/run/user/1000
Environment=WAYLAND_DISPLAY=wayland-1
# Attendre que photobooth-app soit prêt
ExecStartPre=/bin/sleep 8
ExecStart=/usr/bin/cage -- /usr/bin/chromium-browser \
--kiosk \
--noerrdialogs \
--disable-infobars \
--disable-session-crashed-bubble \
--disable-features=TranslateUI \
--no-first-run \
--disable-restore-session-state \
--autoplay-policy=no-user-gesture-required \
http://localhost:8000
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```
```bash
sudo systemctl daemon-reload
sudo systemctl enable photobooth-kiosk
```
> **Note :** cage est un compositeur Wayland "single-app" — il lance Chromium et rien d'autre.
> Pas de gestionnaire de fenêtres, pas de barre des tâches, pas de bureau.
> C'est exactement ce qu'on veut pour un kiosque.
---
## Étape 5 — Activer la caméra
```bash
# Installer picamera2 et les outils libcamera (paquets système)
sudo apt install -y python3-picamera2 libcamera-apps
# Vérifier que la caméra est détectée
libcamera-hello --list-cameras
# Doit afficher : "Available cameras" avec le Sony IMX708
```
---
## Étape 6 — Installer photobooth-app
photobooth-app est l'application kiosque qui gère la caméra, le décompte et les frames.
```bash
# photobooth-app crée lui-même ~/photobooth-data/ et ses sous-dossiers au premier lancement
# Installer dans un venv avec accès aux paquets système (nécessaire pour picamera2)
sudo apt install -y python3-venv
python3 -m venv /home/pi/photobooth-venv --system-site-packages
/home/pi/photobooth-venv/bin/pip install photobooth-app
```
### Créer le service systemd pour photobooth-app
```bash
sudo nano /etc/systemd/system/photobooth-app.service
```
```ini
[Unit]
Description=Photobooth App
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/photobooth-data/
ExecStart=/home/pi/photobooth-venv/bin/photobooth
Restart=always
RestartSec=5
Environment=HOME=/home/pi
[Install]
WantedBy=multi-user.target
```
> **WorkingDirectory=/home/pi/photobooth-data/** — c'est le répertoire de travail de photobooth-app.
> Tous ses sous-dossiers (`config/`, `media/`, `userdata/`, `database/`...) y sont créés au premier lancement.
```bash
sudo systemctl daemon-reload
sudo systemctl enable photobooth-app
sudo systemctl start photobooth-app
# Attendre ~10s puis vérifier
sudo systemctl status photobooth-app
```
photobooth-app est accessible sur `http://localhost:8000`.
### Configurer photobooth-app
Accéder à l'interface d'administration : `http://<IP>:8000/admin`
**Réglages à faire impérativement :**
#### a) Backend caméra
`Settings → Backends → Add / Edit` :
- Backend type : **Picamera2**
- Camera num : **0**
- Capture resolution : **4608 × 2592** *(mode natif IMX708 — 14 fps)*
- Preview resolution : **2304 × 1296** *(mode natif — 56 fps, champ complet)*
- Liveview resolution : **960 × 540** *(min. height=500 imposé par photobooth-app, 16:9)*
- Framerate still mode : **14** *(max en full res)*
#### b) Désactiver les GPIO internes de photobooth-app
`Settings → Hardware → GPIO`**désactiver** (JH Photomaton gère ses propres GPIO)
```
gpio_enabled: false
```
#### c) Plugin commander — connecter à JH Photomaton
Copier la config depuis le dépôt après l'avoir cloné (étape 7) :
```bash
# Après avoir cloné le dépôt JH Photomaton :
cp /home/pi/jh-photomaton/photobooth-app/config/plugin_commander_jh.json \
/home/pi/photobooth-data/config/plugin_commander.json
sudo systemctl restart photobooth-app
```
#### d) Bouton "Demande d'impression"
Dans photobooth-app `Settings → Share → Actions` :
Remplacer la share_command :
```
curl http://127.0.0.1:8090/api/print/request?filename={filename}
```
> ⚠️ L'ancienne valeur pointait vers Node-RED (`:1880`). Bien remplacer par `:8090`.
---
## Étape 7 — Cloner et installer JH Photomaton
```bash
# Cloner depuis Gitea
cd /home/pi
git clone https://gitea.lespatas.ovh/admin/photoBooth.git jh-photomaton
cd jh-photomaton
# Lancer l'installation (crée le venv, installe les dépendances, active le service)
sudo bash scripts/install.sh
```
Le script `install.sh` fait automatiquement :
- `apt install` des dépendances système
- Création du venv Python avec `--system-site-packages`
- `pip install -r requirements.txt`
- `pip install rpi-ws281x` (LEDs)
- Copie du service systemd + `systemctl enable`
### Vérifier l'installation
```bash
sudo systemctl status jh-photomaton
sudo journalctl -u jh-photomaton -f
```
Interface admin : `http://<IP>:8090/admin`
Mot de passe : **PhotoBooth2026!**
---
## Étape 8 — Configurer settings.yaml
```bash
nano /home/pi/jh-photomaton/config/settings.yaml
```
Points à vérifier / adapter :
```yaml
app:
port: 8090
admin_password: "PhotoBooth2026!" # changer si voulu
photobooth:
base_url: "http://localhost:8000"
data_dir: "/home/pi/photobooth-data"
media_dir: "/home/pi/photobooth-data/media/processed_full" # chemin réel créé par photobooth-app
event:
name: "Evenement" # sera modifié depuis l'admin
slug: "evenement"
leds:
pin: 18
count: 35 # nombre de LEDs dans l'anneau
brightness: 180 # 0-255, luminosité normale
effects:
capture:
color: [255, 200, 80] # blanc chaud (évite la dominante bleue WS2812b)
flashes: 2
flash_duration: 0.30
button:
pin: 23 # GPIO du bouton arcade
relay_pin: 12 # GPIO du relay
print_enabled: true
print:
mode: "validation"
printers:
- name: "Selphy_Blanche_WiFi"
label: "Selphy Blanche (WiFi)"
- name: "Selphy_Noire_WiFi"
label: "Selphy Noire (WiFi)"
```
Après modification :
```bash
sudo systemctl restart jh-photomaton
```
---
## Étape 9 — Installer CUPS et les imprimantes Selphy
```bash
# Installer CUPS + pilotes Gutenprint
sudo apt install -y cups printer-driver-gutenprint
# Ajouter l'utilisateur pi au groupe lpadmin
sudo usermod -aG lpadmin pi
# Démarrer CUPS
sudo systemctl enable cups
sudo systemctl start cups
# Autoriser l'accès distant à l'interface CUPS
sudo cupsctl --remote-admin
sudo systemctl restart cups
```
Accéder à CUPS : `http://<IP>:631`
### Ajouter les imprimantes
`Administration → Add Printer` pour chaque Selphy :
| Champ | Valeur |
|-------|--------|
| Connection | `socket://192.168.X.X:9100` (IP de la Selphy sur le WiFi) ou USB |
| Name | `Selphy_Blanche_WiFi` *(exactement ce nom — utilisé par le script)* |
| Driver | Canon SELPHY CP1300 — Gutenprint |
| Media | Postcard 100×148mm |
Répéter pour `Selphy_Noire_WiFi`.
### Script d'impression
> ⚠️ `script_print.sh` est un script **custom** — il n'existe pas par défaut.
> Il doit être copié depuis l'ancienne carte SD (voir Étape 12).
```bash
# Créer le dossier s'il n'existe pas
mkdir -p /home/pi/photobooth-data/script/
# Après copie depuis l'ancienne carte, rendre exécutable
chmod +x /home/pi/photobooth-data/script/script_print.sh
# Test manuel
/home/pi/photobooth-data/script/script_print.sh \
"/home/pi/photobooth-data/media/processed_full/test.jpg" \
"image" "test" "1"
# Doit retourner : PRINTED:Selphy_Blanche_WiFi:1
```
---
## Étape 10 — Point d'accès WiFi (hostapd + dnsmasq)
> **Pourquoi pas RaspAP ?**
> RaspAP installe lighttpd + PHP + une interface web — ~40 Mo de RAM pour une UI qu'on n'utilise pas.
> On configure directement hostapd et dnsmasq, ce qu'il y a en dessous.
```bash
sudo apt install -y hostapd dnsmasq
sudo systemctl unmask hostapd
```
### IP statique sur wlan0
Ajouter dans `/etc/dhcpcd.conf` :
```ini
interface wlan0
static ip_address=192.168.230.1/24
nohook wpa_supplicant
```
### hostapd — point d'accès WiFi ouvert
```bash
sudo nano /etc/hostapd/hostapd.conf
```
```ini
interface=wlan0
driver=nl80211
ssid=Photomaton-LSDW
hw_mode=g
channel=6
wmm_enabled=0
macaddr_acl=0
# WiFi ouvert — pas de mot de passe
auth_algs=1
ignore_broadcast_ssid=0
```
Déclarer le fichier de config dans `/etc/default/hostapd` :
```ini
DAEMON_CONF="/etc/hostapd/hostapd.conf"
```
### dnsmasq — DHCP + redirection DNS (portail captif)
Ajouter à la fin de `/etc/dnsmasq.conf` :
```ini
interface=wlan0
bind-interfaces
# DHCP : distribue des IPs aux clients WiFi
dhcp-range=192.168.230.2,192.168.230.100,255.255.255.0,24h
# Annonce le Pi comme serveur DNS aux clients
dhcp-option=6,192.168.230.1
# ── Portail captif ──────────────────────────────────────────────
# Tout le trafic DNS → Pi (192.168.230.1)
# google.com, instagram.com, lessapinsduweb.com... tout arrive ici.
# Zoraxy fait le tri par HTTP Host header :
# - *.lessapinsduweb.com → apps configurées dans Zoraxy
# - tout le reste → redirect vers photomaton.lessapinsduweb.com
address=/#/192.168.230.1
# Sondes de détection portail captif — iOS et Android ouvrent
# automatiquement le navigateur sur la galerie
address=/captive.apple.com/192.168.230.1
address=/connectivitycheck.gstatic.com/192.168.230.1
address=/detectportal.firefox.com/192.168.230.1
address=/www.msftconnecttest.com/192.168.230.1
```
> **Note :** `address=/#/192.168.230.1` s'applique uniquement aux clients WiFi
> (DHCP sur wlan0). Le Pi lui-même utilise le DNS de son routeur via eth0.
### Activer les services
```bash
sudo systemctl enable --now hostapd
sudo systemctl enable --now dnsmasq
```
---
## Étape 11 — Installer Zoraxy (reverse proxy HTTPS + catch-all)
Zoraxy sert deux rôles ici : reverse proxy HTTPS pour les apps, et redirection
captive portal pour tout le trafic inconnu des clients WiFi.
```bash
# Télécharger le binaire ARM64
mkdir ~/zoraxy && cd ~/zoraxy
wget https://github.com/tobychui/zoraxy/releases/download/v3.3.2/zoraxy_linux_arm64 -O zoraxy
chmod +x zoraxy
# Service systemd
sudo nano /etc/systemd/system/zoraxy.service
```
```ini
[Unit]
Description=Zoraxy Reverse Proxy
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/zoraxy
ExecStart=/home/pi/zoraxy/zoraxy -port=8888
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```
```bash
sudo systemctl daemon-reload
sudo systemctl enable zoraxy
sudo systemctl start zoraxy
```
### Configurer les routes dans Zoraxy
| Hostname | Destination | Notes |
|----------|-------------|-------|
| `photomaton.lessapinsduweb.com` | `127.0.0.1:8000` | Galerie publique / kiosque |
| `admin.lessapinsduweb.com` | `127.0.0.1:8090` | Interface admin JH Photomaton |
| `cups.lessapinsduweb.com` | `127.0.0.1:631` | Optionnel |
| **`*` (catch-all)** | **Redirect → `http://photomaton.lessapinsduweb.com`** | **Portail captif** |
La règle catch-all est la clé : quand un client WiFi tape `google.com`, DNS
résout vers `192.168.230.1`, Zoraxy reçoit la requête, ne reconnaît pas l'hôte,
et redirige vers la galerie photo.
> **Limite HTTPS :** si un client tape `https://google.com`, le navigateur voit
> un certificat invalide et bloque avant la redirection. C'est inhérent à tout
> portail DNS captif. En pratique : QR code sur les tables + iOS/Android qui
> détectent le portail automatiquement via les sondes dnsmasq ci-dessus.
---
## Étape 12 — Copier les données de l'ancienne carte SD
Depuis ton PC, copier les fichiers importants de l'ancienne carte :
```bash
# Monter l'ancienne carte SD sur le PC (remplacer /dev/sdX)
# ou utiliser un lecteur de carte
# Cadres (frames) photobooth
rsync -av /mnt/old-sd/home/pi/photobooth-data/userdata/ \
pi@<IP_DU_PI>:/home/pi/photobooth-data/userdata/
# Script d'impression
rsync -av /mnt/old-sd/home/pi/photobooth-data/script/ \
pi@<IP_DU_PI>:/home/pi/photobooth-data/script/
# Config photobooth-app (actions, frames configurées)
# photobooth-app stocke tout dans ~/photobooth-data/ (WorkingDirectory du service)
rsync -av /mnt/old-sd/home/pi/photobooth-data/ \
pi@<IP_DU_PI>:/home/pi/photobooth-data/
# ⚠️ Après cette copie, vérifier que plugin_commander.json pointe bien vers :8090 (pas :1880)
# Config JH Photomaton (settings.yaml + base SQLite)
rsync -av /mnt/old-sd/home/pi/jh-photomaton/config/settings.yaml \
pi@<IP_DU_PI>:/home/pi/jh-photomaton/config/
rsync -av /mnt/old-sd/home/pi/jh-photomaton/data/ \
pi@<IP_DU_PI>:/home/pi/jh-photomaton/data/
```
---
## Étape 13 — Vérification finale
```bash
# Tous les services actifs ?
sudo systemctl status photobooth-app jh-photomaton cups
# Logs JH Photomaton
sudo journalctl -u jh-photomaton -f
# Tests API rapides
curl http://localhost:8090/api/event # événement en cours
curl http://localhost:8090/api/system/stats # CPU/RAM/temp
# Test LED
curl -X POST "http://localhost:8090/api/leds/play?effect=capture"
# Test webhook photobooth (simule une photo prise)
curl "http://localhost:8090/api/webhook/photobooth?event_key=capture"
curl "http://localhost:8090/api/webhook/photobooth?event_key=finished"
# Imprimantes disponibles
lpstat -p
```
Interface admin : `http://<IP>:8090/admin`
---
## Résumé des ports
| Service | Port | Accès |
|---------|------|-------|
| JH Photomaton (admin) | 8090 | `http://admin.lessapinsduweb.com` ou `http://<IP>:8090/admin` |
| photobooth-app (kiosque) | 8000 | `http://photomaton.lessapinsduweb.com` |
| CUPS (imprimantes) | 631 | `http://<IP>:631` (réseau local uniquement) |
| Zoraxy (proxy admin) | 8888 | `http://192.168.230.1:8888` |
| WiFi hotspot | — | SSID `Photomaton-LSDW` — IP Pi : `192.168.230.1` |
---
## Points d'attention post-installation
1. **plugin_commander.json** — vérifier que la URL pointe vers `:8090` (pas l'ancien Node-RED `:1880`)
2. **share_command dans photobooth-app** — même chose, changer `:1880``:8090/api/print/request`
3. **Nom des imprimantes CUPS** — doit correspondre exactement à ce qui est dans `settings.yaml`
4. **GPIO18 / audio**`dtparam=audio=off` dans `/boot/firmware/config.txt` est obligatoire pour les LEDs
5. **Couleur du flash** — le réglage warm white `[255, 200, 80]` est dans `settings.yaml` → ajustable depuis l'admin dans Réglages → Flash photo
6. **Zoraxy catch-all** — ne pas oublier la règle `*` → redirect `photomaton.lessapinsduweb.com`, c'est elle qui fait le portail captif
7. **DAEMON_CONF hostapd** — sans cette ligne dans `/etc/default/hostapd`, hostapd démarre mais ignore la config (SSID invisible)
---
## CI/CD (déploiement automatique depuis Gitea)
Voir `docs/CI-CD-SETUP.md` pour la configuration complète du pipeline Gitea Actions.
En résumé :
```bash
# Sur le Pi — générer la clé SSH pour le CI
ssh-keygen -t ed25519 -C "gitea-cicd" -f ~/.ssh/gitea_deploy -N ""
cat ~/.ssh/gitea_deploy.pub >> ~/.ssh/authorized_keys
# Installer la règle sudoers
sudo cp /home/pi/jh-photomaton/scripts/sudoers-jh-photomaton /etc/sudoers.d/jh-photomaton
sudo chmod 440 /etc/sudoers.d/jh-photomaton
```
Puis dans Gitea → Settings → Secrets : ajouter `PI_SSH_HOST`, `PI_SSH_USER`, `PI_SSH_KEY`.