====== Docker Advanced ====== ===== Dockerfiles ===== ==== ARGS ==== Con el comando ARGS puedes definir, dentro del Dockerfile, qué argumentos se pueden usar para construir una imagen: ARG [=] En el siguiente ejemplo se añade un argumento sin valor por defecto ''user'', uno con valor por defecto ''3'' y luego se usa el argumento con la sintaxis ''$user''. FROM busybox ARG user ARG buildno=3 USER $user ===== Images ===== ==== Contexto ==== Como ya sabes el siguiente comando construirá una imagen a partir del Docker file en el directorio actual y la taggeará como ''automatron''. Aún así el ''.'' del final no es dónde la genera sino cual es el contexto (el parámetro para indicar el Dockerfile es ''-f''): docker build -t automatron . Docker no puede salirse de su contexto para buscar ficheros a la hora de construir una imagen. ==== Save and load a physical image ==== docker save --output ../dist/puma-app-docker.tar gtd/puma_app:$VERSION docker load --input puma-app-docker.tar ===== Networks ===== ===== Volumenes ===== $ docker volume create portainer_data $ docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer Listar, eliminar... volumenes $ docker volume ls $ docker volume rm ==== Copiar un fichero a un volumen ==== Imaginemos que queremos copiar un fichero a un volúmen que está siendo usado por un contenedor (y luego darle permisos y ejecutar una acción concreta): $ docker cp file_backup.tar :/var/opt/gitlab/backups $ docker exec chown git:root /var/opt/gitlab/backups/COMA-CORE1-dataset_gitlab_backup.tar $ docker exec -it fa38 gitlab-rake gitlab:backup:restore Siempre necesitaremos un contenedor corriendo para copiar el fichero, tenemos las siguientes opciones: docker container create --name dummy -v myvolume:/root hello-world docker cp c:\myfolder\myfile.txt dummy:/root/myfile.txt docker rm dummy En una línea: docker run --rm -v $PWD:/source -v my_volume:/dest -w /source alpine cp myfile.txt /dest O incluso en un contenedor creado desde cero con un Dockerfile con: FROM scratch CMD Luego: docker build -t nothing . docker container create --name dummy -v myvolume:/root nothing docker cp c:\myfolder\myfile.txt dummy:/root/myfile.txt docker rm dummy ==== Creación de un volumen mapeado en nfs (docker-compose) ==== volumes: nas-owncloud: driver: local driver_opts: type: nfs o: "addr=10.10.10.10,nolock,soft,rw" device: ":/volume1/sir-vices/owncloud" services: owncloud: volumes: - nas-owncloud:/mnt/data ===== Compose ===== ==== Environment variables ==== It’s possible to use environment variables in your shell to populate values inside a Compose file: web: image: "webapp:${TAG}" You can set environment variables with the ''environment'' key, just like with ''docker run -e VARIABLE=VALUE ...'': web: environment: - DEBUG=1 Pass environment variables to containers without giving a value: web: environment: - DEBUG You can pass multiple environment variables from an external file with the ''env_file'' option, just like with ''docker run --env-file=FILE ...'': web: env_file: - web-variables.env Just like with ''docker run -e'', you can set environment variables with ''docker-compose run -e'': docker-compose run -e DEBUG=1 web python console.py You can also pass a variable through from the shell by not giving it a value: docker-compose run -e DEBUG web python console.py You can set default values for any environment variables referenced in the Compose file, or used to configure Compose, in an environment file named .env: $ cat .env TAG=v1.5 $ cat docker-compose.yml version: '3' services: web: image: "webapp:${TAG}" ===== Execute GUI programs ===== You can create a Dockerfile where you install a Firefox, a Visual Studio Code... Whatever. Then, as the X11 Linux programs work like client\server you only need to bind the socket. \\ For example, a Dockerfile could be this: FROM ubuntu:14.04 RUN apt-get update && apt-get install -y firefox RUN export uid=1000 gid=1000 && \ mkdir -p /home/developer && \ echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \ echo "developer:x:${uid}:" >> /etc/group && \ echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \ chmod 0440 /etc/sudoers.d/developer && \ chown ${uid}:${gid} -R /home/developer USER developer ENV HOME /home/developer CMD /usr/bin/firefox Then you only need to buid it: docker build -t firefox . And launch it using your x11 socket: docker run -ti --rm \ -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix \ firefox You could also use the run with the cmd as parameter, in this way you could install several programs and launch them with this. ==== Launch them from SSH ==== As it says here [[https://docs.docker.com/engine/examples/running_ssh_service/]] you can create a Dockerfile with... FROM ubuntu:16.04 RUN apt-get update && apt-get install -y openssh-server RUN mkdir /var/run/sshd RUN echo 'root:THEPASSWORDYOUCREATED' | chpasswd RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"] ... for an ssh server. This one will be prepared for launching a remote firefox in your local machine if you connect to it via ssh and launch it. FROM ubuntu:14.04 RUN apt-get update && apt-get install -y firefox openssh-server RUN mkdir /var/run/sshd RUN echo 'root:train' | chpasswd RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile RUN echo "X11UseLocalhost no" >> /etc/ssh/sshd_config EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"] # CMD tail -f /dev/null