Partie 2 sur 7 — Supabase en auto-hébergement : retour d'expérience
Version française de Part 2 — The server.
Ce billet couvre la création du serveur, sa sécurisation et l'installation correcte de Docker. Rien de compliqué en soi, mais il y a quelques endroits où le choix évident est le mauvais.
Créer le serveur
Rendez-vous sur hetzner.com, créez un compte, puis allez dans Cloud > New Server.
Choisissez Ubuntu 24.04 LTS sur une CX22 (2 vCPU, 4 Go de RAM). Sélectionnez un datacenter en Europe si c'est un critère pour vous. Ajoutez votre clé SSH publique pendant la configuration. N'utilisez pas de mot de passe root.
Cliquez sur Create. En une trentaine de secondes, le serveur est prêt. Notez l'adresse IP, que nous appellerons YOUR_VPS_IP tout au long de la série.
Première connexion
ssh root@YOUR_VPS_IP
Mettez le système à jour avant de faire quoi que ce soit d'autre :
apt update && apt upgrade -y
Définissez un nom d'hôte :
hostnamectl set-hostname supabase-vps
Pare-feu
Ubuntu est livré avec ufw. Configurez-le avant de l'activer, et dans cet ordre précis :
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
Vérifiez le résultat :
ufw status
Seuls les ports 22, 80 et 443 doivent être ouverts.
Un point important à connaître sur Docker et ufw : Docker écrit des règles iptables directement, en contournant ufw entièrement. Conséquence : si vous publiez un port dans un fichier Docker Compose avec ports:, ce port sera accessible depuis internet même si ufw ne l'autorise pas. C'est pourquoi nous n'utiliserons jamais ports: pour le service de base de données. Le pare-feu est la porte extérieure ; les ports de base de données n'y ont pas leur place.
Durcissement SSH
nano /etc/ssh/sshd_config
Configurez ces paramètres :
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
prohibit-password autorise la connexion root mais uniquement par clé, jamais par mot de passe. Comme nous avons ajouté notre clé à la création du serveur, c'est parfaitement adapté.
Redémarrez SSH :
systemctl restart ssh
Avant de fermer votre session actuelle, ouvrez une nouvelle fenêtre de terminal et vérifiez que vous pouvez encore vous connecter. Testez toujours les modifications SSH avec une session parallèle. En cas de blocage, Hetzner propose une console de secours dans l'interface web, mais il est bien plus confortable de ne pas en avoir besoin.
fail2ban
fail2ban lit les journaux d'authentification et bannit les adresses IP qui échouent trop souvent. Les paramètres par défaut nous conviennent :
apt install fail2ban -y
systemctl enable fail2ban
systemctl start fail2ban
Aucune modification de fichier de configuration n'est nécessaire. Le jail SSH est actif par défaut.
Avec la configuration par défaut, cinq tentatives SSH échouées depuis une même adresse IP déclenchent un bannissement d'une heure. Les scanners automatisés qui cherchent des mots de passe faibles cessent immédiatement de progresser.
Installation de Docker
C'est ici que le choix évident est le mauvais.
Le gestionnaire de paquets d'Ubuntu propose un paquet Docker. Il est obsolète. Il existe aussi un paquet Docker en Snap. Ce dernier présente des problèmes connus de permissions de fichiers, de chemins de volumes et de comportement au redémarrage des services en environnement de production. N'utilisez ni l'un ni l'autre.
Installez Docker depuis le dépôt apt officiel de Docker :
apt remove docker docker-engine docker.io containerd runc 2>/dev/null
apt install -y ca-certificates curl gnupg lsb-release
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Vérifiez l'installation :
docker --version
# Docker version 29.x.x, build ...
Le numéro de version est important. Nous avons besoin d'un Docker Engine récent pour que Traefik v3 fonctionne correctement. J'ai découvert ce problème à mes dépens après y avoir perdu un après-midi entier. C'est expliqué dans le billet suivant.
Docker Swarm
Nous utilisons Docker Swarm plutôt que docker compose seul. Sur une machine unique, cela peut sembler superflu, mais Swarm nous apporte des limites de ressources par service (indispensable quand on fait tourner 17 conteneurs sur 4 Go de RAM) et le redémarrage automatique en cas de défaillance d'un conteneur.
Initialisez-le :
docker swarm init
Le serveur est maintenant un manager Swarm à nœud unique. La configuration s'arrête là.
Cloner le dépôt
Toute la configuration vit dans un dépôt git. Créez un dépôt privé sur GitHub, puis clonez-le sur le VPS :
cd /root
git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git supabase-vps-cluster
cd supabase-vps-cluster
Le dépôt est vide à ce stade. Vous ajouterez les fichiers Compose et les scripts dans les billets suivants. L'essentiel, c'est que le répertoire est en place et que la connexion git est établie.
Garder la configuration dans git signifie qu'on peut déployer des changements en poussant vers le dépôt et en tirant sur le serveur, examiner les diffs avant de les appliquer, et revenir en arrière si quelque chose casse.
La structure que nous construisons :
supabase-vps-cluster/
├── instances/
│ ├── project1/
│ │ └── docker-compose.yml
│ └── project2/
│ └── docker-compose.yml
├── traefik/
│ └── docker-compose.yml
└── scripts/
Les secrets (les fichiers .env, la configuration de Kong) ne sont jamais committés dans git. Ils sont générés sur le serveur à partir de Vault, que nous configurons dans le billet 5.
Où en sommes-nous
Le serveur tourne, sécurisé derrière trois ports, avec une authentification SSH par clé uniquement et une protection contre les attaques par force brute. Docker CE est installé depuis la source officielle et Swarm est initialisé.
Dans le billet suivant, nous installons Traefik et mettons en place HTTPS pour chaque sous-domaine.
La série complète
- Pourquoi auto-héberger
- Le serveur, vous êtes ici
- Traefik et SSL
- La première instance Supabase
- Vault
- Deux instances
- Sécurité et test de charge
Top comments (0)