Docker est devenu le standard pour déployer des applications dans des conteneurs. Cependant, avant de pouvoir déployer son application, il faut définir “comment” on va packager son application pour ensuite pouvoir la déployer dans les différents environnements. Bien qu’un conteneur docker est par défaut plus isolé qu’un système traditionelle (par exemple un site internet déployé sur une machine virtuelle), il est quand même nécessaire d’optimiser et de sécuriser son image docker. Par image docker on entends le fichier décrivant les différentes étapes de préparation de votre application dans le conteneur.
Dans cet article nous explorerons différents aspects de la sécurisation d’une image docker à travers un exemple d’image que l’on optimisera ensemble. Cette image contiendra une simple application react.
Voici l’image que l’on veut optimiser :
FROM ubuntu:latest
ENV CI true
RUN apt update \\
&& apt upgrade -y \\
&& apt install nodejs npm apache2 -y
COPY ./my-app /app
WORKDIR /app
RUN npm install --silent
RUN npm run test
RUN npm run build
RUN mv /app/build/* /var/www/html/
EXPOSE 80
CMD apachectl -D FOREGROUND
Cette image utilise une ubuntu comme source, installe des dépendances nodejs et apache2 , copie l’application à l’intérieur, test et compile l’application avant de la déplacer dans le dossier d’exposition par défaut d’apache2 /var/www/html.
Si nous déployons cette application, voici le résultat :
Ce docker n’est pas optimisé ni sécurisé. Voici comment nous allons améliorer ça.
Lorsque l’on crée une image docker, nous avons besoin de définir une image de base sur laquelle nous allons réaliser des modifications pour préparer notre application. Dans notre exemple, l’image de base choisie est ubuntu:latest. Cette image n’est pas optimisée, car elle embarque avec elle un très grand nombre d’outils (tout le système d’exploitation Ubuntu) dont nous avons pas besoin. Chaque outil pouvant être la source d’une faille de sécurité, il faut en ajouter le moins possible dans les images.
Pour notre image, il semble que nous ayons besoin uniquement du serveur web apache. Nous allons donc utiliser une image apache (aussi appelé httpd) avec le moins de dépendance à l’intérieur. Pour cela nous allons utiliser l’image httpd:2.4-alpine. Cette image est basée sur le système d’exploitation alpine qui est reconnue pour sa légèreté idéale pour les dockers.
L’image httpd:2.4-alpine est une bonne image pour exposer notre application. Cependant, il ne comprends pas les outils nécessaires à la compilation et la réalisation des tests unitaires de notre application react. Pour cela nous allons réaliser du multi-stage build. Cette technique consiste à réaliser l’ensemble de la phase de compilation et de test dans un docker et d’en extraire uniquement le code compilé dans un second docker qui sera le docker que l’on déploiera. Nous pouvons schématiser ce processus comme cela :