Savoir déployer une application sur un VPS vous donne un contrôle total sur votre infrastructure et une compréhension profonde de ce qui se passe en production. C’est aussi moins cher que les plateformes cloud au-delà d’un certain trafic. Ce guide couvre le déploiement complet : VPS chez un hébergeur, Docker Compose, Nginx comme reverse proxy, SSL automatique.
Choisir son VPS
Pour un projet personnel ou de portfolio, un VPS à 6-12€/mois suffit largement :
- DigitalOcean Droplet : 4€/mois pour 512MB RAM — interface claire, documentation excellente
- Hetzner : 4€/mois pour 2GB RAM — le meilleur rapport qualité/prix, data centers en Europe
- OVH VPS : offres françaises, bon support
- Contabo : très bon marché pour beaucoup de RAM
Choisissez Ubuntu 22.04 LTS — large documentation, paquets récents, support long terme.
Configuration initiale du serveur
# Se connecter en SSH (avec la clé SSH configurée chez l'hébergeur)
ssh root@votre-ip
# Créer un utilisateur non-root
adduser deploy
usermod -aG sudo deploy
# Copier la clé SSH pour le nouvel utilisateur
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy
# Désactiver la connexion root par SSH (sécurité)
nano /etc/ssh/sshd_config
# → PermitRootLogin no
systemctl reload ssh
# Se reconnecter avec l'utilisateur deploy
ssh deploy@votre-ip
# Mettre à jour les paquets
sudo apt update && sudo apt upgrade -y
# Installer Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker deploy
# → se déconnecter et reconnecter pour que le groupe soit pris en compte
Nginx comme reverse proxy
Nginx reçoit les requêtes HTTP/HTTPS et les redirige vers votre container applicatif. C’est aussi lui qui gère le SSL.
# docker-compose.prod.yml — avec Nginx et SSL automatique via Caddy
version: '3.9'
services:
caddy: # Caddy gère SSL automatiquement via Let's Encrypt
image: caddy:2-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
depends_on:
- app
app:
image: mon-registry/mon-app:latest
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
depends_on:
- db
restart: unless-stopped
db:
image: postgres:16-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
restart: unless-stopped
volumes:
caddy_data:
postgres_data:
# Caddyfile — SSL automatique
mondomaine.com {
reverse_proxy app:3000
}
Le déploiement étape par étape
# Sur le serveur — première installation
mkdir -p /app && cd /app
# Copier les fichiers de config (pas le code — Docker pull l'image)
scp docker-compose.prod.yml .env Caddyfile deploy@votre-ip:/app/
# Lancer les services
docker compose -f docker-compose.prod.yml up -d
# Vérifier que tout tourne
docker compose -f docker-compose.prod.yml ps
docker compose -f docker-compose.prod.yml logs -f
# Pour les mises à jour (depuis la CI ou manuellement)
docker pull mon-registry/mon-app:latest
docker compose -f docker-compose.prod.yml up -d --no-deps app
docker system prune -f # nettoyer les anciennes images
Firewall et sécurité de base
# UFW — firewall Ubuntu
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
sudo ufw status
# Fail2ban — bloquer les tentatives de brute force SSH
sudo apt install fail2ban
sudo systemctl enable fail2ban
Monitoring basique
# Voir l'utilisation des ressources
docker stats
# Logs applicatifs en temps réel
docker compose logs -f app
# Espace disque
df -h
# Uptimerobot.com (gratuit) — alertes si le site est down
Offres développeur fullstack et DevOps
Des postes pour développeurs qui savent déployer leurs applications — une compétence différenciante pour les profils juniors.
À lire aussi : Docker Compose — Linux pour développeurs — CI/CD GitHub Actions