VPS pour Docker : critères techniques et ressources recommandées

Checklist technique et profils recommandés pour un VPS Docker-ready : cgroup2, CPU stable, IOPS NVMe, réseau (MTU/conntrack) et bonnes pratiques sécurité.

Ordinateurs avec des diagrammes de VPS et Docker.

Table des matières :

  1. VPS pour Docker : ce que “Docker-ready” implique côté kernel et virtualisation
  2. CPU : vCPU, fréquence, ISA, contention et “steal time”
  3. RAM : page cache, buffers MariaDB/Redis, OOM killer et limites cgroup
  4. Stockage : NVMe, IOPS réels, fsync, overlay2 et stratégie volumes/sauvegardes
  5. Réseau : latence, débit, IPv4/IPv6, MTU et reverse proxy propre
  6. Sécurité et isolation : rootless, AppArmor/SELinux, patching et secrets
  7. Profils de ressources recommandés (dev/staging/prod) + checklist de validation

VPS pour Docker : ce que “Docker-ready” implique côté kernel et virtualisation

Un VPS pour Docker n’est pas “un Linux avec SSH”. Docker s’appuie sur des primitives noyau (namespaces, cgroups, overlayfs) et sur une chaîne réseau (netfilter/iptables/nftables, bridge, veth). Sur certains VPS “containerisés” (LXC/OpenVZ historiques), vous avez un root qui n’est pas vraiment root : modules noyau non disponibles, restrictions sur iptables, impossibilité d’utiliser overlay2, ou cgroups partiels. Résultat : builds qui cassent, réseaux instables, et performance I/O imprévisible.

En pratique, privilégiez une virtualisation KVM (ou équivalent matériel) avec un noyau récent et complet. Vérifiez dès le jour 0 :

systemd-detect-virt
uname -r
stat -fc %T /sys/fs/cgroup   # attendu : cgroup2 (ou cgroup2fs selon la distribution)
grep overlay /proc/filesystems

Si cgroup2 n’est pas présent ou si overlay manque, vous allez vous battre contre le provider au lieu de livrer.

Complétez ce “smoke test” avec 3 contrôles souvent oubliés, mais très révélateurs sur un VPS censé être “Docker-ready” :

  • Cgroups réellement exploitables (pas seulement montés) :
  docker info | sed -n '1,120p' | grep -E 'Cgroup|Driver|Version'

Sur une stack moderne, vous cherchez typiquement Cgroup Driver: systemd et Cgroup Version: 2.

  • Chaîne firewall/NAT disponible (critique pour les bridges Docker, reverse proxies, et tout ce qui fait du port mapping) :
  nft list ruleset >/dev/null 2>&1 && echo "nftables OK" || echo "nftables KO"
  iptables -S >/dev/null 2>&1 && echo "iptables OK" || echo "iptables KO"
  • Forwarding/bridge netfilter cohérents (sinon, vous aurez des surprises de connectivité inter-conteneurs) :
  sysctl net.ipv4.ip_forward
  sysctl net.bridge.bridge-nf-call-iptables 2>/dev/null || true

Point souvent sous-estimé : la compatibilité “fonctionnelle” ne garantit pas la stabilité. Un VPS avec surallocation agressive peut déclencher du CPU steal et des latences disque “en dents de scie”. Sur des workloads e-commerce (PrestaShop 9.x + PHP 8.2/8.3 + MariaDB + Redis), ces variations se traduisent par des pics de TTFB, des back-off côté PHP-FPM/FrankenPHP et, à la fin, des 503. Si vous devez diagnostiquer une 503, gardez une méthodologie serveur/logs propre (voir : diagnostic 503 – Expertise PrestaShop).

