Skip to content

Commit 9fbd3ae

Browse files
committed
feat(docker): Création d'une documentation de mise en production avec docker
1 parent 559ac89 commit 9fbd3ae

File tree

6 files changed

+252
-5
lines changed

6 files changed

+252
-5
lines changed
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# Documentation sur la mise en production avec Docker
2+
3+
## Table des matières
4+
5+
- [Documentation sur la mise en production avec Docker](#documentation-sur-la-mise-en-production-avec-docker)
6+
- [Table des matières](#table-des-matières)
7+
- [Prérequis](#prérequis)
8+
- [Paramètres de Visual Studio Code pour Docker avec node.js et typescript](#paramètres-de-visual-studio-code-pour-docker-avec-nodejs-et-typescript)
9+
- [Création d'une image Docker pour la production](#création-dune-image-docker-pour-la-production)
10+
- [Création du container Docker](#création-du-container-docker)
11+
- [Mise à jour et maintenance des conteneurs en production](#mise-à-jour-et-maintenance-des-conteneurs-en-production)
12+
- [Licence](#licence)
13+
14+
## Prérequis
15+
16+
- Avoir un projet fonctionnel (application web, API, etc.) prêt à être déployé en production.
17+
- Avoir Docker installé sur votre machine pour pouvoir tester localement avant le déploiement.
18+
- Si vous n'avez pas encore Docker installé, vous pouvez suivre la [documentation d'installation de Docker engine](../../02_applications/docker_installation.md).
19+
20+
Dans ce guide, nous allons prendre pour exemple une API RESTful développée avec Node.js et Express.
21+
22+
Voici l'arborescence de notre projet exemple :
23+
24+
```txt
25+
my_api
26+
├── src
27+
│ ├── fichiers_source.js
28+
│ └── ...
29+
├── public
30+
│ ├── fichiers_publics.png
31+
│ └── ...
32+
├── package.json
33+
├── package-lock.json
34+
├── tsconfig.json
35+
├── docker-compose.yml
36+
└── docker-compose.dev.yml
37+
```
38+
39+
## Paramètres de Visual Studio Code pour Docker avec node.js et typescript
40+
41+
Pour un confort de développement avec Visual Studio Code, vous pouvez télécharger le fichier de profil suivant : [Node.js.code-profile](../../files/Node.js.code-profile) puis l'importer dans les paramètres utilisateur de Visual Studio Code.
42+
43+
## Création d'une image Docker pour la production
44+
45+
- Documentation officielle de Docker file : <https://docs.docker.com/build/>
46+
- Créer un fichier `.dockerignore` à la racine de votre projet.
47+
- Dans ce fichier, nous allons spécifier les fichiers et dossiers à ignorer lors de la construction de l'image Docker. Cela permet d'être sûr de ne pas inclure des fichiers sensibles dans l'image finale.
48+
- Copier ce texte dans le fichier `.dockerignore` à la racine de votre projet.
49+
50+
```txt
51+
.git
52+
.env
53+
.env.*
54+
node_modules
55+
```
56+
57+
- Créer un fichier `Dockerfile` à la racine de votre projet.
58+
- Dans ce fichier, nous allons définir les étapes nécessaires pour construire une image Docker optimisée pour la production. Pour cela nous utiliserons un build multi-étapes afin de réduire la taille finale de l'image ainsi que d'améliorer la sécurité en n'incluant pas les fichiers sources et les dépendances de développement dans l'image finale.
59+
- Copier ce texte dans le fichier `Dockerfile` à la racine de votre projet.
60+
- Chaque étape est commentée pour expliquer son rôle.
61+
62+
```Dockerfile
63+
# Étape 1 : Build avec TypeScript | Nous allons compiler le projet TypeScript en JavaScript pour la production
64+
FROM node:24-alpine AS builder # Choix de l'image de base (plus de détails sur https://hub.docker.com/_/node)
65+
WORKDIR /app # Repertoire de travail dans le conteneur (par convention, on utilise /app)
66+
67+
# Copier le code source, les fichiers de configuration et les fichiers publics
68+
COPY tsconfig.json ./
69+
COPY package*.json ./
70+
COPY ./src ./src
71+
COPY ./public ./public
72+
73+
# Supprimer les fichiers sensibles s'ils existent. Ils ne sont de toute façon pas copiés grâce au .dockerignore mais c'est une sécurité supplémentaire.
74+
RUN rm -f .env* public/.env* src/.env*
75+
76+
# Installation des dépendances
77+
RUN npm ci
78+
79+
# Build TypeScript → JavaScript
80+
RUN npm run build
81+
82+
# À ce stade, le code est compilé et prêt pour la production dans le dossier /app/dist.
83+
" Mais vous avez encore les dépendances de développement et le code source dans l'image.
84+
85+
# Étape 2 : Image finale | Nous allons créer une image légère et sécurisée pour exécuter l'application en production
86+
FROM node:24-alpine AS runner
87+
WORKDIR /app
88+
89+
# Copie des fichiers nécessaires à l'exécution uniquement
90+
COPY package*.json ./
91+
92+
# Installation des dépendances de production uniquement
93+
RUN npm ci --omit=dev
94+
95+
COPY --from=builder /app/dist ./dist # Copie du code compilé depuis l'étape de build
96+
COPY --from=builder /app/public ./public # Copie des fichiers publics depuis l'étape de build
97+
98+
# Ajout d'un utilisateur non-root avec UID/GID fixes
99+
# Utiliser les options longues pour éviter les ambiguïtés entre différentes variantes d'adduser/addgroup
100+
RUN addgroup --gid 1800 --system myapigroup && \
101+
adduser --uid 1800 --system --ingroup myapigroup --disabled-password --gecos "" --no-create-home myapiuser
102+
103+
# Utilisation de l'utilisateur non-root créée précédemment
104+
USER myapiuser
105+
106+
# lance le serveur Node.js (Lance le fichier principal de votre application)
107+
# /!\ Attention /!\ lancer directement avec node et pas avec un script npm pour éviter d'exécuter des sous-processus inutiles en production
108+
CMD ["node", "dist/server.js"]
109+
```
110+
111+
- Noter que dans l'image finale produite par ce Dockerfile, seul se qui est présent dans l'étape 2 ("runner") sera inclus. Tous se qui se passe dans l'étape 1 ("builder") sera supprimé, donc le code source TypeScript et les dépendances de développement ne seront pas présents, ce qui réduit la taille de l'image et améliore la sécurité.
112+
113+
## Création du container Docker
114+
115+
Pour la création du container Docker en production, nous allons utiliser un fichier `docker-compose.yml`. Nous pourrions utiliser des commandes `docker run`, mais l'utilisation de Docker Compose facilite la gestion des configurations et des services multiples.
116+
117+
- Documentation officielle de Docker Compose : <https://docs.docker.com/compose/>
118+
- Créer un fichier `docker-compose.yml` à la racine de votre projet.
119+
- Copier ce texte dans le fichier `docker-compose.yml` à la racine de votre projet.
120+
- Chaque étape est commentée pour expliquer son rôle.
121+
122+
```yaml
123+
services: # il y a uniquement un service dans cet exemple, mais vous pouvez en ajouter d'autres (base de données, cache, etc.)
124+
myapi-server: # Nom du service (choix libre)
125+
image: myapi-server:latest # Nom de l'image Docker (remplacer par le vôtre)
126+
build: # Construit l'image Docker automatiquement si elle n'existe pas
127+
context: . # Dossier de contexte (la racine du projet)
128+
dockerfile: Dockerfile # Chemin vers le Dockerfile
129+
restart: always # Redémarre le conteneur automatiquement en cas de plantage ou de redémarrage du serveur hôte
130+
env_file:
131+
- .env # Fichier d'environnement spécifique au service (ne pas oublier de le créer et de le configurer)
132+
networks:
133+
- myapi-net # Réseau Docker dédié (à créer plus bas dans le fichier)
134+
ports:
135+
- ${APP_PORT:-}:80 # Mappe le port 80 du conteneur au port spécifié dans la variable d'environnement APP_PORT (ou aucun port spécifique si non défini)
136+
security_opt:
137+
- no-new-privileges:true # Empêche l'élévation de privilèges dans le conteneur
138+
cap_drop:
139+
- ALL # Supprime toutes les capacités Linux du conteneur pour renforcer la sécurité
140+
cap_add:
141+
- NET_BIND_SERVICE # Ajoute uniquement la capacité nécessaire pour lier des ports
142+
read_only: true # Monte le système de fichiers du conteneur en lecture seule pour améliorer la sécurité
143+
user: "1800:1800" # Exécute le conteneur avec l'utilisateur non-root créé dans le Dockerfile
144+
tmpfs:
145+
- /tmp:exec,nosuid,nodev # Monte /tmp en tmpfs avec des options sécurisées (obligatoire si read_only est true)
146+
healthcheck: # Vérifie que le service est opérationnel
147+
test: ["CMD-SHELL", "wget -q --spider http://myapi-server:80/ || exit 1"]
148+
interval: 10s
149+
timeout: 5s
150+
retries: 5
151+
152+
networks: # Définition des réseaux Docker
153+
myapi-net: # Nom du réseau (choix libre)
154+
driver: bridge # Type de réseau (bridge est le plus courant et sécurisé pour les applications simples)
155+
```
156+
157+
- Pour le développement local, vous pouvez utiliser un fichier `docker-compose.dev.yml` avec des configurations adaptées au développement (montage de volumes, ports différents, etc.). Assurez-vous de ne pas utiliser ce fichier en production.
158+
- Pour le développement local, nous n'utiliserons pas l'image construite précédemment. En réalité nous allons utiliser l'image officielle de Node.js et monter le code source en volume pour pouvoir le modifier sans reconstruire l'image à chaque fois. Donc se qui vas se passer c'est que le code sera lancer avec nodemon pour le rechargement automatique et le container utilisera les fichiers et les dépendances présents sur la machine hôte.
159+
160+
```yaml
161+
myapi-server:
162+
image: node:24-alpine # Utilisation de l'image officielle de Node.js (la même version que dans le Dockerfile de production)
163+
working_dir: /app # Repertoire de travail dans le conteneur (par convention, on utilise /app)
164+
env_file: .env # Fichier d'environnement spécifique au service (ne pas oublier de le créer et de le configurer)
165+
volumes:
166+
- ./:/app/ # Monte le code source local dans le conteneur
167+
- ./node_modules:/app/node_modules # Monte les dépendances installées localement pour éviter de les réinstaller dans le conteneur
168+
command: sh -c "cd /app && nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/server.ts" # Commande pour lancer le serveur avec nodemon et ts-node (permet le rechargement automatique)
169+
networks:
170+
- myapi-net # Réseau Docker dédié (à créer plus bas dans le fichier)
171+
ports:
172+
- ${APP_PORT}:80 # Mappe le port 80 du conteneur au port spécifié dans la variable d'environnement APP_PORT
173+
user: "1800:1800" # Exécute le conteneur avec un utilisateur non-root
174+
tmpfs:
175+
- /tmp:exec,nosuid,nodev # Monte /tmp en tmpfs avec des options sécurisées
176+
- /app/src/swagger/json:rw,uid=1800,gid=1800 # Monte le dossier swagger/json en tmpfs pour permettre l'écriture des fichiers générés par l'API
177+
178+
networks: # Définition des réseaux Docker
179+
myapi-net: # Nom du réseau (choix libre)
180+
driver: bridge # Type de réseau (bridge est le plus courant et sécurisé pour les applications simples)
181+
```
182+
183+
- Les réseaux Docker permettent aux conteneurs de communiquer entre eux de manière isolée et sécurisée. En définissant un réseau dédié pour votre application, vous pouvez contrôler quels conteneurs peuvent communiquer entre eux et limiter l'exposition aux autres conteneurs sur le même hôte Docker.
184+
185+
## Mise à jour et maintenance des conteneurs en production
186+
187+
Vous pouvez mettre à jour votre application en suivant ces étapes :
188+
189+
1. Apporter les modifications nécessaires à votre code source.
190+
2. Mettre à jour le fichier `.env` si nécessaire.
191+
3. Rebuild l'image Docker avec la commande :
192+
193+
```bash
194+
docker-compose -f docker-compose.yml build
195+
```
196+
197+
4. Faire une sauvegarde de vos données si nécessaire (base de données, fichiers, etc.).
198+
- Si vous avez une base de données postgresql dans un autre conteneur, vous pouvez vous référer à la documentation suivante pour faire une sauvegarde : [Sauvegarde et restauration de bases de données PostgreSQL avec Docker](../database/postgresql.md#backup-dune-base-de-données-postgresql-depuis-un-conteneur-docker)
199+
5. Stopper le conteneur en cours d'exécution :
200+
201+
```bash
202+
docker-compose -f docker-compose.yml down
203+
```
204+
205+
6. Redémarrer le conteneur avec la nouvelle image :
206+
207+
```bash
208+
docker-compose -f docker-compose.yml up -d
209+
```
210+
211+
7. Restaurer les données si nécessaire.
212+
- Si vous avez une base de données postgresql dans un autre conteneur, vous pouvez vous référer à la documentation suivante pour faire une sauvegarde : [Sauvegarde et restauration de bases de données PostgreSQL avec Docker](../database/postgresql.md#backup-dune-base-de-données-postgresql-depuis-un-conteneur-docker)
213+
214+
## Licence
215+
216+
Copyright (C) 2024 Floris Robart
217+
218+
Authors: Floris Robart
219+
220+
This program is free software; you can redistribute it and/or modify it
221+
under the terms of the GNU Lesser General Public License as published by
222+
the Free Software Foundation; either version 2.1 of the License, or
223+
(at your option) any later version.
224+
225+
This program is distributed in the hope that it will be useful,
226+
but WITHOUT ANY WARRANTY; without even the implied warranty of
227+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
228+
GNU Lesser General Public License for more details.
229+
230+
You should have received a copy of the GNU Lesser General Public License
231+
along with this program; if not, write to the Free Software Foundation,
232+
Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.

docs/01_development/deployment/docker.md renamed to docs/02_applications/docker_installation.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
- [Sources](#sources)
88
- [Introduction](#introduction)
99
- [Installation de Docker engine sur Ubuntu 24.XX](#installation-de-docker-engine-sur-ubuntu-24xx)
10-
- [créer votre premier conteneur Docker](#créer-votre-premier-conteneur-docker)
10+
- [Utilisation de docker](#utilisation-de-docker)
1111
- [Licence](#licence)
1212

1313
## Sources
1414

1515
- [Documentation officiel d'installation de Docker engine](https://docs.docker.com/engine/install/ubuntu/)
1616
- [Documentation officiel de post installation de Docker engine](https://docs.docker.com/engine/install/linux-postinstall/)
17+
- [Documentation officiel complète de Docker engine](https://docs.docker.com/engine/)
1718

1819
## Introduction
1920

@@ -124,9 +125,15 @@
124125
https://docs.docker.com/get-started/
125126
```
126127
127-
## créer votre premier conteneur Docker
128+
## Utilisation de docker
128129
129-
> <https://docs.docker.com/get-started/workshop/>
130+
- Créer un projet docker et mettez le en production en suivant ce tutoriel
131+
132+
> [Production avec docker](../01_development/deployment/production_with_docker.md)
133+
134+
- créer votre premier conteneur Docker
135+
136+
> <https://docs.docker.com/get-started/workshop/>
130137
131138
## Licence
132139

docs/02_applications/installation_usage.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [Documentation d'installation, de configuration et d'utilisation de différents logiciels](#documentation-dinstallation-de-configuration-et-dutilisation-de-différents-logiciels)
66
- [Table des matières](#table-des-matières)
77
- [Installation Ventoy (Multi-boot USB) - Linux](#installation-ventoy-multi-boot-usb---linux)
8+
- [Installation de Docker engine - Linux](#installation-de-docker-engine---linux)
89
- [Installation de Chrome - Linux](#installation-de-chrome---linux)
910
- [Installation de Qdirstat - Linux](#installation-de-qdirstat---linux)
1011
- [Installation de Ticktick - Linux](#installation-de-ticktick---linux)
@@ -60,6 +61,10 @@
6061

6162
[Documentation complète de Ventoy](./ventoy.md)
6263

64+
## Installation de Docker engine - Linux
65+
66+
[Documentation complète de l'installation de Docker engine](./docker_installation.md)
67+
6368
## Installation de Chrome - Linux
6469

6570
- Installer le paquet deb disponible sur

docs/files/Node.js.code-profile

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

docs/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@
2222
- Front-end
2323
- [React](01_development/frontend/react.md)
2424
- Déploiement
25-
- [Docker](01_development/deployment/docker.md)
25+
- [Mise en production d'une application dockerisée](01_development/deployment/production_with_docker.md)
2626
- [Creation de packets Debian](01_development/deployment/debian_package_creation.md)
2727
- [Mise sous licence d'un projet open source](01_development/deployment/open_source_licensing_gnu_gpl.md)
2828
- Autres
2929
- [Bonne pratiques de développement by ChatGPT](01_development/others/coding_best_practices_by_chatgpt.md)
3030
- [Developpement web en PHP](01_development/others/web_development_php.md)
3131
- Applications
3232
- [Installation d'applications Linux divers](02_applications/installation_usage.md)
33+
- [Installation de Docker](02_applications/docker_installation.md)
3334
- [Git](02_applications/git.md)
3435
- [SSH](02_applications/ssh.md)
3536
- [Visual Studio Code](02_applications/vscode.md)

mkdocs.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,15 @@ nav:
7171
- Front-end:
7272
- React : 01_development/frontend/react.md
7373
- Déploiement:
74-
- Docker : 01_development/deployment/docker.md
74+
- Mise en production d'une application dockerisée : 01_development/deployment/production_with_docker.md
7575
- Creation de packets Debian : 01_development/deployment/debian_package_creation.md
7676
- Mise sous licence d'un projet open source: 01_development/deployment/open_source_licensing_gnu_gpl.md
7777
- Autres:
7878
- Bonne pratiques de développement by ChatGPT : 01_development/others/coding_best_practices_by_chatgpt.md
7979
- Developpement web en PHP: 01_development/others/web_development_php.md
8080
- Applications:
8181
- Installation d'applications Linux divers: 02_applications/installation_usage.md
82+
- Installation de Docker : 02_applications/docker_installation.md
8283
- Git: 02_applications/git.md
8384
- SSH: 02_applications/ssh.md
8485
- Visual Studio Code: 02_applications/vscode.md

0 commit comments

Comments
 (0)