📍 Article principal du sujet : Incus 6 LTS — gérer conteneurs système et VMs Linux pour PME ouest-africaine
Pour une équipe de cinq développeurs qui partage un seul VPS, la gestion des environnements de travail tourne vite au cauchemar : chacun installe ses dépendances, modifie le PHP, casse le Node de l’autre, et personne n’ose plus toucher la machine de peur de bloquer le collègue. La solution moderne est de donner à chaque développeur un conteneur Incus personnel, isolé, avec ses propres versions d’outils, et de gérer les bascules de version par snapshots. Sur un Hostinger Cloud VPS 8 Go RAM, cinq environnements complets (Node, PHP, Python, Docker) cohabitent sereinement, à un coût d’infrastructure mensuel inférieur à celui d’une machine de développement physique.
Ce tutoriel monte le pattern complet : profil dev, conteneurs nommés par utilisateur, accès SSH par clé publique, snapshots de référence, restauration à un état antérieur en une commande, et automatisation via un script onboard-dev.sh qui crée l’environnement complet d’un nouveau développeur en moins d’une minute.
Pourquoi un conteneur par développeur plutôt qu’un Docker Compose partagé
Un Docker Compose partagé fonctionne tant qu’il y a un seul développeur. Dès deux personnes, les conflits arrivent : versions PHP différentes selon les projets, configurations PostgreSQL incompatibles, ports qui se marchent dessus. La parade classique consiste à monter un Compose par projet et par développeur, ce qui multiplie les conteneurs à orchestrer (souvent six à huit par projet) et complique la sauvegarde individuelle.
Un conteneur Incus système par développeur retourne le problème : une seule instance Linux complète par dev, qui contient ses outils, ses projets, ses bases de données, ses serveurs locaux. Le dev SSH dans son conteneur, travaille comme dans une VM, mais à un coût bien moindre. Quand il veut tester une nouvelle version de Node, il incus snapshot create, fait son test, et restaure si ça casse. Quand il quitte l’équipe, on supprime son conteneur — propre, sans résidu.
Prérequis
- VPS Linux 64 bits, 8 Go RAM minimum, 100 Go SSD
- Incus 6 LTS opérationnel — voir Installer Incus avec Zabbly
- Pool de stockage ZFS pour des snapshots instantanés et la déduplication
- SSH système configuré sur l’hôte (pour l’accès admin)
- Niveau attendu : Linux confortable, SSH par clé publique
- Temps estimé : 60 minutes pour le setup initial, 10 minutes par développeur ajouté ensuite
Pour ce scénario, Hostinger Cloud VPS 8 Go RAM tient confortablement cinq développeurs avec environnements complets. Pour un effectif au-delà de huit, on bascule sur 16 Go RAM ou on monte un cluster Incus à deux VPS pour répartir la charge.
Étape 1 — Profil dev avec ressources adaptées
incus profile create dev
incus profile edit dev
config:
limits.cpu.allowance: 100%
limits.memory: 1.5GB
limits.processes: 800
security.idmap.isolated: true
security.nesting: true
description: Environnement de développement par developpeur
devices:
eth0:
name: eth0
network: incusbr0
type: nic
root:
path: /
pool: default
size: 25GB
type: disk
name: dev
used_by: []
Quelques choix méritent explication. security.nesting: true autorise l’utilisation de Docker à l’intérieur du conteneur — utile pour les développeurs qui testent des images Docker localement. 1,5 Go RAM est un compromis : confortable pour un IDE distant, un compilateur, un node_modules, mais frugal pour cinq dev en parallèle sur 8 Go d’hôte. 25 Go disque couvre largement les besoins courants ; ZFS compresse à 60 % la taille effective des projets typiques, donc l’occupation réelle reste autour de 8-10 Go par développeur.
Étape 2 — Image modèle dev-template
On prépare une fois une image avec tous les outils que l’équipe utilise, puis chaque développeur reçoit un clone instantané de cette image. La logique est identique à celle de la CI/CD éphémère, mais ici on garde le conteneur dans la durée.
incus launch images:debian/12 dev-template -p dev
incus shell dev-template
apt update && apt upgrade -y
apt install -y curl wget git unzip build-essential ca-certificates gnupg \
vim nano tmux htop tree jq ripgrep fd-find bat
# Node.js 20 LTS
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs
# Python 3 + outils
apt install -y python3 python3-pip python3-venv pipx
# Docker (utilisable grâce à security.nesting)
curl -fsSL https://get.docker.com | sh
# pnpm pour les projets JS modernes
npm install -g pnpm
exit
incus stop dev-template
incus publish dev-template --alias dev-template-debian12
incus delete dev-template
L’image fait environ 2 Go après installation, mais grâce au copy-on-write ZFS, chaque clone n’occupe que la divergence — les cinq premières instances utilisent à peine 2,5 Go d’espace total au lieu de 10 Go en stockage naïf.
Étape 3 — Script d’onboarding développeur
Le script qui crée un environnement complet pour un nouveau dev :
cat <<'EOF' > /usr/local/bin/onboard-dev
#!/usr/bin/env bash
set -eo pipefail
DEV_NAME=${1:?"Usage: onboard-dev "}
PUBKEY_FILE=${2:?"Usage: onboard-dev "}
INSTANCE="dev-${DEV_NAME}"
PORT_SSH=$((22000 + RANDOM % 1000))
# Créer le conteneur depuis l'image template
incus launch local:dev-template-debian12 "${INSTANCE}" -p dev
# Attendre démarrage et IP
sleep 5
incus exec "${INSTANCE}" -- bash -c "
apt install -y openssh-server
systemctl enable --now ssh
useradd -m -s /bin/bash -G sudo ${DEV_NAME}
echo '${DEV_NAME} ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/${DEV_NAME}
mkdir -p /home/${DEV_NAME}/.ssh
chmod 700 /home/${DEV_NAME}/.ssh
"
incus file push ${PUBKEY_FILE} "${INSTANCE}/home/${DEV_NAME}/.ssh/authorized_keys"
incus exec "${INSTANCE}" -- chown -R ${DEV_NAME}:${DEV_NAME} /home/${DEV_NAME}/.ssh
incus exec "${INSTANCE}" -- chmod 600 /home/${DEV_NAME}/.ssh/authorized_keys
# Forwarder le port SSH de l'hôte vers le conteneur
incus config device add "${INSTANCE}" ssh proxy \
listen=tcp:0.0.0.0:${PORT_SSH} connect=tcp:127.0.0.1:22
echo "Dev ${DEV_NAME} provisionné."
echo "Connexion : ssh ${DEV_NAME}@vps.example.org -p ${PORT_SSH}"
EOF
chmod +x /usr/local/bin/onboard-dev
Avec ce script, ajouter un développeur tient en une commande : onboard-dev fatou /tmp/fatou-pubkey.pub. Trente secondes plus tard, Fatou a son environnement personnel, son shell, ses droits sudo dedans (mais limités à son conteneur — pas accès à l’hôte ni aux conteneurs des autres), et un port SSH dédié.
Étape 4 — Accès au quotidien pour les développeurs
Côté développeur, la connexion ressemble à un SSH classique vers un VPS personnel. Pour l’IDE, VS Code Remote SSH ou JetBrains Gateway se branchent dessus comme sur n’importe quelle machine distante.
# Côté développeur, dans ~/.ssh/config :
Host dev-fatou
HostName vps.example.org
User fatou
Port 22042
# Connexion
ssh dev-fatou
# Ou directement avec VS Code :
# code --remote ssh-remote+dev-fatou /home/fatou/projet
L’expérience est celle d’une machine virtuelle dédiée : Fatou peut faire git clone, pnpm install, lancer son npm run dev sur le port 3000 du conteneur, et y accéder via un tunnel SSH ou en exposant le port via Caddy si besoin.
Étape 5 — Snapshots avant manipulation à risque
L’argument différenciant majeur du conteneur Incus pour le dev : la possibilité de prendre un snapshot, tenter une opération hasardeuse (mise à jour majeure de Node, refactor lourd, test de migration BDD), et revenir à l’état précédent en deux secondes si ça plante.
# Côté admin sur l'hôte
incus snapshot create dev-fatou avant-upgrade-node
# Le développeur teste la migration node 18 → 20
# Si ça casse :
incus snapshot restore dev-fatou avant-upgrade-node
# Tout revient comme avant, fichiers, services, BDD locale, état des process
Le développeur peut aussi avoir le droit de prendre ses propres snapshots, en lui octroyant un jeton API restreint à son conteneur. C’est une commodité qui décharge l’admin tout en gardant l’isolation par dev.
Étape 6 — Sauvegardes communes équipe
Une fois par jour, on snapshot tous les environnements et on exporte vers un stockage distant. Pour cinq développeurs, ça prend quelques minutes, et l’archive complète permet à un nouveau venu de récupérer un environnement clé en main même si son conteneur a été supprimé par erreur.
cat <<'EOF' > /etc/cron.daily/incus-dev-backup
#!/usr/bin/env bash
set -eo pipefail
BACKUP_DIR=/var/backups/incus
mkdir -p ${BACKUP_DIR}
DATE=$(date +%Y%m%d)
for inst in $(incus list dev- -c n --format csv); do
incus snapshot create "${inst}" "daily-${DATE}" --reuse
incus export "${inst}" "${BACKUP_DIR}/${inst}-${DATE}.tar.gz" \
--snapshot="daily-${DATE}"
done
# Push vers stockage S3 distant
rclone copy ${BACKUP_DIR} bunny:backups-itskills/dev/
# Garder 7 jours localement
find ${BACKUP_DIR} -name '*.tar.gz' -mtime +7 -delete
EOF
chmod +x /etc/cron.daily/incus-dev-backup
Les archives quotidiennes pèsent 100 à 500 Mo par développeur (ZFS-compressé). Sur sept jours conservés, ça reste sous les 20 Go d’espace local + un téra-octet annuel chez Bunny — coût total de la sauvegarde équipe : environ 5 USD/mois.
Étape 7 — Limiter les ressources pour éviter le chaos
Sur un VPS partagé, un développeur qui lance par erreur un build qui consomme 16 Go de RAM peut bloquer toute l’équipe. Les limites sont là pour ça :
incus config set dev-fatou limits.memory 2GB
incus config set dev-fatou limits.cpu.allowance 100%
incus config set dev-fatou limits.processes 1000
Au-delà de la limite, le processus du développeur est tué proprement par l’OOM killer du conteneur, sans toucher aux autres conteneurs ni à l’hôte. Le dev voit le crash, comprend qu’il doit réviser son code, et l’équipe continue de bosser.
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| SSH refusé après onboarding | Mauvais format de clé publique ou permissions .ssh incorrectes | Vérifier cat ~/.ssh/authorized_keys et ls -la ~/.ssh dans le conteneur |
| VS Code Remote SSH se déconnecte fréquemment | Conteneur OOM tue le serveur Remote | Augmenter limits.memory à 2 ou 3 Go |
| Docker dans le conteneur ne démarre pas | security.nesting non activé | Vérifier le profil dev et redémarrer le conteneur |
| Disque saturé après quelques mois | Snapshots ZFS qui s’accumulent | zfs list -t snapshot et purger les anciens via sanoid |
| Performance dégradée à plusieurs simultanés | Pas de limites CPU, un dev sature | Mettre limits.cpu.allowance à 100% sur tous les profils |
Adaptation au contexte ouest-africain
Pour un bootcamp à Dakar qui forme 12 stagiaires sur trois mois, donner à chacun un conteneur Incus sur un VPS Hostinger 16 Go remplace l’achat de 12 ordinateurs portables ou la galère de configurer 12 environnements de dev locaux différents. Le formateur entre en SSH dans n’importe quel conteneur stagiaire pour aider, peut figer un état de référence et restaurer si un stagiaire casse tout, et garde un historique pédagogique propre.
Pour une agence avec télétravailleurs, le pattern résout aussi le problème des connexions résidentielles instables. L’IDE tourne côté serveur, les builds aussi, le poste local n’a besoin que d’une connexion SSH stable (qui consomme peu de bande passante). Quand internet coupe, le travail en cours reste sur le conteneur et reprend exactement où il était au reconnect.
Côté budget : un VPS 8 Go Hostinger à 13 USD/mois pour cinq développeurs revient à 2,60 USD par dev — bien moins qu’un abonnement GitHub Codespaces (10 USD/mois pour le premier tier). Pour une équipe de quinze sur 16 Go RAM, on tombe à 1 USD/dev/mois.
Tutoriels frères
- Auto-héberger Gitea avec runner CI — la forge interne complémentaire.
- Runners GitLab avec conteneurs Incus éphémères — pour les pipelines.
- Snapshots et restauration d’instance Incus — pour creuser le mécanisme.
Pour aller plus loin
- 🔝 Retour à l’article principal sur Incus
- VS Code Remote SSH (doc officielle)
- JetBrains Remote Development
- Pour pratiquer : Hostinger Cloud VPS 8/16 Go RAM
FAQ
Combien de développeurs sur un VPS 8 Go ?
Cinq à six confortablement, en activité standard (édition, build modéré, run local). Pour des charges plus intenses (compilation lourde de C++, ML local), prévoir 16 Go ou un cluster Incus à deux nœuds.
Le développeur peut-il installer ses propres outils ?
Oui, il a sudo dans son conteneur. Mais cette liberté reste cantonnée à son périmètre — pas d’impact sur les autres devs ni sur l’hôte.
Comment partager du code entre développeurs ?
Via la forge git (Gitea ou GitLab). Pas de partage de filesystem entre conteneurs — chaque dev clone le repo et travaille dessus en local dans son conteneur.
Pourquoi pas GitHub Codespaces ?
Codespaces démarre un conteneur Docker éphémère par session, qui s’arrête après 30 min d’inactivité. Le pattern Incus garde l’environnement vivant 24/7, ce qui change la nature de l’expérience pour qui aime ses tmux ouverts.
Les snapshots impactent-ils les performances ?
Sur ZFS et Btrfs : non, instantanés et sans copie. Sur dir-pool : à éviter, lent et coûteux en disque. ZFS reste l’option recommandée pour ce cas d’usage.