Enfin, ajoutez une couche “GEO pragmatique” : en e-commerce, la localisation du datacenter n’est pas un argument marketing, c’est une variable de latence. Si votre clientèle est majoritairement en France/Benelux, un VPS en France (Paris/Marseille selon les fournisseurs) ou en zones proches (Belgique, Allemagne de l’Ouest) réduit généralement le RTT moyen par rapport à des régions plus lointaines. Plutôt que de deviner, mesurez depuis vos réseaux “réels” (bureau, 4G/5G, fibre) :

mtr -rwzbc 100 <ip_vps>
curl -o /dev/null -s -w 'namelookup:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' https://votre-domaine/

CPU : vCPU, fréquence, ISA, contention et “steal time”

Sur un VPS pour Docker, la question n’est pas “combien de vCPU”, mais quelle performance CPU soutenue. Les providers vendent souvent du burst CPU : ça passe sur docker build ou un import ponctuel, puis vous tombez sur une limite de crédits/quotas et la latence explose. Pour un stack conteneurisé classique (Nginx/HAProxy + PHP + MariaDB + Redis), la saturation se voit d’abord sur PHP et sur les threads InnoDB.

Deux points techniques à regarder : (1) la fréquence et génération CPU (AVX2/AVX-512 pour certains workloads, compression, chiffrement, ou recherche), (2) la contention (noisy neighbor). Mesurez le steal time :

apt-get install -y sysstat
mpstat 1
# surveiller la colonne %steal ; >2-3% soutenu = VPS surchargé

Si %steal monte pendant vos pics (cron, indexation, exports), vous n’avez pas un “problème Docker”, vous avez un problème de host.

Pour objectiver la partie “fréquence/ISA”, gardez un réflexe simple : inspectez les flags CPU et la stabilité en charge.

lscpu | egrep 'Model name|Socket|Thread|MHz|Flags'
  • aes, pclmulqdq : utiles si vous terminez beaucoup de TLS (reverse proxy) et chiffrez des backups.
  • avx2 : utile sur certains traitements (compression, search, parfois images), mais pas un prérequis universel.
  • Attention aux CPU “très basiques” : ils peuvent suffire en dev, mais rendent la prod imprévisible dès que vous activez des jobs.

Côté conteneurs, l’erreur classique est d’avoir toutes les charges “batch” dans le même service que le front. Une stratégie simple (et très efficace) : isoler les tâches lourdes dans un conteneur “worker” et le brider. Exemple de principes (sans imposer un format unique) :

  • limiter un worker à un budget CPU (pour qu’il n’écrase pas PHP/DB),
  • planifier les gros cron à des fenêtres plus calmes,
  • mettre de la priorité (nice) côté OS si nécessaire.

Côté sizing réaliste : 2 vCPU suffisent rarement en production dès qu’on active des tâches lourdes (index de recherche, thumbnails, import, hooks). Pour des boutiques à catalogue conséquent, l’indexation et les jobs (ex : réconciliation d’import) peuvent monopoliser le CPU (voir les contraintes d’import : Import PrestaShop – Expertise PrestaShop). Si vous conteneurisez, isolez les jobs (service séparé, limites CPU cgroup) pour éviter de “voler” le CPU du front.

Dernier point “terrain” : beaucoup de stacks modernes ajoutent des coûts CPU invisibles au début (TLS, HTTP/2, compression Brotli/gzip, antivirus/scan, génération d’images). Un VPS qui “tient” en trafic faible peut devenir limite le jour où vous activez un CDN partiel, une stratégie d’images, ou un module qui augmente le nombre de requêtes dynamiques.

RAM : page cache, buffers MariaDB/Redis, OOM killer et limites cgroup

La RAM est le premier facteur de stabilité sur un VPS Docker. Entre le page cache Linux, les buffers InnoDB, OPcache, et éventuellement Redis, vous pouvez “manger” 8–16 Go sans forcer. Le piège : un système qui “semble” tenir jusqu’au jour où l’OOM killer tue le mauvais conteneur (souvent celui qui a le plus de RSS au moment T, pas celui qui est responsable).

