Problème de permissions avec Docker

Voir la vidéo

Dans ce tutoriel nous allons voir comment gérer les problèmes de permissions que beaucoup d'entre vous rencontre lors de la mise en place d'un environnement Docker.

La problématique

Lorsque l'on travaille avec un environnement docker on monte très souvent un volume de notre système dans le conteneur. Lors de son éxécution le conteneur va écrire des fichiers dans ce volume, fichiers qu'il ne sera pas possible ensuite de supprimer facilement car on aura des erreurs de permissions.

En effet, les écritures de fichiers au sein du conteneur se font avec l'utilisateur root, et se retrouve donc aussi avec ce propriétaire sur le système de fichier hôte. On est alors obligé d'utiliser un sudo pour supprimer ces fichiers.

Solution 1, le drapeau --user

La première solution pour remédier au problème consiste à utiliser le drapeau --user lorsque l'ont utilise un conteneur afin de faire correspondre l'utilisateur dans le conteneur à l'utilisateur de notre système. On peut utiliser la commande id pour obtenir l'id de notre utilisateur et de notre groupe dynamiquement.

# Dans le cas de bash
docker run --rm -v ${PWD}:/app --user $(id -u):$(id -g) php php /app/index.php

Il faudra en revanche être attentif au fonctionnement du conteneur car cela peut poser des problèmes de permissions au sein même du container car votre utilisateur n'aura pas forcément les niveaux de permission nécessaire pour effectuer certaines actions. Par exemple, si vous utilisez un container apache vous ne pourrez pas utiliser le port 80 et il faudra changer votre configuration (si votre version du kernel est supérieur ou égale à 4.11 vous pouvez contourner ce problème avec le drapeau --sysctl net.ipv4.ip_unprivileged_port_start=0).

Solution 2, construire le container avec le bon utilisateur

L'autre solution consiste à construire notre container avec un utilisateur qui correspond à l'utilisateur de notre système. Par exemple, en partant de l'image apache de PHP on va utiliser des arguments de build pour passer l'id et l'utilisateur et du groupe.

FROM php:7.2-apache

ARG USER_ID
ARG GROUP_ID

RUN groupadd -f -g $GROUP_ID user
RUN useradd -u $USER_ID -g $GROUP_ID user
USER user

On utilisera ensuite ces arguments pour créer l'utilisateur à l'intérieur du conteneur et on le définira comme utilisateur à utiliser lors de l'éxécution du container.

docker build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) -t grafikart:php ./php

Mainenant vous n'avez plus à vous soucier des permissions lorsque vous utilisez cette image car le conteneur utilisera le même utilisateur que votre système. Comme pour la première solution il faudra surement ajuster certaines choses pour éviter les problèmes de permissions mais le processus dépendra du conteneur à mettre en place.

avec docker compose

Ces 2 solutions peuvent être appliquée simplement avec docker-compose.

Pour adopter la solution 1, il faudra passer l'utilisateur dans la configuration.

version: '3.1'
services:
    web:
        image: php:7.2-apache
        user: "${USER_ID}:${GROUP_ID}"
        ports:
            - 8000:80
        volumes:
            - .:/var/www/html
        sysctls:
            - net.ipv4.ip_unprivileged_port_start=0

Vous pouvez utiliser des variables d'environnement afin de dynamiser les choses.

USER_ID=$(id -u) GROUP_ID=$(id -g) docker-compose up

Pour adopter la solution 2, il suffit de passer les informations au niveau des arguments de build.

version: '3.1'
services:
    web:
        build:
            context: ./php
            args:
                USER_ID: ${USER_ID}
                GROUP_ID: ${GROUP_ID}
        ports:
            - 8000:80
        volumes:
            - .:/var/www/html
        sysctls:
            - net.ipv4.ip_unprivileged_port_start=0

Et voila, docker ne devrait plus vous poser de problème de permission maintenant.

Publié
Technologies utilisées
Auteur :
Grafikart
Partager