Comment changer le propriétaire du répertoire VOLUME dans Dockerfile?

11

J'ai ce qui suit Dockerfile:

FROM ubuntu:xenial
RUN useradd -d /home/ubuntu -ms /bin/bash -g root -G sudo -p ubuntu ubuntu
WORKDIR /home/ubuntu
USER ubuntu
VOLUME /opt/myvolume

Que je l'ai construit:

$ docker build -t vol-test .
Sending build context to Docker daemon  2.048kB
Step 1/5 : FROM ubuntu:xenial
 ---> 0b1edfbffd27
Step 2/5 : RUN useradd -d /home/ubuntu -ms /bin/bash -g root -G sudo -p ubuntu ubuntu
 ---> Using cache
 ---> d82e3ecc5fe8
Step 3/5 : WORKDIR /home/ubuntu
 ---> Using cache
 ---> ab1db29ee8bf
Step 4/5 : USER ubuntu
 ---> Using cache
 ---> 129393a35d9e
Step 5/5 : VOLUME /opt/myvolume
 ---> Running in 691a4cbd077e
Removing intermediate container 691a4cbd077e
 ---> 11bc9e9db9d3
Successfully built 11bc9e9db9d3
Successfully tagged vol-test:latest

Cependant, lors de son exécution, le /opt/myvolumerépertoire appartient à root, et non ubuntu:

$ docker run vol-test id
uid=1000(ubuntu) gid=0(root) groups=0(root),27(sudo)
$ docker run vol-test find /opt/myvolume -ls
    66659      4 drwxr-xr-x   2 root     root         4096 Jul 18 23:02 /opt/myvolume
$ docker run -u ubuntu vol-test find /opt/myvolume -ls
    66940      4 drwxr-xr-x   2 root     root         4096 Jul 18 23:12 /opt/myvolume

car il est créé pendant la course.

Est-il possible de définir ou de changer le propriétaire par défaut du VOLUMErépertoire dans Dockerfile?

Je l'exécute sur macOS et Linux.

kenorb
la source

Réponses:

12

Comme indiqué dans la documentation , l'instruction VOLUME hérite du contenu du répertoire et des autorisations existantes dans le conteneur, vous pouvez donc contourner le problème avec un fichier docker comme celui-ci:

FROM ubuntu:xenial
RUN useradd -d /home/ubuntu -ms /bin/bash -g root -G sudo -p ubuntu ubuntu
RUN mkdir /opt/myvolume  && chown ubuntu /opt/myvolume
WORKDIR /home/ubuntu
VOLUME /opt/myvolume

La création du répertoire doit se faire en tant que root (pour pouvoir écrire dans / opt).

Tensibai
la source
L'astuce semble être de spécifier une VOLUMEfois le répertoire créé: si des étapes de génération modifient les données du volume après leur déclaration, ces modifications seront ignorées.
Jesse Glick
La création du répertoire n'est pas liée, un volume sera monté hors du conteneur, donc tout ce qui est fait dans le conteneur avant le montage (lancement du conteneur) sera ignoré. Je ne comprends pas vraiment votre commentaire
Tensibai
2

J'ai eu un problème similaire, cela a fonctionné pour moi:

  1. Écrire un fichier Docker avec:

    # Create app layer:
    FROM python:3.4
    # Create app user & group "testuser" with IDs:
    RUN groupadd -r testuser --gid 1234 && useradd -d /home/testuser -ms /bin/bash -r -g testuser testuser --uid 1234
    # Create "testuser" working dir:
    WORKDIR /home/testuser
    # Make working dir known to Python    
    ENV PYTHONPATH "${PYTHONPATH}:/home/testuser"
    # Create & mount shared storage:
    RUN mkdir /var/run/testuser-storage
    VOLUME ["/var/run/testuser-storage"]
    # Start container as "testuser":
    ENV NAME testuser
    ENV HOME /home/testuser
    USER testuser
    
  2. Exécutez ces commandes bash:

    # Create the same user & group "testuser" with IDs on host:
    getent group testuser > /dev/null || /usr/sbin/groupadd -r testuser --gid 1234
    getent passwd testuser > /dev/null || /usr/sbin/useradd -r -g testuser -d /var/lib/testuser -s /bin/nologin testuser --uid 1234
    # Create shared storage dirs on host:
    mkdir /var/run/testuser-storage
    chown -R testuser.testuser /var/run/testuser-storage
    # Build and run "testuser" Docker image:
    docker build . -t testuser
    docker run --net host --name testuser -v /var/run/testuser-storage:/var/run/testuser-storage -d testuser
    # Change ownership of shared volume dir to the be the GID of "testuser"
    chown -R 1234:1234 /var/run/testuser-storage
    

Notez que les noms, UID et GID doivent être les mêmes pour l'utilisateur Docker et l'utilisateur hôte. La dernière commande bash indique à l'image Docker que cet utilisateur hôte est le même que l'utilisateur de répertoire de volume partagé Docker, de sorte que le répertoire de fichier devient alors la propriété de "testuser" dans le conteneur Docker.

CubeBot88
la source
ÉGALEMENT, dans certains environnements, SELinux peut empêcher l'accès aux fichiers. Cela peut être résolu en désactivant temporairement ou définitivement SELinux (bien que je déconseille fortement la désactivation permanente). Un guide à ce sujet peut être trouvé ici: tecmint.com/…
CubeBot88