Docker ajoute une couche : les limites mémoire cgroup. Si vous mettez un mem_limit trop bas sur PHP ou MariaDB, vous créez des OOM dans le conteneur (killed), parfois invisibles si vous ne scrutez pas dmesg et les exit codes (selon la version de Compose, la configuration des limites se gère différemment). À l’inverse, si vous ne mettez aucune limite, un service (ex : un import) peut faire monter la mémoire et provoquer du swap, donc de la latence globale. Sur un VPS, le swap peut sauver un spike court, mais en e-commerce il cache souvent une mauvaise allocation RAM.

Deux vérifications rapides qui évitent des “faux diagnostics” :

1) Distinguer la mémoire réellement libre de la mémoire utile (cache) :

free -h
cat /proc/meminfo | egrep 'MemAvailable|Cached|Buffers|Swap'

2) Voir les OOM côté hôte et côté conteneur :

dmesg -T | egrep -i 'oom|killed process' | tail -n 30
docker ps -a --format 'table {{.Names}}\t{{.Status}}' | tail

Recommandation opérationnelle : dimensionnez la RAM par “gros consommateurs” et imposez des budgets. Exemple PrestaShop : OPcache bien configuré (OPcache recommandations – Expertise PrestaShop), MariaDB avec un innodb_buffer_pool_size cohérent, Redis limité (Redis PrestaShop – Expertise PrestaShop). Ensuite, encodez ces budgets dans compose.yaml (limits) et monitorez les oom_kill/container_restart comme des incidents, pas comme du bruit.

Pour rendre ces “budgets” concrets, voici une grille simple (à adapter à votre trafic et à votre profil de catalogue) sur un VPS “tout-en-un” :

Composant Ordre d’idée RAM Signal d’alerte
PHP (FPM/FrankenPHP) + OPcache 1–4 Go hausse des 502/504, workers saturés
MariaDB (buffer pool + caches) 3–16 Go InnoDB buffer pool reads qui explose, latence queries
Redis 256 Mo–4 Go évictions fréquentes (maxmemory-policy)
OS + page cache 1–4 Go MemAvailable faible + swap actif

Objectif : garder une marge (notamment pour le cache disque) plutôt que de “coller” 100% de la RAM à des daemons, surtout en conteneurs.

Stockage : NVMe, IOPS réels, fsync, overlay2 et stratégie volumes/sauvegardes

Pour Docker, le stockage est à la fois un sujet de performance et de fiabilité. Les couches d’images et le filesystem de conteneur reposent souvent sur overlay2. Docker est explicite : « overlay2 is the preferred storage driver for all currently supported Linux distributions. » (Docker documentation, OverlayFS storage driver, Docker docs – OverlayFS storage driver). Concrètement, overlay2 fonctionne bien sur des disques rapides, mais peut souffrir si le provider impose des limites IOPS agressives.

Ne vous contentez pas de “NVMe” sur une fiche produit. Mesurez :

apt-get install -y fio
fio --name=randwrite --filename=/var/lib/docker/fio.test --size=2G \
  --rw=randwrite --bs=4k --iodepth=32 --numjobs=1 --direct=1 \
  --time_based --runtime=60 --group_reporting

Pour MariaDB, ce ne sont pas que les MB/s qui comptent, mais la latence sur les writes sync (fsync). Une latence 99p élevée sur 4k random write se traduira en InnoDB log waits et en checkout lent.

  • Regardez latence (clés : clat / percentiles), pas seulement les IOPS “moyennes”.
  • Comparez deux emplacements si possible : (a) là où Docker écrit (/var/lib/docker), (b) là où la DB écrit (volume dédié). Un provider peut avoir des profils I/O différents selon le type de volume.

