Introduction
Récemment j’ai déployer pour la première fois une application sur un VPS. Jusqu’à présent j’utilisais des serveurs mutualisés avec quelques bidouille.
Le déploiement d’une application sur un serveur VPS (Virtual Private Server) peut sembler intimidant pour les débutants. Pourtant, avec Docker et une pipeline CI/CD (Intégration Continue / Déploiement Continu), il est possible d’automatiser et de simplifier cette tâche.
Dans cet article, nous allons voir comment dockeriser une application Nuxt et la déployer sur un VPS en utilisant Docker. Nous verrons aussi comment automatiser le processus de déploiement grâce à un pipeline CI/CD.
Prérequis
Avant de commencer, vous devez avoir :
- Un compte VPS chez un hébergeur (Hostinger pour ma part) avec un OS installé (Ubuntu 22.04 par exemple)
- Un accès SSH à votre VPS
- GitHub ou GitLab pour la gestion du code source
- Un projet à dockeriser (ici un projet Nuxt)
1. Dockerisation de l’application

Pour cet article et vu que c’est ma stack principale mon projet à dockeriser sera un site simple sur Nuxt. Il n’y aura pas de base de données et nous aurons qu’un seul conteneur Docker.
Nous allons le dockeriser en créant un fichier Dockerfile à la racine du projet.
a. Création du Dockerfile
Un Dockerfile est un fichier texte contenant une série d’instructions permettant de créer une image Docker. Il définit l’environnement dans lequel une application va s’exécuter en spécifiant le système de base, les dépendances, les fichiers à copier, les commandes à exécuter, et les ports à exposer.
C’est un fichier qui se nomme Dockerfile (sans extension).
Créez un fichier Dockerfile à la racine du projet et ajoutez-y le contenu suivant :
# Étape 1 : Utiliser une image Node.js
FROM node:18-alpine
# Étape 2 : Définir le répertoire de travail
WORKDIR /usr/src/app
# Étape 4 : Copier les fichiers nécessaires
COPY package*.json ./
COPY . .
# Étape 4 : Installer les dépendances
RUN npm install
# Étape 5 : Construire l'application pour la production
RUN npm run build
# Étape 6 : Exposer le port de l'application
EXPOSE 3000
# Étape 7 : Lancer l'application en mode production
CMD ["node", ".output/server/index.mjs"]
Voyons ce que font ces lignes :
FROM node:18-alpine : Utilise l’image officielle de Node.js en version 18 basée sur Alpine Linux (une version légère et optimisée pour les conteneurs). Les Dockerfiles commencent toujours pas FROM et une image
WORKDIR /usr/src/app : Définit le répertoire de travail à l’intérieur du conteneur où les fichiers seront copiés.
COPY package*.json ./ : Copie uniquement les fichiers package.json et package-lock.json (pour optimiser la gestion des dépendances.)
COPY . . : Copie tous les fichiers du projet dans le conteneur.
Ensuite c’est comme si vous lanciez votre projet dans le terminal (sauf la partie EXPOSE)
RUN npm install : Installe les dépendances du projet définies dans package.json.
RUN npm run build : Exécute la commande de build pour générer les fichiers de production de Nuxt.
EXPOSE 3000 : Indique que l’application écoute sur le port 3000.
CMD ["node", ".output/server/index.mjs"] : Démarre le serveur Nuxt en mode production.
b. Création du fichier .dockerignore
Comme pour les repos distants Git, certains fichiers n’ont pas besoin d’être ajouter au conteneur. Ajoutez un fichier .dockerignore à la racine de votre application pour éviter de copier les fichiers inutiles dans l’image Docker :
node_modules
.git
.gitignore
.output //Pour une application Nuxt
c. Construction de l’image Docker
La suite se passe sur le terminal, exécutez la commande suivante pour construire l’image Docker :
docker build -t mon-image-nuxt .
La partie dockerisation est terminé. Une fois l’image construite, nous allons la transférer et la déployer sur notre VPS.
2. Préparation de l’environnement sur le VPS
Il faudra que vous ayez une connexion SSH à votre VPS. Je ne détaillerai pas cette partie, cela se fait facilement sur MAC. Sur Windows je n’en ai jamais fait mais il semble que vous ayez besoin de soft supplémentaire comme PuTTYgen.
a. Connexion au serveur
Connectez-vous à votre VPS via SSH :
ssh user@votre-ip-vps
b. Installation de Docker et Docker Compose
Mettons à jour le système et installons Docker :
sudo apt update && sudo apt upgrade -y
sudo apt install -y docker.io
Ensuite, ajoutons l’utilisateur actuel au groupe Docker :
sudo usermod -aG docker $USER
newgrp docker
Installons Docker Compose (optionnel pour un seul conteneur) :
sudo apt install -y docker-compose
3. Transfert et exécution de l’application Dockerisée
Bien vote VPS est prêt ! Il ne reste plus qu’à transférer l’image Docker de votre machine vers votre VPS et de l’exécuter (enfin presque)
a. Transfert de l’image Docker
Vous pouvez transférer votre image Docker via SCP :
scp mon-image-nuxt.tar user@votre-ip-vps:/home/user/
Puis, importez l’image sur le VPS :
docker load < mon-image-nuxt.tar
b. Exécution du conteneur
Exécutons le conteneur en arrière-plan :
docker run -d -p 3000:3000 --name mon-app-nuxt mon-image-nuxt
Vérifions que le conteneur fonctionne :
docker ps
Allez, comme je le disais plus haut, c’est presque fini ! En effet, votre site est bien installé, mais il faut maintenant y accéder. Sur un VPS, il peut y avoir plusieurs sites ou applications tournant avec des conteneurs Docker. Pour gérer cela et rendre votre application accessible via un nom de domaine, nous allons configurer un reverse proxy avec Nginx.
4. Configuration de Nginx comme reverse proxy
Si votre application doit être accessible via un nom de domaine, configurons Nginx.
Nginx est un serveur web et un reverse proxy performant et léger. Il est souvent utilisé pour :
✅ Servir des sites web statiques (comme HTML, CSS, JS)
✅ Agir comme un reverse proxy : il redirige les requêtes des visiteurs vers les bons services en arrière-plan (comme ton conteneur)
✅ Gérer plusieurs sites sur un même serveur
✅ Améliorer la sécurité en cachant la structure interne du serveur
✅ Optimiser les performances grâce à la mise en cache et au load balancing
a. Installation de Nginx
sudo apt install -y nginx
b. Configuration de Nginx
Créons un fichier de configuration pour notre site :
sudo nano /etc/nginx/sites-available/mon-app
Ajoutez la configuration suivante, on considère que l’on a pas encore de nom de domaine pour notre site:
server {
listen 80;
server_name _; # Accepte toutes les requêtes sur le serveur, indépendamment du nom d'hôte
// sinon => server_name mon-domaine.com;
location / {
proxy_pass http://localhost:3000; # Redirige les requêtes vers le serveur local qui écoute sur le port 3000
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Activez la configuration et redémarrez Nginx :
sudo ln -s /etc/nginx/sites-available/mon-app /etc/nginx/sites-enabled/
sudo systemctl restart nginx
5. Automatisation avec un pipeline CI/CD
Cette partie est totalement optionnelle et est déjà bien poussée. Je vous recommande d’avoir de bonnes bases sur Git. Cette partie suppose bien évidemment que votre projet est versionner sur GitHub.
a. Configuration GitHub Actions
Créons un fichier .github/workflows/deploy.yml dans notre dossier race
name: Deploy to VPS
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Build Docker image
run: docker build -t mon-image-nuxt .
- name: Save and upload Docker image
run: docker save mon-image-nuxt > mon-image-nuxt.tar && scp mon-image-nuxt.tar user@votre-ip-vps:/home/user/
- name: Connect and restart container
run: |
ssh user@votre-ip-vps << 'EOF'
docker load < /home/user/mon-image-nuxt.tar
docker stop mon-app-nuxt || true
docker rm mon-app-nuxt || true
docker run -d -p 3000:3000 --name mon-app-nuxt mon-image-nuxt
EOF
Et voila ! Dès qu’un push est fait sur la branch main, GitHub action créé une image Docker, l’envoie sur le VPS et la lance sans action de votre part ! Vous avez fait vos premiers pas dans le monde magique des DevOps.