¿Cómo cambiar el propietario del directorio VOLUME en Dockerfile?

11

Tengo lo siguiente 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

Lo que lo construí:

$ 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

Sin embargo, cuando se ejecuta, el /opt/myvolumedirectorio es propiedad de root, no 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

porque se creó durante la ejecución.

¿Es posible definir o cambiar el propietario predeterminado del VOLUMEdirectorio en Dockerfile?

Lo estoy ejecutando en macOS y Linux.

kenorb
fuente

Respuestas:

12

Como se indica en la documentación , la instrucción VOLUME hereda el contenido del directorio y los permisos existentes en el contenedor, por lo que puede solucionar el problema con un dockerfile como este:

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 creación del directorio debe hacerse como root (para poder escribir dentro de / opt).

Tensibai
fuente
El truco parece estar especificando VOLUMEdespués de que se crea el directorio: si algún paso de compilación cambia los datos dentro del volumen después de que se haya declarado, esos cambios serán descartados.
Jesse Glick
La creación del directorio no está relacionada, se montará un volumen fuera del contenedor, por lo que todo lo que se haga dentro del contenedor antes del montaje (contenedor lanzado) se descartará. Realmente no entiendo tu comentario
Tensibai
2

Tuve un problema similar, esto funcionó para mí:

  1. Escribe el archivo Docker con:

    # 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. Ejecute estos comandos 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
    

Tenga en cuenta que los nombres, UID, GID deben ser los mismos para el usuario Docker y el usuario host. El último comando bash le dice a la imagen de Docker que ese usuario de host es el mismo que el usuario de directorio de volumen compartido de Docker, por lo que ese directorio de archivo pasa a ser propiedad del "usuario de prueba" en el contenedor de Docker.

CubeBot88
fuente
TAMBIÉN, en algunos entornos, SELinux puede evitar el acceso a archivos. Esto puede resolverse desactivando temporal o permanentemente SELinux (aunque desaconsejo encarecidamente que no lo haga). Puede encontrar una guía sobre esto aquí: tecmint.com/…
CubeBot88