GoPhish avec Docker Compose : déploiement complet
Déployer GoPhish via Docker Compose avec Nginx Proxy Manager, certificats SSL Let's Encrypt et hardening. Tutoriel complet 2026.
GoPhish s’installe en quelques minutes via un binaire statique, et c’est précisément la méthode que la documentation officielle met en avant. Pourtant, sur un serveur de production qui doit survivre à plusieurs mois de campagnes, de redémarrages et de mises à jour, le binaire posé sur un systemd unit montre rapidement ses limites. Docker Compose offre une alternative plus reproductible : un seul fichier décrit la stack complète, un seul docker compose up -d la déploie sur n’importe quel hôte. Les rebuilds, les rollbacks et la migration entre serveurs deviennent triviaux.
Ce guide couvre le déploiement complet d’une stack GoPhish + Nginx Proxy Manager via Docker Compose, avec certificats Let’s Encrypt, hardening de l’hôte et sauvegardes. Il prolonge le tutoriel d’installation GoPhish sur VPS écrit en parallèle, qui détaille la méthode binaire avec systemd. Choisissez Docker si vous voulez de la portabilité, le binaire si vous voulez le strict minimum.
Une précision avant de commencer : un container compromis reste un container, mais le serveur hôte, lui, reste exposé. Docker n’est pas une frontière de sécurité aussi étanche qu’une machine virtuelle. Un déploiement GoPhish accessible publiquement doit être traité comme une cible — ce que des attaquants ne manqueront pas de faire si vous laissez le panel d’administration sur Internet. Et bien sûr, cette stack ne s’utilise que sur des organisations qui ont explicitement autorisé le test. Pour la critique large de GoPhish en tant que socle de programme de sensibilisation, voir GoPhish en entreprise : pourquoi ça ne suffit pas.
Architecture cible
La stack se compose de deux containers connectés sur un réseau Docker bridge isolé.
Internet
│
▼
┌──────────────────────┐
│ VPS (hôte Docker) │
│ │
│ ┌────────────────┐ │
│ │ nginx-proxy- │ │ ports 80/443 publics
│ │ manager │ │ port 81 admin (interne)
│ │ (jc21/npm) │ │
│ └───────┬────────┘ │
│ │ phish-net │
│ ▼ │
│ ┌────────────────┐ │
│ │ gophish │ │ 3333 admin (interne)
│ │ (gophish/gophish)│ │ 80 phish (interne)
│ │ + volume db │ │
│ └────────────────┘ │
│ │
└──────────────────────┘
NPM expose les ports 80 et 443 publiquement et termine TLS via Let’s Encrypt. Les certificats sont demandés par challenge HTTP-01, donc le port 80 doit rester accessible depuis Internet pour le renouvellement. Le port 81 (interface d’administration NPM) reste accessible uniquement via tunnel SSH.
GoPhish tourne avec deux écoutes : 3333 pour le panel d’administration, 80 (interne au container) pour le serveur de phishing qui sert les landing pages et collecte les clics. Aucun de ces ports n’est exposé directement sur l’hôte. Tout passe par NPM.
La persistance de la base SQLite GoPhish est assurée par un volume bind sur ./gophish-data. Pour une production sérieuse, l’étape 5 décrit le passage à MySQL dans un troisième container.
Prérequis
- Un VPS Ubuntu 22.04 LTS ou Debian 12 avec 2 vCPU, 4 Go de RAM et 30 Go de SSD (Hetzner CX22, Scaleway DEV1-M ou OVH VPS Comfort 2 conviennent).
- Docker Engine 24 ou plus et Docker Compose v2 (plugin officiel, pas
docker-composeen Python qui est obsolète). - Un domaine, par exemple
example.com, avec deux sous-domaines pointant vers l’IP publique du VPS :admin.example.compour le panel etphish.example.compour les emails de simulation. En production réelle, le domaine de phishing doit être distinct du domaine d’administration et idéalement non lié de manière visible à votre organisation cible. - Les ports 80 et 443 ouverts en entrée sur le pare-feu du fournisseur cloud. Le port 3333 doit rester fermé en externe (vérifiez-le explicitement, certains fournisseurs ouvrent tout par défaut).
- Un accès SSH avec clé publique (mot de passe SSH désactivé). Si ce n’est pas encore le cas, c’est le premier hardening à faire.
Étape 1 — Installer Docker sur Ubuntu 22.04 ou Debian 12
La méthode officielle Docker passe par le script get-docker.sh (documentation Docker). Il installe Docker Engine et le plugin Compose v2 en une commande, sur Ubuntu, Debian, Fedora et CentOS.
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
Le script ajoute le dépôt APT officiel Docker, installe docker-ce, docker-ce-cli, containerd.io et le plugin docker-compose-plugin. À l’issue, l’agent dockerd tourne et démarre automatiquement au boot.
Pour exécuter les commandes Docker sans sudo, ajoutez votre utilisateur au groupe docker :
sudo usermod -aG docker $USER
newgrp docker
Attention au compromis de sécurité : appartenir au groupe docker équivaut à un accès root sur l’hôte. Un utilisateur de ce groupe peut monter / dans un container et écrire n’importe où. Sur un VPS multi-utilisateurs, n’ajoutez que les comptes d’administration. Sur un VPS dédié à GoPhish, c’est acceptable mais documentez-le.
Vérifiez les versions installées :
docker version
docker compose version
À mai 2026, vous devez voir Docker Engine 28.x et Docker Compose v2.40+. Si docker compose version renvoie une erreur de sous-commande, le plugin n’est pas installé : sudo apt install docker-compose-plugin complète l’installation.
Étape 2 — Le docker-compose.yml de base
Créez un répertoire de travail et le fichier compose :
mkdir -p /opt/gophish-stack
cd /opt/gophish-stack
Voici un fichier docker-compose.yml complet et fonctionnel.
services:
gophish:
image: gophish/gophish:latest
container_name: gophish
restart: unless-stopped
environment:
- ADMIN_USE_TLS=true
- ADMIN_TRUSTED_ORIGINS=https://admin.example.com
volumes:
- ./gophish-data:/opt/gophish/db
networks:
- phish-net
mem_limit: 1g
cpus: 1.0
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
container_name: npm
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "127.0.0.1:81:81"
volumes:
- ./npm-data:/data
- ./npm-letsencrypt:/etc/letsencrypt
networks:
- phish-net
mem_limit: 512m
cpus: 0.5
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
networks:
phish-net:
driver: bridge
Quelques éléments méritent d’être justifiés.
L’image gophish/gophish:latest est l’image officielle publiée par les mainteneurs du projet sur Docker Hub. Elle est construite à partir du Dockerfile du dépôt GitHub. À mai 2026, elle embarque la version 0.12.1.
Les variables ADMIN_USE_TLS et ADMIN_TRUSTED_ORIGINS sont nécessaires depuis GoPhish 0.12.1, qui a introduit le contrôle d’origine sur les requêtes du panel d’administration (release notes GoPhish 0.12.1). Sans ces variables, le panel placé derrière un reverse proxy qui termine TLS renvoie soit une erreur d’origine, soit redirige vers localhost. C’est l’erreur la plus fréquente sur les déploiements Docker — elle revient sur Stack Overflow et dans les issues GitHub à chaque nouvelle version.
Le volume ./gophish-data:/opt/gophish/db persiste la base SQLite et l’historique des campagnes hors du container. Sans cela, un docker compose down détruirait toutes les données.
NPM expose son interface d’administration sur le port 81, mais uniquement sur l’interface de loopback 127.0.0.1. Personne ne peut s’y connecter depuis Internet. Pour y accéder, on passe par un tunnel SSH :
ssh -L 8081:127.0.0.1:81 utilisateur@vps.example.com
Puis on ouvre http://localhost:8081 dans son navigateur local. C’est moins commode que d’exposer directement, mais ça évite que le panneau d’administration de votre reverse proxy se retrouve sur Internet — où il sera scanné dans les 24 heures suivant l’ouverture.
Les mem_limit et cpus plafonnent la consommation des containers. Sans cela, un bug ou une attaque pourrait saturer la machine.
Étape 3 — Premier démarrage
Démarrez la stack :
docker compose up -d
Docker télécharge les deux images et crée le réseau phish-net. La première fois, comptez deux à trois minutes selon la bande passante.
Récupérez le mot de passe admin GoPhish, qui est randomisé au premier lancement et affiché dans les logs :
docker compose logs gophish 2>&1 | grep "Please login"
La ligne ressemble à :
Please login with the username admin and the password XXXXXXXXXXXX
Notez le mot de passe immédiatement. Si vous redémarrez le container avant de l’avoir noté, vous devrez réinitialiser via le fichier gophish.db (ou recréer la stack en supprimant le volume).
Le panel GoPhish n’est pas encore accessible publiquement à cette étape, c’est normal — nous passons par NPM, qui n’est pas encore configuré. Pour valider que GoPhish tourne, faites un appel curl depuis l’hôte :
docker exec gophish wget -qO- --no-check-certificate https://localhost:3333 | head -20
Vous devez voir du HTML qui mentionne GoPhish.
Connectez-vous ensuite à NPM via le tunnel SSH ouvert plus haut, à l’URL http://localhost:8081. Le compte par défaut est admin@example.com / changeme. Changez-le immédiatement avec une adresse email valide (utile pour les notifications de renouvellement Let’s Encrypt) et un mot de passe long. C’est non-négociable : le compte par défaut NPM est documenté publiquement, des bots scannent les exposés.
Étape 4 — Configurer NPM comme reverse proxy SSL
Dans l’interface NPM, ouvrez Hosts → Proxy Hosts → Add Proxy Host.
Proxy Host pour le panel admin
Onglet Details :
- Domain Names :
admin.example.com - Scheme :
http - Forward Hostname / IP :
gophish - Forward Port :
3333 - Cochez Block Common Exploits
- Cochez Websockets Support
Le hostname gophish fonctionne parce que les deux containers sont sur le même réseau Docker phish-net. NPM résout gophish via le DNS interne Docker.
Onglet SSL :
- SSL Certificate :
Request a new SSL Certificate - Cochez Force SSL et HTTP/2 Support
- Cochez HSTS Enabled (mise en cache de la consigne HTTPS côté navigateur)
- Email Address for Let’s Encrypt : votre email
- Cochez l’acceptation des Terms of Service Let’s Encrypt
- Cliquez Save
NPM lance la validation HTTP-01 : Let’s Encrypt envoie une requête sur http://admin.example.com/.well-known/acme-challenge/... qui doit être servie par NPM. Si votre DNS est correctement configuré et que le port 80 est ouvert, le certificat est émis en 10 à 30 secondes.
Onglet Access List : créez une Access List (menu Access Lists) avec soit une allowlist d’IP (l’IP publique de votre bureau), soit un Basic Auth avec un compte/mot de passe. Associez-la au proxy host. C’est une seconde barrière en plus de l’authentification GoPhish elle-même : si une CVE est publiée sur GoPhish, votre panel reste protégé par cette couche externe.
Proxy Host pour le serveur de phishing
Add Proxy Host :
- Domain Names :
phish.example.com - Scheme :
http - Forward Hostname / IP :
gophish - Forward Port :
80 - Cochez Block Common Exploits
SSL : même procédure que ci-dessus, demandez un certificat Let’s Encrypt et forcez HTTPS.
N’activez pas d’Access List sur ce proxy host — les cibles de vos campagnes doivent pouvoir y accéder librement, sinon les liens cliqués retourneront une 401.
Rappel sur les variables GoPhish
Vérifiez que ADMIN_TRUSTED_ORIGINS dans le docker-compose.yml correspond bien à https://admin.example.com (le domaine que vous venez de configurer). Si vous changez de domaine, modifiez la variable, puis relancez :
docker compose up -d gophish
Pas besoin de docker compose down, le up -d recrée uniquement le service modifié.
Étape 5 — Passer à MySQL (optionnel mais recommandé en prod)
SQLite verrouille la base entière à chaque écriture. Sur des campagnes de plus de 5 000 destinataires lancées en parallèle, vous verrez apparaître des timeouts sur le tableau de bord. Surtout, sauvegarder le fichier SQLite à chaud (sans arrêter GoPhish) peut produire un snapshot incohérent. Avec MySQL, le mysqldump --single-transaction règle ce problème.
Ajoutez un service db au compose :
db:
image: mysql:8
container_name: gophish-db
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=changeme-root-pwd
- MYSQL_DATABASE=gophish
- MYSQL_USER=gophish
- MYSQL_PASSWORD=changeme-app-pwd
volumes:
- ./mysql-data:/var/lib/mysql
networks:
- phish-net
mem_limit: 1g
cpus: 1.0
command: --default-authentication-plugin=mysql_native_password
Et modifiez le service gophish pour pointer vers ce service. GoPhish lit ces paramètres depuis son fichier de configuration JSON (cf. documentation GoPhish). La version Docker accepte de surcharger via les variables d’environnement suivantes :
environment:
- ADMIN_USE_TLS=true
- ADMIN_TRUSTED_ORIGINS=https://admin.example.com
- DB_NAME=mysql
- DB_HOST=db:3306
- DB_USER=gophish
- DB_PASSWORD=changeme-app-pwd
- DB_DATABASE=gophish
depends_on:
- db
Le depends_on évite que GoPhish démarre avant que MySQL ait initialisé sa base.
Au premier démarrage de MySQL 8, le container met 20 à 40 secondes à provisionner la base. Si GoPhish démarre trop tôt, il échoue avec un connection refused puis retente. Si l’erreur persiste, le restart: unless-stopped finira par stabiliser la stack après une ou deux tentatives.
Sauvegarde quotidienne MySQL :
docker exec gophish-db mysqldump \
--single-transaction \
-u root -pchangeme-root-pwd \
gophish > /backups/gophish-$(date +%F).sql
À ajouter dans un cron quotidien. Conservez 30 jours de dumps.
Migration SQLite → MySQL : il n’y a pas d’outil officiel d’import. La méthode pragmatique consiste à exporter vos groupes d’utilisateurs en CSV depuis le panel SQLite, à archiver vos templates en JSON via l’API REST, puis à les réimporter dans l’instance MySQL fraîche. L’historique des campagnes anciennes peut être conservé sous forme d’export JSON archivé hors de la base.
Étape 6 — Hardening de l’hôte Docker
Le container est une bonne isolation logique, pas une frontière de sécurité absolue. La machine elle-même doit être protégée.
UFW : pare-feu hôte
sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP (Let''s Encrypt + redirect HTTPS)'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw enable
sudo ufw status verbose
Le port 81 (NPM admin) reste accessible uniquement via tunnel SSH grâce au binding 127.0.0.1:81 dans le compose. Le port 3333 (GoPhish admin) n’est pas exposé du tout sur l’hôte — il vit dans le réseau interne Docker.
Attention : Docker contourne UFW par défaut. Quand vous publiez un port avec ports: - "80:80", Docker insère une règle iptables qui rend le port accessible même si UFW est censé bloquer. C’est documenté et c’est un piège classique. Trois mitigations possibles : (1) ne publier que sur 127.0.0.1, (2) restreindre l’écoute Docker via iptables=false dans /etc/docker/daemon.json (et gérer le NAT à la main, fragile), (3) installer le paquet ufw-docker qui fournit des règles compatibles. Pour cette stack, la mitigation 1 (utilisée pour le port 81 ci-dessus) couvre le risque principal.
Watchtower : non, ou avec précaution
Watchtower met à jour automatiquement les images Docker dès qu’une nouvelle version est publiée. C’est tentant pour ne pas oublier les patches. Mais sur une stack GoPhish, une mise à jour silencieuse peut casser une campagne en cours (changement de schéma de base, changement de comportement d’une API).
La recommandation pragmatique : pas de Watchtower sur GoPhish lui-même. Activez-le seulement sur NPM, qui se met à jour de manière plus prévisible. Pour GoPhish, faites les mises à jour manuellement après chaque release officielle :
cd /opt/gophish-stack
docker compose pull gophish
docker compose up -d gophish
docker compose logs -f gophish
Si la nouvelle version casse quelque chose, pinnez la version précédente dans le compose (par exemple image: gophish/gophish:v0.12.1) et docker compose up -d gophish.
Rotation des logs Docker
Sans configuration explicite, Docker écrit ses logs dans /var/lib/docker/containers/<id>/<id>-json.log sans rotation. En quelques mois, un container bavard remplit le disque. La configuration logging dans le compose (déjà incluse plus haut) limite à 10 Mo × 5 fichiers par container, soit 50 Mo maximum.
Pour appliquer ces limites à tous les containers par défaut, éditez /etc/docker/daemon.json :
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "5"
}
}
Puis sudo systemctl restart docker. À noter que cela ne s’applique qu’aux nouveaux containers, pas aux existants.
Mises à jour de l’hôte
Activez unattended-upgrades pour les patches de sécurité de l’OS :
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
Sur Ubuntu, la configuration par défaut couvre les mises à jour de sécurité. Vérifiez /etc/apt/apt.conf.d/50unattended-upgrades et autorisez les redémarrages automatiques nocturnes si la stack peut absorber une interruption courte.
Fail2ban sur SSH
Si SSH écoute encore sur le port 22 public, installez fail2ban :
sudo apt install fail2ban
sudo systemctl enable --now fail2ban
La configuration par défaut bannit une IP après 5 échecs SSH sur 10 minutes.
Étape 7 — Sauvegardes et restauration
Une stack qui n’est pas sauvegardée n’est pas une stack de production. Deux niveaux complémentaires.
Niveau 1 : snapshot de l’hôte
OVH, Scaleway et Hetzner proposent tous des snapshots automatiques de VPS pour quelques euros par mois. Activez-les : un snapshot quotidien capturé sur 7 jours coûte moins de 5 euros par mois et constitue le filet de sécurité ultime en cas de corruption majeure ou d’erreur humaine grave (un rm -rf qui part en vrille).
Le snapshot capture l’intégralité du disque, donc l’état Docker, les volumes, le compose et le système. La restauration est de l’ordre de la minute. Le snapshot ne dispense pas du backup applicatif, parce qu’il est moins granulaire (vous ne pouvez pas restaurer seulement la base sans tout reposer).
Niveau 2 : backup applicatif quotidien
Script /opt/gophish-stack/backup.sh :
#!/bin/bash
set -euo pipefail
BACKUP_DIR="/var/backups/gophish"
DATE=$(date +%F-%H%M)
mkdir -p "$BACKUP_DIR"
cd /opt/gophish-stack
# Backup volumes (SQLite si pas de MySQL)
tar czf "$BACKUP_DIR/gophish-data-$DATE.tar.gz" gophish-data/
# Backup NPM (config + certificats)
tar czf "$BACKUP_DIR/npm-$DATE.tar.gz" npm-data/ npm-letsencrypt/
# Backup MySQL si présent
if docker compose ps db | grep -q running; then
docker compose exec -T db mysqldump \
--single-transaction \
-u root -p"${MYSQL_ROOT_PASSWORD}" \
gophish | gzip > "$BACKUP_DIR/gophish-db-$DATE.sql.gz"
fi
# Rétention : 30 jours
find "$BACKUP_DIR" -type f -mtime +30 -delete
Cron quotidien à 03h00 :
0 3 * * * /opt/gophish-stack/backup.sh >> /var/log/gophish-backup.log 2>&1
Et synchronisez le répertoire /var/backups/gophish vers un stockage hors-site (S3, Backblaze B2, ou même un VPS distinct) via rclone ou restic. Un backup local ne survit pas à une compromission de la machine.
Restauration
Le test de restauration est aussi important que la sauvegarde. Une fois par trimestre, sur une VM jetable :
cd /opt/gophish-test
git clone <repo-de-votre-compose>
tar xzf /var/backups/gophish/gophish-data-2026-05-09.tar.gz
docker compose up -d
Vérifiez que l’admin GoPhish se connecte et que les campagnes archivées sont visibles. Sans ce test, vous n’avez pas une sauvegarde, vous avez un fichier compressé sur lequel vous projetez de l’espoir.
Erreurs courantes et debug
Le login GoPhish redirige vers localhost après saisie du mot de passe. Cause quasi systématique : ADMIN_USE_TLS=true et ADMIN_TRUSTED_ORIGINS=https://admin.example.com non renseignés ou mal renseignés. Vérifiez la casse, le https:// (pas http) et l’absence de slash final. Relancez avec docker compose up -d gophish.
Certbot / Let’s Encrypt : Rate limit exceeded. Let’s Encrypt limite à 5 certificats identiques par domaine et par semaine (letsencrypt.org/docs/rate-limits). Si vous testez plusieurs configurations NPM en boucle, vous toucherez cette limite. Utilisez le serveur de staging Let’s Encrypt pendant les tests (option dans l’interface NPM, ou via STAGING_LETSENCRYPT=true selon la version). Les certificats de staging ne sont pas valides côté navigateur, mais ils permettent de vérifier la mécanique sans consommer le quota.
GoPhish n’envoie pas d’emails. Vérifiez d’abord le Sending Profile (Menu → Sending Profiles dans GoPhish) : test SMTP via le bouton “Send Test Email”. Si le test échoue, c’est un problème SMTP, pas un problème GoPhish. Les causes courantes : authentification refusée (mauvais mot de passe), TLS exigé alors que vous avez configuré du SMTP en clair, IP source bannie par le relais. Pour le suivi en temps réel des envois :
docker compose logs -f gophish
Container unhealthy ou redémarrage en boucle. Cherchez la cause dans les logs :
docker compose logs --tail=100 gophish
Sur GoPhish, la cause classique est un volume avec des permissions trop restrictives. Le container tourne avec un UID spécifique (souvent 1001) et doit pouvoir écrire dans /opt/gophish/db. Corrigez avec :
sudo chown -R 1001:1001 ./gophish-data
Le port 80 NPM répond 502 Bad Gateway. Le proxy host vers gophish:80 ne trouve pas le container. Vérifiez que les deux services sont bien sur le même réseau phish-net et que le service gophish tourne :
docker compose ps
docker network inspect gophish-stack_phish-net
Le nom du réseau préfixe le nom du répertoire de travail Docker Compose.
Délivrabilité catastrophique : tous les emails partent en spam. Ce sujet sort du périmètre de ce guide. Il combine la configuration DNS du domaine d’envoi (SPF, DKIM, DMARC), la réputation de l’IP du relais SMTP, le contenu de l’email et le profil d’envoi. Le guide GoPhish délivrabilité SPF DKIM DMARC couvre la procédure complète. Pour la base de la configuration DNS hors GoPhish, voir Configurer SPF, DKIM et DMARC.
Limites de cette approche
Cette stack couvre l’infrastructure, et seulement l’infrastructure. Une fois en place, vous avez un serveur GoPhish accessible derrière HTTPS, sauvegardé et raisonnablement durci. Vous n’avez pas encore : les templates en français adaptés à votre contexte, la configuration DNS et la chauffe du domaine d’envoi, les modules de formation post-clic, ni les rapports de conformité.
La création de templates HTML responsive testés sur Outlook, Gmail et Apple Mail prend une à deux heures par scénario. Vingt scénarios pour couvrir une année de campagnes représentent 30 à 40 heures de travail récurrent, parce qu’il faut renouveler tous les six mois (les collaborateurs qui ont vu un scénario le reconnaîtront la fois suivante). La délivrabilité demande une chauffe progressive du domaine sur quatre à six semaines, du monitoring des taux de bounce et de la veille permanente sur les changements de filtres côté Gmail et Microsoft.
La formation post-clic est totalement absente de GoPhish : la cible qui clique voit une page HTML statique sans aucun module pédagogique. Or c’est précisément ce module qui fait baisser le taux de clic sur les campagnes suivantes — sans lui, vous mesurez un état sans le traiter. La conformité NIS2 et RGPD demande des preuves de sensibilisation exportables et de la documentation que GoPhish ne génère pas. Vous extrairez ces données manuellement de l’API à chaque audit.
Pour la critique complète de GoPhish en tant que socle de programme de sensibilisation, voir GoPhish en entreprise : pourquoi ça ne suffit pas et le comparatif GoPhish vs solutions managées. Si l’opérationnel pèse plus que le contrôle total, l’alternative managée nophi.sh inclut templates en français, formation post-clic et rapports de conformité — voir tarifs et fonctionnalités. La référence communautaire PhishDock propose un compose plus complet, mais nous recommandons de partir du compose minimal documenté ici et de l’étendre selon vos besoins, plutôt que d’hériter d’une configuration que vous ne comprenez pas.
FAQ
Pourquoi mon login GoPhish échoue derrière un reverse proxy ?
Depuis la version 0.12.1, GoPhish vérifie l’origine HTTP des requêtes envoyées au panel d’administration. Quand le panel est placé derrière un reverse proxy qui termine TLS, l’origine vue par GoPhish ne correspond plus à l’URL publique. Il faut déclarer cette URL via la variable d’environnement ADMIN_TRUSTED_ORIGINS (par exemple ADMIN_TRUSTED_ORIGINS=https://admin.example.com) et activer ADMIN_USE_TLS=true. Sans ces deux variables, le POST du formulaire de login est rejeté en silence ou redirige vers localhost.
SQLite ou MySQL pour GoPhish en Docker ?
SQLite est le défaut, suffit pour des tests ponctuels et des petites organisations. Le fichier est posé dans /opt/gophish/db et se sauvegarde à froid sans difficulté. MySQL devient préférable quand vous lancez des campagnes en parallèle sur plusieurs milliers de destinataires, ou quand vous voulez des sauvegardes à chaud via mysqldump sans arrêter le service. Pour une PME de moins de 500 utilisateurs avec une campagne à la fois, SQLite reste un choix défendable.
Comment mettre à jour le container GoPhish proprement ?
Évitez Watchtower en production : une mise à jour silencieuse peut casser la configuration d’une campagne en cours. La procédure manuelle prend deux minutes. Faites d’abord une sauvegarde du volume gophish-data, puis exécutez docker compose pull gophish suivi de docker compose up -d gophish. Vérifiez les logs au démarrage et le tableau de bord. Si la nouvelle version casse quelque chose, revenez à l’image précédente avec docker compose down et un pin de version explicite dans le compose.
Puis-je héberger plusieurs instances GoPhish sur un même hôte ?
Oui, c’est même un cas d’usage courant pour les prestataires qui gèrent des campagnes pour plusieurs clients sur la même infrastructure. Dupliquez le service gophish dans le compose avec un autre nom (gophish-client-a, gophish-client-b), des volumes distincts et des ports internes différents. Le reverse proxy NPM route ensuite admin-a.example.com et admin-b.example.com vers les deux instances. Isolez chaque instance dans son propre réseau Docker pour éviter les fuites latérales.
Quelle taille de VPS pour 500 destinataires par campagne ?
Un VPS 2 vCPU / 4 Go RAM / 30 Go SSD absorbe sans problème des campagnes de 500 à 2 000 destinataires avec SQLite, en supposant un envoi étalé sur 30 à 60 minutes. Le goulot d’étranglement n’est pas GoPhish mais le SMTP en sortie : si vous envoyez via un relais externe (SES, Mailgun, Sendgrid), la machine reste calme. Si vous montez un Postfix local, comptez 8 Go de RAM pour absorber les pics de file d’attente et la résolution DNS inverse.
Faut-il exposer le port admin (3333) en externe ?
Non. Le port 3333 ne doit jamais être ouvert sur l’IP publique. Le bon pattern est de lier l’admin uniquement au réseau Docker interne (pas de section ports: dans le compose pour ce port) et d’y accéder via le reverse proxy sur admin.example.com avec HTTPS, une Access List NPM (Basic Auth ou allowlist IP) et idéalement un MFA en amont. Si vous avez vraiment besoin d’un accès direct pour un debug, passez par un tunnel SSH (ssh -L 3333:localhost:3333 utilisateur@vps) le temps de la session.
Comment gérer plusieurs domaines de phishing avec ce setup ?
Le service phish de GoPhish écoute sur un seul port (80 par défaut) et sert toutes les campagnes en se basant sur l’URL configurée dans le Sending Profile. Pour servir phish-banque.example.com et phish-rh.example.fr depuis le même container, ajoutez deux Proxy Hosts NPM qui pointent tous les deux vers gophish:80, chacun avec son certificat Let’s Encrypt. GoPhish identifie la campagne à partir du paramètre rid dans l’URL, pas à partir du nom d’hôte. Variez les domaines pour brouiller les analyses anti-phishing et améliorer la délivrabilité.