DEV Community

Dinh Doan Van Bien
Dinh Doan Van Bien

Posted on

Partie 2 — Le serveur

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
Enter fullscreen mode Exit fullscreen mode

Mettez le système à jour avant de faire quoi que ce soit d'autre :

apt update && apt upgrade -y
Enter fullscreen mode Exit fullscreen mode

Définissez un nom d'hôte :

hostnamectl set-hostname supabase-vps
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

⚠️ Autorisez SSH en premier. Activer ufw avant d'ouvrir le port 22 vous coupe immédiatement l'accès. Ça paraît évident jusqu'au moment où ça arrive.

Vérifiez le résultat :

ufw status
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Configurez ces paramètres :

PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Vérifiez l'installation :

docker --version
# Docker version 29.x.x, build ...
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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/
Enter fullscreen mode Exit fullscreen mode

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.

Partie 3 — Traefik et HTTPS →


La série complète

  1. Pourquoi auto-héberger
  2. Le serveur, vous êtes ici
  3. Traefik et SSL
  4. La première instance Supabase
  5. Vault
  6. Deux instances
  7. Sécurité et test de charge

Top comments (0)