Search K
Déploiement
SnapOtter se déploie sous la forme d'une pile Docker Compose à 3 conteneurs : l'image applicative SnapOtter, PostgreSQL 17 et Redis 8. L'image applicative prend en charge linux/amd64 (avec NVIDIA CUDA pour l'accélération de l'IA) et linux/arm64 (CPU), elle s'exécute donc nativement sur les serveurs Intel/AMD, les Mac Apple Silicon et les appareils ARM comme le Raspberry Pi 4/5. L'accélération par iGPU Intel/AMD via VA-API, Quick Sync ou OpenCL n'est pas prise en charge pour l'inférence IA aujourd'hui.
Consultez Image Docker pour la configuration GPU, les exemples Docker Compose et l'épinglage de version.
Démarrage rapide (CPU)
yaml
# docker-compose.yml - Copy this file and run: docker compose up -d
services:
SnapOtter:
image: snapotter/snapotter:latest # or ghcr.io/snapotter-hq/snapotter:latest
container_name: SnapOtter
ports:
- "1349:1349" # Web UI + API
volumes:
- SnapOtter-data:/data # AI models, user files (PERSISTENT)
- SnapOtter-workspace:/tmp/workspace # Temp processing files (can be tmpfs)
environment:
# --- Authentication ---
- AUTH_ENABLED=true # Set to false to disable login entirely
- DEFAULT_USERNAME=admin # First-run admin username
- DEFAULT_PASSWORD=admin # First-run admin password (you'll be forced to change it)
# --- Database + Queue ---
- DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter
- REDIS_URL=redis://redis:6379
# --- Limits (set 0 for unlimited) ---
# - MAX_UPLOAD_SIZE_MB=100 # Per-file upload limit in MB
# - MAX_BATCH_SIZE=100 # Max files per batch request
# - RATE_LIMIT_PER_MIN=1000 # API rate limit per IP, default shown (0 = disabled)
# - MAX_USERS=0 # Max user accounts
# --- Networking ---
# - TRUST_PROXY=true # Trust X-Forwarded-For headers (set false if not behind a proxy)
# --- Bind mount permissions ---
# - PUID=1000 # Match your host user's UID (run: id -u)
# - PGID=1000 # Match your host user's GID (run: id -g)
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"]
interval: 30s
timeout: 5s
start_period: 60s
retries: 3
shm_size: "2gb" # Needed for Python ML shared memory
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
postgres:
image: postgres:17-alpine
container_name: SnapOtter-postgres
environment:
POSTGRES_USER: snapotter
POSTGRES_PASSWORD: snapotter # Change this for non-local deployments
POSTGRES_DB: snapotter
volumes:
- SnapOtter-pgdata:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U snapotter"]
interval: 10s
timeout: 5s
retries: 12
start_period: 15s
redis:
image: redis:8-alpine
container_name: SnapOtter-redis
command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"]
volumes:
- SnapOtter-redisdata:/data
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 12
start_period: 10s
volumes:
SnapOtter-data: # Named volume - Docker manages permissions automatically
SnapOtter-workspace:
SnapOtter-pgdata:
SnapOtter-redisdata:bash
docker compose up -dL'application est ensuite disponible sur http://localhost:1349.
Limites de débit Docker Hub ? Remplacez
snapotter/snapotter:latestparghcr.io/snapotter-hq/snapotter:latestpour récupérer l'image depuis GitHub Container Registry à la place. Les deux registres reçoivent la même image à chaque publication.
Démarrage rapide (NVIDIA CUDA)
Pour l'accélération NVIDIA CUDA sur les outils IA (suppression d'arrière-plan, agrandissement, amélioration des visages, OCR) :
yaml
# docker-compose-gpu.yml - Requires: NVIDIA GPU + nvidia-container-toolkit
# Install toolkit: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
services:
SnapOtter:
image: snapotter/snapotter:latest
container_name: SnapOtter
ports:
- "1349:1349"
volumes:
- SnapOtter-data:/data
- SnapOtter-workspace:/tmp/workspace
environment:
- AUTH_ENABLED=true
- DEFAULT_USERNAME=admin
- DEFAULT_PASSWORD=admin
- DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter
- REDIS_URL=redis://redis:6379
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:1349/api/v1/health"]
interval: 30s
timeout: 5s
start_period: 60s
retries: 3
shm_size: "2gb" # Required for PyTorch CUDA shared memory
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all # Or set to 1 for a specific GPU
capabilities: [gpu]
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
postgres:
image: postgres:17-alpine
container_name: SnapOtter-postgres
environment:
POSTGRES_USER: snapotter
POSTGRES_PASSWORD: snapotter
POSTGRES_DB: snapotter
volumes:
- SnapOtter-pgdata:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U snapotter"]
interval: 10s
timeout: 5s
retries: 12
start_period: 15s
redis:
image: redis:8-alpine
container_name: SnapOtter-redis
command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"]
volumes:
- SnapOtter-redisdata:/data
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 12
start_period: 10s
volumes:
SnapOtter-data:
SnapOtter-workspace:
SnapOtter-pgdata:
SnapOtter-redisdata:bash
docker compose -f docker-compose-gpu.yml up -dVérifiez la détection de CUDA dans les journaux :
bash
docker logs SnapOtter 2>&1 | head -20
# Look for: [gpu] CUDA available via torchExigences matérielles
Ces chiffres proviennent de tests de performance sur toute une gamme de systèmes, d'un poste de travail amd64 moderne équipé d'une NVIDIA RTX 4070 jusqu'à un Raspberry Pi, en exécutant l'intégralité du catalogue d'outils sur chacun et en balayant les limites de ressources Docker pour trouver le plancher réel.
Référence rapide
| Niveau | Cas d'usage | CPU | RAM | GPU | Stockage |
|---|---|---|---|---|---|
| Minimum | Outils image, fichiers et PDF légers ; utilisateur unique ; petits lots | 2 cœurs | 2 Go | Aucun | ~7 Go |
| Recommandé | Les cinq modalités, y compris vidéo, PDF et IA sur CPU ; lots ; quelques utilisateurs | 4 cœurs | 4 Go | Aucun | ~25 Go |
| Complet | Tout à pleine vitesse, y compris IA sur GPU ; grands lots ; nombreux utilisateurs | 6-8 cœurs | 8 Go | NVIDIA 8 Go+ de VRAM (12 Go confortable) | ~35 Go |
Architecture : 64 bits uniquement (linux/amd64 ou linux/arm64). SnapOtter s'exécute nativement sur les serveurs Intel/AMD, les Mac Apple Silicon et les cartes ARM 64 bits, y compris le Raspberry Pi 4 et 5 (4-8 Go). Il ne fonctionne pas sur ARM 32 bits (armv7/armhf), aucune image n'étant construite pour cette cible, ni sur les cartes de la classe 512 Mo comme le Pi Zero, qui sont sous le plancher mémoire (voir ci-dessous).
Minimum (outils image, fichiers et PDF légers ; sans IA)
| Ressource | Exigence |
|---|---|
| CPU | 2 cœurs |
| RAM | 2 Go |
| Disque | ~5,5 Go (image) + volume de données |
| GPU | Non requis |
Les 222 outils non-IA du catalogue - image (redimensionner, rogner, convertir, compresser, ajuster, filigraner), vidéo (couper, rendre muet, remultiplexer), audio (convertir, normaliser, couper), PDF (fusionner, diviser, compresser, pivoter, protéger), conversions de fichiers et préréglages de conversion dédiés - s'exécutent sur du matériel modeste. La plupart des opérations se terminent en bien moins d'une seconde, même sur un gros fichier : une image de 2,7 Mo est redimensionnée en ~0,05 s et réencodée en WebP en ~2 s.
Le plancher mémoire est réel, d'après un balayage des limites de ressources Docker : 512 Mo ne peuvent pas démarrer la pile (même un simple redimensionnement d'image est tué), 1 Go gère les opérations sur un seul fichier mais un lot multi-fichiers manque de mémoire, et 2 Go / 2 cœurs est la plus petite configuration qui gère les lots confortablement.
yaml
deploy:
resources:
limits:
cpus: '2'
memory: 2GLa seule exception gourmande en CPU est le réencodage vidéo. Les opérations de copie de flux (couper, rendre muet, remultiplexage de conteneur) sont instantanées, mais le transcodage vers un codec différent est limité par le CPU. Un clip 1080p / 45 secondes réencodé en VP9 (WebM) prend environ ~40 s sur un CPU moderne rapide, ~45 s sur Apple Silicon, ~80 s sur un ancien 4 cœurs mobile et ~130 s sur un ancien serveur 4 cœurs. Si votre charge de travail est axée sur la vidéo, privilégiez les cœurs CPU et la fréquence d'horloge, ou augmentez la limite cpus: du conteneur : le compose fourni plafonne l'application à 4 cœurs par défaut (8 sur le compose GPU).
Recommandé (outils IA sur CPU)
| Ressource | Exigence |
|---|---|
| CPU | 4 cœurs |
| RAM | 4 Go |
| Disque | 3 Go (image) + 24 Go (modèles IA) + espace de travail |
| GPU | Non requis (repli sur CPU) |
C'est l'installation des bundles IA qui pousse la RAM à 4 Go. Sans IA installée, l'application est au repos autour de 360 Mo ; avec les sept bundles installés, elle maintient ~2,6 Go résidents, car le sidecar IA Python précharge ses modèles (suppression d'arrière-plan, agrandissement, OCR, transcription, détection de visages, restauration) au démarrage. Les installations non-IA restent légères ; les installations IA nécessitent ≥4 Go.
La plupart des outils IA sont parfaitement utilisables sur CPU ; deux ou trois veulent vraiment un GPU. Mesuré sur un CPU 4 cœurs moderne :
| Outil IA | Temps CPU | Utilisable sur CPU ? |
|---|---|---|
| Détection de visages (flouter les visages, recadrage intelligent, yeux rouges), suppression du bruit | moins de 1 s | Oui |
| OCR, transcription, sous-titres | 1-3 s | Oui |
| Coloriser, amélioration des visages | ~10 s | Oui |
| Suppression / remplacement / floutage d'arrière-plan | ~29 s | Oui (il faudra patienter) |
| Agrandissement IA (RealESRGAN) | ~33 s sur petit format ; plusieurs minutes sur les grandes images | Limite - GPU fortement recommandé |
| Restauration de photo (pipeline complet) | plusieurs minutes | Non - nécessite un GPU ou un CPU rapide à nombreux cœurs |
SnapOtter n'intègre volontairement pas ces téléchargements de modèles dans l'image Docker. Les bundles IA ne sont récupérés que lorsqu'un administrateur active l'outil concerné, stockés dans le volume persistant /data/ai et partagés par chaque outil qui dépend de la même pile de modèles. Cela maintient l'image finale du conteneur petite tout en permettant à une installation IA complète d'atteindre les chiffres de stockage plus élevés ci-dessous.
Certains outils dépendent de plus d'un bundle partagé. Par exemple, Photo d'identité a besoin à la fois de background-removal et de face-detection ; si background-removal est déjà installé, activer Photo d'identité ne télécharge que le bundle face-detection manquant. La même réutilisation s'applique à tous les outils IA.
Tailles de téléchargement des modèles IA :
| Bundle | Taille disque |
|---|---|
| Suppression d'arrière-plan | 4-5 Go |
| Agrandissement + Amélioration des visages + Suppression du bruit | 5-6 Go |
| Détection de visages | 200-300 Mo |
| Gomme d'objets + Coloriser | 1-2 Go |
| OCR | 5-6 Go |
| Restauration de photo | 4-5 Go |
| Tous les bundles | ~24 Go |
yaml
deploy:
resources:
limits:
cpus: '4'
memory: 4GComplet (outils IA sur NVIDIA CUDA)
| Ressource | Exigence |
|---|---|
| CPU | 6-8 cœurs (la préparation vidéo + la concurrence s'exécutent sur CPU même avec l'IA sur GPU) |
| RAM | 8 Go |
| GPU | NVIDIA avec 8+ Go de VRAM (12 Go recommandé) |
| Disque | ~35 Go au total |
Un GPU NVIDIA (CUDA) accélère considérablement les modèles IA lourds. Mesuré sur une RTX 4070 par rapport à un CPU moderne :
| Outil IA | Accélération avec GPU | Notes |
|---|---|---|
| Agrandissement IA (RealESRGAN 2×) | ~47× | Le plus gros gain - moins d'une seconde contre ~33 s (plusieurs minutes sur les grandes images) |
| Amélioration des visages (CodeFormer) | ~12× | ~0,9 s contre ~11 s |
| Transcription (Whisper) | ~4,5× | |
| Suppression / remplacement / floutage d'arrière-plan | ~4× | ~7 s sur GPU contre ~29 s sur CPU |
| Coloriser | ~1,8× | |
| OCR, détection de visages, yeux rouges, suppression du bruit | ~1× | Déjà rapide sur CPU - un GPU n'apporte rien |
| Restauration de photo | aucune | Limité par le CPU même sur un GPU (0 % d'utilisation du GPU) ; un CPU rapide compte plus qu'un GPU ici |
Les outils qui valent un GPU sont l'agrandissement, l'amélioration des visages, la transcription et la suppression d'arrière-plan. La détection de visages, l'OCR et les yeux rouges sont limités par le CPU et déjà rapides, un GPU n'apporte donc rien.
L'utilisation de VRAM en pic atteint 7,5 Go pendant un agrandissement avec amélioration des visages. Un GPU NVIDIA de 6 Go convient pour la plupart des outils IA pris individuellement, mais échouera sur l'agrandissement. 8-12 Go de VRAM gèrent tout.
L'accélération par iGPU Intel/AMD via VA-API, Quick Sync ou OpenCL n'est pas prise en charge pour l'inférence IA aujourd'hui. Mapper /dev/dri dans le conteneur n'active pas l'accélération GPU de l'IA ; SnapOtter exécutera les outils IA sur CPU sauf si NVIDIA CUDA est disponible.
yaml
deploy:
resources:
limits:
cpus: '4'
memory: 8G
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]Utilisateurs simultanés
Requêtes de redimensionnement d'image parallèles sur le conteneur applicatif plafonné à 4 cœurs par défaut :
| Requêtes simultanées | Temps de réponse moyen | Erreurs |
|---|---|---|
| 1 | 0,4 s | 0 |
| 5 | 1,2 s | 0 |
| 10 | 2,1 s | 0 |
Le temps de réponse se dégrade de manière sous-linéaire sans erreur à mesure que le pool de workers sature. Augmenter la limite cpus: du conteneur applicatif (ou utiliser un hôte avec plus de cœurs) relève le plafond. Notez que les tâches lourdes (transcodage vidéo, IA sur CPU) mobilisent un worker pendant toute leur durée, dimensionnez donc le CPU selon votre nombre attendu de tâches lourdes simultanées, et pas seulement selon le nombre de requêtes.
Formats d'image pris en charge
SnapOtter prend en charge 55+ formats d'entrée et 14 formats de sortie, dont les fichiers RAW de 20+ marques d'appareils photo, les formats professionnels (PSD, EPS, OpenEXR, HDR), les codecs modernes (JPEG XL, AVIF, HEIC, QOI) et les formats scientifiques/de jeu (FITS, DDS).
Consultez la liste complète des formats pour les détails sur chaque format pris en charge, le décodeur utilisé et les contrôles de qualité disponibles.
Limitations connues
- Le redimensionnement sensible au contenu plante sur les grandes images (>5 MP) en raison d'une limitation du binaire caire. Fonctionne bien avec des images plus petites.
- Le décodage HEIF prend 13-23 secondes. HEIC (la variante d'Apple) est bien plus rapide, à 0,3-0,9 seconde.
- L'OCR japonais échoue sur CPU à cause d'un bug MKLDNN de PaddlePaddle. Fonctionne sur GPU.
- L'agrandissement expire sur CPU pour tout ce qui dépasse les petites images. GPU requis pour un usage pratique.
- L'amélioration des visages CodeFormer est nettement plus lente que GFPGAN (53 s contre 2 s sur GPU). GFPGAN est recommandé pour la plupart des cas d'usage.
Volumes
| Montage / Volume | Rôle | Requis ? |
|---|---|---|
/data (app) | Modèles IA, venv Python, fichiers utilisateur | Oui - perte de fichiers sans lui |
/tmp/workspace (app) | Fichiers de traitement temporaires (nettoyés automatiquement) | Recommandé |
SnapOtter-pgdata (postgres) | Répertoire de données PostgreSQL (utilisateurs, paramètres, pipelines, tâches) | Oui - perte de données sans lui |
SnapOtter-redisdata (redis) | Fichier append-only Redis pour des files de tâches durables | Recommandé |
Montages liés (bind mounts) vs volumes nommés
Volumes nommés (recommandés) - Docker gère les permissions automatiquement :
yaml
volumes:
- SnapOtter-data:/dataMontages liés - Vous gérez les permissions. Réglez PUID/PGID pour correspondre à votre utilisateur hôte :
yaml
volumes:
- ./SnapOtter-data:/data
environment:
- PUID=1000 # Your host UID (run: id -u)
- PGID=1000 # Your host GID (run: id -g)Permissions de stockage
SnapOtter écrit à deux emplacements à l'exécution : /data (fichiers utilisateur, journaux, modèles IA et le venv Python) et /tmp/workspace (espace de travail temporaire de traitement). Les deux doivent être accessibles en écriture par l'utilisateur sous lequel le conteneur s'exécute. Si l'un ne l'est pas, le conteneur échoue rapidement au démarrage avec un message nommant le répertoire, l'UID/GID en cours d'exécution et comment corriger, au lieu de démarrer « en bonne santé » puis d'échouer au premier téléversement avec une erreur cryptique.
La façon dont les permissions sont gérées dépend de la manière dont le conteneur est lancé :
Par défaut (démarre en root, redescend vers snapotter) - le point d'entrée démarre en root, corrige la propriété des volumes montés, puis redescend vers l'utilisateur non privilégié snapotter via gosu. Les volumes nommés fonctionnent sans aucune configuration. Pour les montages liés, réglez PUID/PGID sur votre utilisateur hôte (ci-dessus) afin que les fichiers qu'il écrit vous appartiennent.
Kubernetes / OpenShift (non-root via runAsUser) - lancé directement en tant qu'utilisateur non-root, le conteneur ne peut pas chown les volumes lui-même, l'orchestrateur doit donc les rendre accessibles en écriture. Réglez fsGroup :
yaml
securityContext:
runAsUser: 999
runAsGroup: 999
fsGroup: 999 # makes mounted volumes writable by the podLes répertoires accessibles en écriture de l'image appartiennent au groupe GID 0 et sont accessibles en écriture par le groupe, de sorte qu'un pod s'exécutant avec un UID arbitraire plus le groupe supplémentaire root (le défaut OpenShift) peut écrire sans chown.
TrueNAS Scale (et autres configurations à « UID étranger ») - TrueNAS exécute les applications sous un utilisateur non-root (souvent 568:568) et monte des jeux de données hôtes appartenant à un autre utilisateur, de sorte que ni le point d'entrée ni fsGroup ne les rendent accessibles en écriture par lui-même. Choisissez l'une des options :
Exécuter l'application en root (recommandé) - laissez l'utilisateur de l'application non défini ou réglez-le sur
0, et laissez le point d'entrée par défaut corriger les permissions et redescendre verssnapotter.Exécuter en tant qu'UID
999- réglez l'utilisateur/groupe de l'application sur999:999(l'utilisateur intégrésnapotterde SnapOtter) pour qu'il corresponde à la propriété de l'image.chownle jeu de données hôte vers l'UID sous lequel le conteneur s'exécute, depuis le shell TrueNAS :bash# Utilisez l'UID de l'erreur de démarrage (ou exécutez `id` dans le conteneur) chown -R 568:568 /mnt/<pool>/<dataset>
L'erreur de démarrage nomme l'UID exact à utiliser, le chemin le plus rapide est donc de démarrer l'application une fois, de lire le message, puis d'exécuter chown (ou d'ajuster l'utilisateur) en conséquence.
Variables d'environnement
| Variable | Défaut | Description |
|---|---|---|
AUTH_ENABLED | true | Activer/désactiver l'exigence de connexion |
DEFAULT_USERNAME | admin | Nom d'utilisateur admin initial |
DEFAULT_PASSWORD | admin | Mot de passe admin initial (changement forcé à la première connexion) |
MAX_UPLOAD_SIZE_MB | 100 | Limite de téléversement par fichier |
MAX_BATCH_SIZE | 100 | Nombre max de fichiers par requête de lot |
RATE_LIMIT_PER_MIN | 1000 | Requêtes API par minute et par IP (mettez 0 pour désactiver) |
MAX_USERS | 0 (illimité) | Nombre maximal de comptes utilisateur |
TRUST_PROXY | true | Faire confiance aux en-têtes X-Forwarded-For du reverse proxy |
PUID | 999 | Exécuter sous cet UID (pour les permissions de montage lié) |
PGID | 999 | Exécuter sous ce GID (pour les permissions de montage lié) |
LOG_LEVEL | info | Verbosité des journaux : fatal, error, warn, info, debug, trace |
CONCURRENT_JOBS | 0 (auto) | Nombre max de tâches de traitement IA en parallèle |
SESSION_DURATION_HOURS | 168 | Durée de vie de la session de connexion (7 jours) |
CORS_ORIGIN | (vide) | Origines autorisées séparées par des virgules, ou vide pour même origine |
Vérification d'état (health check)
Le conteneur inclut une vérification d'état intégrée :
bash
# Check container health status
docker inspect --format='{{.State.Health.Status}}' SnapOtter
# Manual health check
curl http://localhost:1349/api/v1/health
# {"status":"healthy","version":"x.y.z"}Reverse proxy
SnapOtter définit TRUST_PROXY=true par défaut afin que la limitation de débit et la journalisation utilisent l'IP client réelle issue des en-têtes X-Forwarded-For.
Nginx
nginx
server {
listen 80;
server_name images.example.com;
# Match MAX_UPLOAD_SIZE_MB (0 = nginx default 1M, so set high for unlimited)
client_max_body_size 500M;
location / {
proxy_pass http://localhost:1349;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# SSE support (batch progress, feature install progress)
proxy_buffering off;
proxy_read_timeout 300s;
}
}Nginx Proxy Manager
- Ajoutez un nouveau Proxy Host
- Réglez Domain Name sur votre domaine
- Réglez Scheme sur
http, Forward Hostname surSnapOtter(ou l'IP de votre conteneur), Forward Port sur1349 - Activez la prise en charge WebSocket
- Sous Advanced, ajoutez :
client_max_body_size 500M;etproxy_buffering off;
Traefik
yaml
# Add these labels to the SnapOtter service in docker-compose.yml
labels:
- "traefik.enable=true"
- "traefik.http.routers.snapotter.rule=Host(`images.example.com`)"
- "traefik.http.routers.snapotter.entrypoints=websecure"
- "traefik.http.routers.snapotter.tls.certresolver=letsencrypt"
- "traefik.http.services.snapotter.loadbalancer.server.port=1349"
# Increase upload limit (default 2MB is too low)
- "traefik.http.middlewares.snapotter-body.buffering.maxRequestBodyBytes=524288000"
- "traefik.http.routers.snapotter.middlewares=snapotter-body"Caddy
txt
images.example.com {
reverse_proxy localhost:1349 {
flush_interval -1
transport http {
read_timeout 300s
write_timeout 300s
}
}
}flush_interval -1 désactive la mise en tampon des réponses, ce qui est requis pour les événements de progression SSE (traitement par lots, outils IA, installations de fonctionnalités). Les délais d'expiration étendus permettent aux gros téléversements de fichiers de se terminer sans que Caddy ne ferme la connexion trop tôt.
Cloudflare Tunnels
bash
cloudflared tunnel --url http://localhost:1349Remarque : Cloudflare impose une limite de téléversement de 100 Mo sur les offres gratuites. Réglez MAX_UPLOAD_SIZE_MB=100 en conséquence.
CI/CD
Le dépôt GitHub comporte trois workflows :
- ci.yml - S'exécute automatiquement à chaque push et PR. Effectue le lint, la vérification de types, les tests, la construction et la validation de l'image Docker (sans push).
- release.yml - Déclenché manuellement via
workflow_dispatch. Exécute semantic-release pour créer un tag de version et une release GitHub, puis construit une image Docker multi-architecture (amd64 + arm64) et la pousse vers Docker Hub (snapotter/snapotter) et GitHub Container Registry (ghcr.io/snapotter-hq/snapotter). - deploy-docs.yml - Construit ce site de documentation et le déploie sur Cloudflare Pages lors d'un push vers
main.
Pour créer une release, allez dans Actions > Release > Run workflow dans l'interface GitHub, ou exécutez :
bash
gh workflow run release.ymlSemantic-release détermine la version à partir de l'historique des commits. Le tag Docker latest pointe toujours vers la release la plus récente.
Analytique
SnapOtter inclut une analytique produit anonyme (schémas d'utilisation des outils, rapports d'erreurs) pour aider à détecter les bugs et améliorer les fonctionnalités. Elle est activée par défaut. Vos fichiers, leurs noms et vos données personnelles n'en font jamais partie. SnapOtter fonctionne normalement avec l'analytique désactivée.
Désactiver l'analytique
Le retrait à l'exécution est un basculement admin en un clic. Ouvrez Settings > System > Privacy et désactivez Anonymous Product Analytics. Cela s'arrête immédiatement pour toute l'instance, sans reconstruction requise.
Pour une image qui ne peut jamais émettre d'analytique, définissez l'arrêt matériel au moment de la construction en clonant le dépôt et en le reconstruisant :
bash
git clone https://github.com/snapotter-hq/SnapOtter.git
cd SnapOtter
docker compose -f docker/docker-compose.yml build --build-arg SNAPOTTER_ANALYTICS=off
docker compose -f docker/docker-compose.yml up -dOu ajoutez l'argument de construction à votre docker-compose.yml existant :
yaml
services:
snapotter:
build:
context: .
dockerfile: docker/Dockerfile
args:
SNAPOTTER_ANALYTICS: "off"