Architecture recommandée : évitez de laisser des données critiques “dans la couche writable” du conteneur. Utilisez des volumes (ou bind mounts) pour /var/lib/mysql, /var/lib/redis, /var/www/html/var (cache) et organisez vos backups. Et si vous migrez MySQL/MariaDB, traitez ça comme un chantier infra (InnoDB, collation, charset) plutôt qu’un simple dump/restore (Prérequis migration MySQL→MariaDB – Expertise PrestaShop).

Côté sauvegardes, une règle simple évite des restaurations impossibles : un snapshot de volume n’est pas un backup applicatif si votre base est en pleine écriture. En production, visez au minimum :

  • un dump logique (ou un backup physique cohérent selon votre stratégie),
  • une copie hors du VPS (autre zone/région si possible),
  • un test de restauration (au moins sur staging).

Réseau : latence, débit, IPv4/IPv6, MTU et reverse proxy propre

Un VPS pour Docker doit encaisser : trafic HTTP(S), appels externes (paiement, ERP), et parfois réplication/backup. Deux métriques réelles : latence (surtout vers vos dépendances : DB managée, storage, APIs) et perte/variabilité. Le débit “1 Gbps” sur une brochure est inutile si la congestion et le jitter sont mauvais sur les heures de pointe.

Docker rajoute des composants réseau (bridge, NAT, conntrack). Si vous avez une charge HTTP élevée, surveillez nf_conntrack et la table NAT. Exemple de vérifs rapides :

sysctl net.netfilter.nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count
ss -s

Si le count se rapproche du max, vous verrez des symptômes “bizarres” (connexions qui échouent aléatoirement) qui ressemblent à un bug applicatif… mais sont purement réseau/kernel.

Et faites attention au MTU : certains providers (ou tunnels) imposent du 1450, et vous vous retrouvez avec des timeouts aléatoires si PMTUD est cassé. Test rapide :

ping -M do -s 1472 1.1.1.1  # 1472 + 28 = 1500

Si ça ne passe pas, adaptez le MTU Docker (/etc/docker/daemon.json) ou votre overlay réseau.

  • Si votre reverse proxy et votre VPS sont dans une région donnée, mais que vos services tiers (paiement, ERP, outils marketing) sont hébergés ailleurs, testez la latence VPS → API (pas seulement client → VPS). Une latence instable vers un PSP peut se transformer en paniers abandonnés.
  • Si vous activez HTTP/3 (QUIC), vérifiez que l’UDP/443 est bien autorisé (firewall provider + firewall OS). C’est une cause fréquente de “ça marche chez moi, pas chez certains clients”.

Pour la terminaison TLS et la gestion du trafic, un reverse proxy robuste (HAProxy) rend le déploiement plus prédictible : limitation débit, healthchecks, circuit breaker. La doc interne ici est directement réutilisable en conteneurs (HAProxy – Expertise PrestaShop). Et si vous partez sur Caddy/FrankenPHP, anticipez aussi le coût CPU de TLS/HTTP3 et la gestion certificats (FrankenPHP & Caddy – Expertise PrestaShop).

Sécurité et isolation : rootless, AppArmor/SELinux, patching et secrets

Sur VPS, Docker est souvent déployé “vite fait” en root, avec un daemon exposé et des volumes permissifs. C’est une surface d’attaque classique. Si votre provider le supporte, considérez rootless Docker ou, au minimum, un durcissement AppArmor/SELinux et des user namespaces. Et n’oubliez pas que la sécurité Docker ne compense pas une base OS non patchée : planifiez les updates kernel, OpenSSL, container runtime.

Quelques mesures très “rentables” sur un VPS Docker (sans transformer votre stack en projet sécurité de 6 mois) :

  • ne jamais exposer le socket Docker (/var/run/docker.sock) à un conteneur “par confort” ;
  • exécuter vos conteneurs applicatifs en non-root quand c’est possible ;
  • éviter les privilèges inutiles (--privileged, capabilities non nécessaires) ;
  • limiter l’écriture avec des systèmes de fichiers en lecture seule (quand l’app le permet) et des volumes strictement nécessaires ;
  • pare-feu côté VPS (et, si disponible, security groups côté provider) : n’ouvrir que 22 (idéalement restreint), 80/443, et le strict nécessaire.

Côté runtime, alignez la gestion des cgroups avec systemd et vos outils. Kubernetes résume un point clé (valable même sans Kubernetes) : « The kubelet’s cgroup driver must match the container runtime’s cgroup driver. » (Kubernetes docs – Container runtimes). Traduction Docker-only : choisissez une pile cohérente (systemd + cgroup v2) pour éviter des comportements bizarres de limites CPU/RAM. Pour approfondir la logique de cgroup v2 côté noyau Linux (référence technique), voir : Kernel docs – cgroup v2

Enfin, traitez les secrets proprement : pas de mots de passe dans compose.yaml, pas de .env committé. Si vous avez déjà une brique de gestion de secrets (Vault, SOPS, ou équivalent), branchez-la. Sur un stack plus ambitieux (Kubernetes), l’External Secrets Operator est un standard de fait ; la logique reste la même : synchroniser depuis une source KMS/OKMS vers votre runtime (External Secrets Operator – Expertise PrestaShop).

Profils de ressources recommandés (dev/staging/prod) + checklist de validation

Il n’existe pas de taille “universelle”, mais vous pouvez partir de profils stables, puis ajuster avec des métriques (CPU steal, latence disque, RAM, temps de réponse). Pour un stack Docker typique PrestaShop (web + PHP + MariaDB + Redis), ces bases évitent 80% des erreurs de sizing :

Profil Usage vCPU RAM Disque Notes
Dev dev local distant / sandbox 2 4–6 Go 40–80 Go NVMe pas d’Elasticsearch ; logs limités
Staging pré-prod réaliste, tests perf 4 8–12 Go 80–160 Go NVMe dataset anonymisé, jobs activés
Prod (small/medium) boutique standard 4–8 16–32 Go 160–320 Go NVMe Redis recommandé, backups chiffrés
Prod (catalogue lourd) gros catalogue + recherche 8–16 32–64 Go NVMe + IOPS garantis penser séparation DB/recherche

Dans les gros catalogues, la recherche interne (Elasticsearch/Solr) devient vite un serveur à part. Ce n’est pas “un conteneur de plus” : c’est une charge mémoire/IO propre, avec ses JVM tuning et ses disques. Si vous hésitez sur la recherche, partez d’une analyse de besoin/pertinence et des métriques de conversion (Recherche interne – Expertise PrestaShop).

Avant de valider un VPS pour Docker, exécutez une checklist qui force le réel : (1) bench CPU sysbench + mesure %steal, (2) bench I/O fio sur le futur emplacement de /var/lib/docker et du volume DB, (3) test réseau iperf3 (vers un serveur de référence) + vérification MTU, (4) test de montée en charge applicative (k6/wrk) sur vos endpoints critiques (checkout, recherche).

Pour rendre cette checklist exécutable (et comparable entre fournisseurs), vous pouvez la formaliser en “go/no-go” :

  • Virtualisation : systemd-detect-virt indique KVM (ou équivalent complet), cgroup v2 actif.
  • CPU : %steal < 2–3% en charge soutenue sur un test de 10–15 min.
  • Disque : latence 99p acceptable sur random write 4k (le chiffre “acceptable” dépend de votre DB, mais l’important est d’éviter une latence qui part en spikes).
  • Réseau : pas de pertes sur mtr, MTU cohérent, et tests vers vos APIs critiques.
  • Stabilité : aucun redémarrage conteneur “mystérieux”, pas d’OOM dans dmesg.

Et si vos tests montrent que vous “tapez le plafond” trop tôt, assumez le move : un serveur dédié ou une infra HA est souvent plus simple qu’un VPS surdimensionné et instable (Serveurs dédiés – Expertise PrestaShop).


À lire aussi