El fin de semana pasado, tuve la fortuna de poder asistir al meetup de Docker, donde nos dieron un curso de Docker para principiantes. A pesar de las dificultades presentadas, ya que al ser un curso totalmente gratuito, a base del esfuerzo de la comunidad se logró bastante bien.

En este primer post, les compartiré mis notas del curso.

En el #SysArmyMxTalks previo, el buen Iván Chavero, nos habló de los fundamentos de los contenedores, si quieren revisar el material, lo encuentran en los enlaces:

Durante el curso, nos dieron una breve introducción a docker, además de ver un fragmento del vídeo de la presentación de Jessie Frazell:

Ver en Youtube

Después de esto, iniciamos con la parte práctica:

Comandos básicos

1. Después de instalar docker, es necesario habilitarlo e iniciarlo

user@computer:$ sudo systemctl status docker
[sudo] password for alex.callejas:
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: dis
Active: inactive (dead)
Docs: http://docs.docker.com
$ sudo systemctl enable docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.
$ sudo systemctl start docker

2. Para correr un contenedor mediante docker con nginx, ejecutamos

user@computer:$ sudo docker run nginx
Unable to find image 'nginx:latest' locally
Trying to pull repository registry.fedoraproject.org/nginx ...
Trying to pull repository registry.access.redhat.com/nginx ...
Trying to pull repository docker.io/library/nginx ...
sha256:788fa27763db6d69ad3444e8ba72f947df9e7e163bad7c1f5614f8fd27a311c3: Pulling from docker.io/library/nginx
94ed0c431eb5: Pull complete
9406c100a1c3: Pull complete
aa74daafd50c: Pull complete
Digest: sha256:788fa27763db6d69ad3444e8ba72f947df9e7e163bad7c1f5614f8fd27a311c3
Status: Downloaded newer image for docker.io/nginx:latest
$

Como es una imagen que no tenemos en un repositorio local, la descarga del repositorio oficial de docker.

3. Si abrimos una terminal alterna, podemos observar que el contenedor se esta ejecutando

user@computer:$ sudo docker ps
[sudo] password for alex.callejas:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2127ad18758a nginx "nginx -g 'daemon ..." 30 seconds ago Up 29 seconds 80/tcp cocky_joliot
$

Se observa que, por default, docker nombra el contenedor como cocky_joliot, esto es debido a que si no especificamos un nombre del contenedor, docker por convención utilizará un adjetivo y el apellido de algún científico (según el código fuente de docker)

4. También podemos ejecutar un contenedor de forma interactiva con una TTY

user@computer:$ sudo docker run ubuntu bash
Unable to find image 'ubuntu:latest' locally
Trying to pull repository registry.fedoraproject.org/ubuntu ...
Trying to pull repository registry.access.redhat.com/ubuntu ...
Trying to pull repository docker.io/library/ubuntu ...
sha256:34471448724419596ca4e890496d375801de21b0e67b81a77fd6155ce001edad: Pulling from docker.io/library/ubuntu
d5c6f90da05d: Pull complete
1300883d87d5: Pull complete
c220aa3cfc1b: Pull complete
2e9398f099dc: Pull complete
dc27a084064f: Pull complete
Digest: sha256:34471448724419596ca4e890496d375801de21b0e67b81a77fd6155ce001edad
Status: Downloaded newer image for docker.io/ubuntu:latest
$ sudo docker run -it ubuntu bash
root@a656df585428:/#
root@a656df585428:/# ps
PID TTY TIME CMD
1 ? 00:00:00 bash
11 ? 00:00:00 ps
root@51728d60a8a8:/# pwd
/
root@51728d60a8a8:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@51728d60a8a8:/# exit
exit
$

Se observa que, dentro del contenedor, solamente existe el proceso de bash que ejecutamos, además de contar con toda la estructura de directorios del sistema.

5. En la terminal alterna, podemos observar la ejecución del contenedor

user@computer:$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a656df585428 ubuntu "bash" 45 seconds ago Exited (0) 28 seconds agonifty_payne
2127ad18758a nginx "nginx -g 'daemon ..." 3 minutes ago Exited (0) 2 minutes ago cocky_joliot
$

Con la opción -a, podemos ver todos los contenedores que hemos ejecutado, por default solo se muestran los que se encuentran en ejecución actualmente.

6. Si queremos eliminar un contenedor, utilizamos su CONTAINER ID, de la salida del ps ejecutando

user@computer:$ sudo docker rm 2127ad18758a
2127ad18758a
$ sudo docker rm a656df585428
a656df585428
$

Al revisar en la terminal alterna, ya no se observa dicho contenedor

user@computer:$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$

7. Se le puede indicar al contenedor que se ejecute en background y que utilice un puerto local en particular

user@computer:$ sudo docker run -d -p 80:80 nginx
c81ee76d8cd0b3180b4d543c9d266d13dc1302d396207412eab80d10b091d269
$

Se observa en la terminal alterna, que el proceso se ejecute en el puerto asignado

user@computer:$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c81ee76d8cd0 nginx "nginx -g 'daemon ..." 5 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp tender_montalcini
$

Podemos revisar con el navegador o con curl que el contenedor nos muestre la página de prueba de nginx en el puerto local configurado

Para detener el contenedor, sin eliminarlo, utilizamos su CONTAINER ID o su nombre

user@computer:$ sudo docker stop tender_montalcini
tender_montalcini
$

8. Si lo deseamos, podemos ejecutar un contenedor con un nombre en particular

user@computer:$ sudo docker run --name test -d -p 80:80 nginx
a13f3e75ea522646ca6b1b6a926cdf680b636924bdbf2c2942b7249acff0e513
$

Lo revisamos en la terminal alterna

user@computer:$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a13f3e75ea52 nginx "nginx -g 'daemon ..." 3 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp test
$

También podemos obtener estadísticas ejecutando

user@computer:$ sudo docker stats

CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a13f3e75ea52 0.01% 1.969 MiB / 7.493 GiB 0.03% 7.68 kB / 936 B 0 B / 0 B 2

Estas se muestran en tiempo real.

9. Con el contenedor ejecutándose, también podemos indicarle que corra algún comando en particular, por ejemplo

user@computer:$ sudo docker exec -it test bash
[sudo] password for alex.callejas:
root@a13f3e75ea52:/#
root@a13f3e75ea52:/# ps
bash: ps: command not found
root@a13f3e75ea52:/# exit
exit
$

En este caso en particular, le indicamos que ejecutara, de forma interactiva bash, sin embargo se observa que la imagen del contenedor no tiene el comando ps. Esto puede ser debido a que cuando se creo la imagen, no se le incluyó dicho comando o comandos; esto se puede realizar para que la imagen del contenedor tenga una característica de seguridad en caso de ser necesario.

El proceso para generar la imagen de esta forma se profundizará en una sesión posterior.

10. Para revisar la configuración general del contenedor, ejecutamos

user@computer:$ sudo docker inspect test
[
{
"Id": "a13f3e75ea522646ca6b1b6a926cdf680b636924bdbf2c2942b7249acff0e513",
"Created": "2017-08-12T15:37:29.101171417Z",
"Path": "nginx",
"Args": [
"-g",
"daemon off;"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 6912,
"ExitCode": 0,
"Error": "",
"StartedAt": "2017-08-12T15:37:29.606735048Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:b8efb18f159bd948486f18bd8940b56fd2298b438229f5bd2bcf4cedcf037448",
"ResolvConfPath": "/var/lib/docker/containers/a13f3e75ea522646ca6b1b6a926cdf680b636924bdbf2c2942b7249acff0e513/resolv.conf",
...

Salida completa de la inspección: inspect_test.txt

También podemos obtener información de la inspección en formato de Go

user@computer:$ sudo docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' test
172.17.0.2
$ sudo docker inspect --format='{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}' test
172.17.0.1
$

11. Para listar las imágenes que hemos utilizado, ejecutamos

user@computer:$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/ubuntu latest ccc7a11d65b1 43 hours ago 120 MB
docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB
$

Creación de imágenes

12. La primer opción, aunque no la mejor nos comentaron, es utilizar una imagen básica de algún Sistema Operativo y adecuarla a nuestras necesidades. Por ejemplo, si queremos una imagen de vim, primeramente ejecutamos de forma interactiva una imagen base, para nuestro caso, de fedora e instalamos el paquete de forma tradicional

user@computer:$ sudo docker run -it fedora bash
[root@057ce3fd873e /]# dnf install vim
Fedora 25 - x86_64 2.7 MB/s | 50 MB 00:18
Fedora 25 - x86_64 - Updates 3.8 MB/s | 25 MB 00:06
Last metadata expiration check: 0:00:06 ago on Sat Aug 12 15:51:37 2017.
Dependencies resolved.
=======================================================================================
Package Arch Version Repository Size
=======================================================================================
Installing:
gpm-libs x86_64 1.20.7-9.fc24 fedora 36 k
perl-Carp noarch 1.40-365.fc25 fedora 29 k
perl-Exporter noarch 5.72-366.fc25 fedora 33 k
perl-libs x86_64 4:5.24.2-387.fc25 updates 1.5 M
vim-common x86_64 2:8.0.823-1.fc25 updates 6.7 M
vim-enhanced x86_64 2:8.0.823-1.fc25 updates 1.3 M
vim-filesystem x86_64 2:8.0.823-1.fc25 updates 35 k
which x86_64 2.21-1.fc25 fedora 46 k

Transaction Summary
=======================================================================================
Install 8 Packages

Total download size: 9.6 M
Installed size: 37 M
Is this ok [y/N]: y
Downloading Packages:
(1/8): which-2.21-1.fc25.x86_64.rpm 71 kB/s | 46 kB 00:00
(2/8): gpm-libs-1.20.7-9.fc24.x86_64.rpm 56 kB/s | 36 kB 00:00
(3/8): perl-libs-5.24.2-387.fc25.x86_64.rpm 1.0 MB/s | 1.5 MB 00:01
(4/8): perl-Carp-1.40-365.fc25.noarch.rpm 213 kB/s | 29 kB 00:00
(5/8): perl-Exporter-5.72-366.fc25.noarch.rpm 244 kB/s | 33 kB 00:00
(6/8): vim-enhanced-8.0.823-1.fc25.x86_64.rpm 524 kB/s | 1.3 MB 00:02
(7/8): vim-filesystem-8.0.823-1.fc25.x86_64.rpm 249 kB/s | 35 kB 00:00
(8/8): vim-common-8.0.823-1.fc25.x86_64.rpm 1.3 MB/s | 6.7 MB 00:05
---------------------------------------------------------------------------------------
Total 1.3 MB/s | 9.6 MB 00:07
warning: /var/cache/dnf/updates-87ad44ec2dc11249/packages/vim-enhanced-8.0.823-1.fc25.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID fdb19c98: NOKEY
Importing GPG key 0xFDB19C98:
Userid : "Fedora 25 Primary (25) <fedora-25-primary@fedoraproject.org>"
Fingerprint: C437 DCCD 558A 66A3 7D6F 4372 4089 D8F2 FDB1 9C98
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-25-x86_64
Is this ok [y/N]: y
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Installing : perl-Carp-1.40-365.fc25.noarch 1/8
Installing : perl-Exporter-5.72-366.fc25.noarch 2/8
Installing : perl-libs-4:5.24.2-387.fc25.x86_64 3/8
Installing : vim-filesystem-2:8.0.823-1.fc25.x86_64 4/8
Installing : vim-common-2:8.0.823-1.fc25.x86_64 5/8
Installing : which-2.21-1.fc25.x86_64 6/8
Installing : gpm-libs-1.20.7-9.fc24.x86_64 7/8
Installing : vim-enhanced-2:8.0.823-1.fc25.x86_64 8/8
Verifying : vim-enhanced-2:8.0.823-1.fc25.x86_64 1/8
Verifying : gpm-libs-1.20.7-9.fc24.x86_64 2/8
Verifying : which-2.21-1.fc25.x86_64 3/8
Verifying : vim-common-2:8.0.823-1.fc25.x86_64 4/8
Verifying : perl-libs-4:5.24.2-387.fc25.x86_64 5/8
Verifying : perl-Carp-1.40-365.fc25.noarch 6/8
Verifying : perl-Exporter-5.72-366.fc25.noarch 7/8
Verifying : vim-filesystem-2:8.0.823-1.fc25.x86_64 8/8

Installed:
gpm-libs.x86_64 1.20.7-9.fc24 perl-Carp.noarch 1.40-365.fc25
perl-Exporter.noarch 5.72-366.fc25 perl-libs.x86_64 4:5.24.2-387.fc25
vim-common.x86_64 2:8.0.823-1.fc25 vim-enhanced.x86_64 2:8.0.823-1.fc25
vim-filesystem.x86_64 2:8.0.823-1.fc25 which.x86_64 2.21-1.fc25

Complete!
[root@057ce3fd873e /]# exit
exit
$

Identificamos el nombre del contenedor, con ayuda de la terminal alterna

user@computer:$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
057ce3fd873e fedora "bash" 2 minutes ago Exited (0) About a minute ago infallible_fermat
a13f3e75ea52 nginx "nginx -g 'daemon ..." 16 minutes ago Up 16 minutes 0.0.0.0:80->80/tcp test
$

Y hacemos commit al cambio en la imagen, identificándola con un mensaje descriptivo y un nuevo nombre

user@computer:$ sudo docker commit -m "testvim" infallible_fermat imagenvim
sha256:663643920fdd5323b62b0e088a3233a4c95affd91b98b23e5ec25e8cddfd12c3
$

Al revisar las imágenes observamos

user@computer:$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
imagenvim latest 663643920fdd 12 seconds ago 452 MB
docker.io/ubuntu latest ccc7a11d65b1 43 hours ago 120 MB
docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB
registry.fedoraproject.org/fedora latest 7f17e6b4a386 6 weeks ago 232 MB
$

Existe una importante diferencia en el tamaño de la imagen base contra la imagen que creamos, esto depende de los paquetes que instalamos.

Al ejecutar vim dentro del contenedor, funciona correctamente

user@computer:$ sudo docker run -it imagenvim
[root@c4e11a2ac378 /]# vim

~
~
~
~
~ VIM - Vi IMproved
~
~ version 8.0.885
~ by Bram Moolenaar et al.
~ Modified by <bugzilla@redhat.com>
~ Vim is open source and freely distributable
~
~ Become a registered Vim user!
~ type :help register<Enter> for information
~
~ type :q<Enter> to exit
~ type :help<Enter> or <F1> for on-line help
~ type :help version8<Enter> for version info
~
~

:q!

[root@c4e11a2ac378 /]# exit
exit
$

Podemos revisar la diferencia de imágenes usando el id del contenedor:

user@computer:$ sudo docker ps -a
[sudo] password for alex.callejas:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c4e11a2ac378 imagenvim "bash" 41 minutes ago Exited (0) 40 minutes ago clever_meitner
057ce3fd873e fedora "bash" 44 minutes ago Exited (0) 42 minutes ago infallible_fermat
$
$ sudo docker diff c4e11a2ac378
C /root
C /root/.bash_history
A /root/.viminfo
$ sudo docker diff 057ce3fd873e
C /etc
C /etc/ld.so.cache
C /etc/pki/nssdb
C /etc/pki/nssdb/cert9.db
C /etc/pki/nssdb/key4.db
C /etc/profile.d
A /etc/profile.d/vim.csh
A /etc/profile.d/vim.sh
A /etc/profile.d/which2.csh
A /etc/profile.d/which2.sh
A /etc/vimrc
C /root
A /root/.bash_history
D /root/.pki
...

Salida completa de la diferencia: diff_imagenvim.txt

13. La otra forma de crear una imagen, es generando un archivo Dockerfile con las instrucciones de personalización del contenedor. Utilizando el mismo ejemplo, creamos el archivo Dockerfile (por convención, así debe llamarse) con la información necesaria

user@computer:$ vim Dockerfile
FROM fedora
RUN dnf update -y && dnf install -y vim
$

Y ejecutamos la construcción de la imagen

user@computer:$ sudo docker build -t imagenvim:2 .
Sending build context to Docker daemon 2.048 kB
Step 1/2 : FROM fedora
---> 7f17e6b4a386
Step 2/2 : RUN dnf update -y && dnf install -y vim
---> Running in 8b8e9e66ca8a
Last metadata expiration check: 0:00:18 ago on Sat Aug 12 16:01:33 2017.
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Upgrading:
curl x86_64 7.51.0-8.fc25 updates 307 k
dbus x86_64 1:1.11.16-1.fc25 updates 255 k
dbus-libs x86_64 1:1.11.16-1.fc25 updates 175 k
emacs-filesystem noarch 1:25.2-3.fc25 updates 66 k
expat x86_64 2.2.3-1.fc25 updates 86 k
file-libs x86_64 5.29-7.fc25 updates 497 k
glibc x86_64 2.24-9.fc25 updates 3.3 M
glibc-common x86_64 2.24-9.fc25 updates 879 k
glibc-langpack-en x86_64 2.24-9.fc25 updates 282 k
gnutls x86_64 3.5.14-1.fc25 updates 754 k
krb5-libs x86_64 1.14.4-8.fc25 updates 741 k
libcrypt-nss x86_64 2.24-9.fc25 updates 44 k
libcurl x86_64 7.51.0-8.fc25 updates 267 k
libdb x86_64 5.3.28-24.fc25 updates 750 k
libdb-utils x86_64 5.3.28-24.fc25 updates 139 k
libgcc x86_64 6.4.1-1.fc25 updates 95 k
libgcrypt x86_64 1.7.8-1.fc25 updates 435 k
libidn2 x86_64 2.0.3-1.fc25 updates 97 k
libsolv x86_64 0.6.28-5.fc25 updates 366 k
libsss_idmap x86_64 1.15.3-1.fc25 updates 83 k
libsss_nss_idmap x86_64 1.15.3-1.fc25 updates 81 k
nspr x86_64 4.15.0-1.fc25 updates 137 k
nss x86_64 3.31.0-1.1.fc25 updates 862 k
nss-softokn x86_64 3.31.0-1.0.fc25 updates 385 k
nss-softokn-freebl x86_64 3.31.0-1.0.fc25 updates 224 k
nss-sysinit x86_64 3.31.0-1.1.fc25 updates 61 k
nss-tools x86_64 3.31.0-1.1.fc25 updates 504 k
nss-util x86_64 3.31.0-1.0.fc25 updates 87 k
openldap x86_64 2.4.44-11.fc25 updates 352 k
pcre x86_64 8.41-1.fc25 updates 199 k
sqlite-libs x86_64 3.14.2-2.fc25 updates 454 k
sssd-client x86_64 1.15.3-1.fc25 updates 134 k
systemd x86_64 231-17.fc25 updates 2.8 M
systemd-libs x86_64 231-17.fc25 updates 421 k
systemd-pam x86_64 231-17.fc25 updates 178 k
tar x86_64 2:1.29-4.fc25 updates 814 k
vim-minimal x86_64 2:8.0.823-1.fc25 updates 525 k

Transaction Summary
================================================================================
Upgrade 37 Packages

Total download size: 18 M
Downloading Packages:
/usr/share/doc/file-libs/ChangeLog: No such file or directory
cannot reconstruct rpm from disk files
...

Verifying : vim-filesystem-2:8.0.823-1.fc25.x86_64 8/8

Installed:
gpm-libs.x86_64 1.20.7-9.fc24 perl-Carp.noarch 1.40-365.fc25
perl-Exporter.noarch 5.72-366.fc25 perl-libs.x86_64 4:5.24.2-387.fc25
vim-common.x86_64 2:8.0.823-1.fc25 vim-enhanced.x86_64 2:8.0.823-1.fc25
vim-filesystem.x86_64 2:8.0.823-1.fc25 which.x86_64 2.21-1.fc25

Complete!
---> 6306acd85190
Removing intermediate container 8b8e9e66ca8a
Successfully built 6306acd85190
$

Salida completa de la construcción de la imagen: build_imagenvim2.txt

Al ejecutar vim dentro del contenedor, funciona correctamente

user@computer:$ sudo docker run -it imagenvim:2
[root@aa039e84b63b /]# vim
~
~
~
~
~ VIM - Vi IMproved
~
~ version 8.0.885
~ by Bram Moolenaar et al.
~ Modified by <bugzilla@redhat.com>
~ Vim is open source and freely distributable
~
~ Become a registered Vim user!
~ type :help register<Enter> for information
~
~ type :q<Enter> to exit
~ type :help<Enter> or <F1> for on-line help
~ type :help version8<Enter> for version info
~
~

:q!

[root@aa039e84b63b /]#
[root@aa039e84b63b /]# uname -a
Linux aa039e84b63b 4.11.11-300.fc26.x86_64 #1 SMP Mon Jul 17 16:32:11 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
[root@aa039e84b63b /]# exit
exit
$

Al listar las imágenes, observamos

user@computer:$ sudo docker images
[sudo] password for alex.callejas:
REPOSITORY TAG IMAGE ID CREATED SIZE
imagenvim 2 6306acd85190 26 minutes ago 519 MB
imagenvim latest 663643920fdd 35 minutes ago 452 MB
docker.io/ubuntu latest ccc7a11d65b1 44 hours ago 120 MB
docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB
registry.fedoraproject.org/fedora latest 7f17e6b4a386 6 weeks ago 232 MB
$

A esta nueva imagen, le podemos asignar una etiqueta diferente para poder diferenciarla

user@computer:$ sudo docker tag imagenvim:2 axl/imagenvim2
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
axl/imagenvim2 latest 6306acd85190 28 minutes ago 519 MB
imagenvim 2 6306acd85190 28 minutes ago 519 MB
imagenvim latest 663643920fdd 37 minutes ago 452 MB
docker.io/ubuntu latest ccc7a11d65b1 44 hours ago 120 MB
docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB
registry.fedoraproject.org/fedora latest 7f17e6b4a386 6 weeks ago 232 MB
$

Podemos, además, guardar esta imagen como archivo

user@computer:$ sudo docker save -o imagenvim2 axl/imagenvim2
$ ls
Dockerfile imagenvim2
$ sudo file imagenvim2
imagenvim: POSIX tar archive
$ du -sh imagenvim2
509M imagenvim2
$

Con lo cual, podríamos portar la imagen a algún lugar, incluso por USB y exportarla. Para este ejemplo, primero eliminamos la imagen

user@computer:$ sudo docker rmi axl/imagenvim2
Untagged: axl/imagenvim2:latest
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
imagenvim 2 6306acd85190 2 days ago 519 MB
imagenvim latest 663643920fdd 2 days ago 452 MB
docker.io/ubuntu latest ccc7a11d65b1 4 days ago 120 MB
docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB
registry.fedoraproject.org/fedora latest 7f17e6b4a386 6 weeks ago 232 MB
$

Para cargar esta imagen en algún otro equipo, después de transferir dicha imagen, utilizamos el comando

user@computer:$ sudo docker load -i imagenvim2
Loaded image: axl/imagenvim2:latest
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
cosasaxl latest 2b76fbb9ebba 2 days ago 147 MB
axl/imagenvim2 latest 6306acd85190 2 days ago 519 MB
docker.io/ubuntu latest ccc7a11d65b1 4 days ago 120 MB
docker.io/nginx latest b8efb18f159b 2 weeks ago 107 MB
docker.io/debian latest a20fd0d59cf1 3 weeks ago 100 MB
registry.fedoraproject.org/fedora latest 7f17e6b4a386 6 weeks ago 232 MB
$

Volúmenes

La información de los contenedores es efímera, pero si requerimos que se monte algún directorio en particular o que los datos sean persistentes, utilizamos volúmenes.

14. Si requerimos que nuestro contenedor incluya algún directorio en particular, ejecutamos

user@computer:$ sudo docker run -it -v /directorio ubuntu bash
[sudo] password for alex.callejas:
root@46e6e1cc5fc1:/# ls
bin boot dev directorio etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@46e6e1cc5fc1:/# ls directorio/
root@46e6e1cc5fc1:/# touch directorio/hola
root@46e6e1cc5fc1:/# ls directorio/
hola
root@46e6e1cc5fc1:/# mkdir -p directorio/test
root@46e6e1cc5fc1:/# touch directorio/test/hola
root@46e6e1cc5fc1:/#
root@46e6e1cc5fc1:/# ls -l directorio/*
-rw-r--r--. 1 root root 0 Aug 12 02:24 directorio/hola

directorio/test:
total 0
-rw-r--r--. 1 root root 0 Aug 12 02:25 hola
root@46e6e1cc5fc1:/# exit
exit
$

En la terminal alterna, inspeccionamos el contenedor, para revisar los montajes

user@computer:$ sudo docker ps
[sudo] password for alex.callejas:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
540ee1c3cc95 ubuntu "bash" 25 seconds ago Up 24 seconds gracious_lamarr
$ sudo docker inspect --format='{{range .Mounts}}{{.Destination}}{{end}}' gracious_lamarr
/directorio
$ sudo docker inspect --format='{{range .Mounts}}{{.Source}}{{end}}' gracious_lamarr
/var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data
$

Por default, docker crea un directorio en el host para poder montarlo en el contenedor. Esto lo podemos revisar,como root, directamente en el host

user@computer:$ # ls -ld /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data
drwxr-xr-x. 2 root root 4096 Aug 12 21:32 /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data
# ls /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data
hola test
# ls /var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data/*
/var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data/hola

/var/lib/docker/volumes/4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323/_data/test:
hola
#

15. Si queremos que el contenedor utilice algún directorio del host en particular, ejecutamos

user@computer:$ mkdir directorio
$ ls
directorio Dockerfile imagenvim2
$ sudo docker run -it -v $PWD/directorio:/directorio ubuntu bash
root@4230a22ebcd5:/# ls
bin boot dev directorio etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@4230a22ebcd5:/# ls directorio/
ls: cannot open directory 'directorio/': Permission denied
root@4230a22ebcd5:/# touch directorio/hola
touch: cannot touch 'directorio/hola': Permission denied
root@4230a22ebcd5:/#

Se montó correctamente el directorio dentro del contenedor, pero no tenemos permiso de escritura debido a que el daemon de docker lo monta como root, como se observo en la inspección anterior. Para poder escribir, necesitamos indicarle al contenedor los permisos que requerimos, ejecutando

user@computer:$ sudo docker run -it -v $PWD/test:/prueba:ro ubuntu bash
root@59c188463618:/# ls
bin boot dev etc home lib lib64 media mnt opt proc prueba root run sbin srv sys tmp usr var
root@59c188463618:/# ls prueba/
ls: cannot open directory 'prueba/': Permission denied
root@59c188463618:/# cd prueba
root@59c188463618:/prueba# ls
ls: cannot open directory '.': Permission denied
root@59c188463618:/prueba# touch hola
touch: cannot touch 'hola': Read-only file system
root@59c188463618:/prueba# exit
exit
$

En la inspección se observa

user@computer:$ sudo docker inspect --format='{{range .Mounts}}{{.Source}}{{end}}' dazzling_franklin
/home/alex.callejas/Devel/docker/test
$ sudo docker inspect --format='{{range .Mounts}}{{.Destination}}{{end}}' dazzling_franklin
/prueba
$ sudo docker inspect --format='{{range .Mounts}}{{.Mode}}{{end}}' dazzling_franklin
rw
$ sudo docker inspect --format='{{range .Mounts}}{{.RW}}{{end}}' dazzling_franklin
true
$

16. Los volúmenes los podemos crear antes de usarlos, ejecutando

user@computer:$ sudo docker volume create --name myvol
myvol
$ sudo docker volume ls
DRIVER VOLUME NAME
local 4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323
local 5e76c5028ea86b1671837372c914d1603944dbf7d4676d0ee49740920756da24
local a909d99c5b8cab582d7c7a5c8e8dc21ed75f0a0ff8df15040906ab34fc67f142
local d840fde43be8d06fa06448478755f414de20c00705d27928ac5a8e0bba140d02
local myvol
$

Para asignarlo al contenedor, ejecutamos

user@computer:$ sudo docker run -it -v myvol:/stuff ubuntu bash
root@6b2116af2431:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv stuff sys tmp usr var
root@6b2116af2431:/# cd stuff/
root@6b2116af2431:/stuff# touch test{1..7}
root@6b2116af2431:/stuff# ls
test1 test2 test3 test4 test5 test6 test7
root@6b2116af2431:/stuff#

En la inspección observamos donde se creo el volumen y los archivos creados

user@computer:$ sudo docker inspect distracted_franklin | grep Mounts -A 11
"Mounts": [
{
"Type": "volume",
"Name": "myvol",
"Source": "/var/lib/docker/volumes/myvol/_data",
"Destination": "/stuff",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
$
# ls /var/lib/docker/volumes/myvol/_data
test1 test2 test3 test4 test5 test6 test7
#

17. Para eliminar el volumen, después de eliminar el contenedor, ejecutamos

user@computer:$ sudo docker volume rm myvol
myvol
$ sudo docker volume ls
DRIVER VOLUME NAME
local 4f3eb21be35f9b49ecc082592a47587253785ead6937f6352e434db2b8d6a323
local 5e76c5028ea86b1671837372c914d1603944dbf7d4676d0ee49740920756da24
local a909d99c5b8cab582d7c7a5c8e8dc21ed75f0a0ff8df15040906ab34fc67f142
local d840fde43be8d06fa06448478755f414de20c00705d27928ac5a8e0bba140d02
$

18. Si se requiere copiar archivos del host al contenedor, la mejor práctica es realizarlo desde su creación mediante Dockerfile, suponiendo que en el host tenemos un directorio archivos que deseamos tener en el contenedor dentro del directorio stuff, ejecutamos

user@computer:$ ls archivos/
notas1.txt notas2.txt
$ cat Dockerfile
FROM debian
RUN apt-get update && apt-get install vim -qqy
COPY ./archivos/ /stuff
$ sudo docker build -t cosasaxl .
[sudo] password for alex.callejas:
Sending build context to Docker daemon 556 kB
Step 1/3 : FROM debian
---> a20fd0d59cf1
Step 2/3 : RUN apt-get update && apt-get install vim -qqy
---> Running in d095c62569fa
Ign:1 http://deb.debian.org/debian stretch InRelease
Get:2 http://deb.debian.org/debian stretch-updates InRelease [88.5 kB]
Get:3 http://security.debian.org stretch/updates InRelease [62.9 kB]
Get:4 http://deb.debian.org/debian stretch Release [118 kB]
Get:5 http://deb.debian.org/debian stretch Release.gpg [2373 B]
Get:6 http://security.debian.org stretch/updates/main amd64 Packages [169 kB]
Get:7 http://deb.debian.org/debian stretch/main amd64 Packages [9497 kB]
Fetched 9938 kB in 5s (1799 kB/s)
Reading package lists...
debconf: delaying package configuration, since apt-utils is not installed
...
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/editor (editor) in auto mode
---> 56193462f153
Removing intermediate container d095c62569fa
Step 3/3 : COPY ./archivos/ /stuff
---> 83e969244bce
Removing intermediate container 0a687e1b1998
Successfully built 83e969244bce
$ sudo docker run -it cosasaxl bash
root@7f3d34dfa53a:/# ls
bin   dev  home  lib32 libx32 mnt  proc  run srv sys  usr
boot  etc  lib lib64 media opt  root  sbin  stuff tmp  var
root@7f3d34dfa53a:/# ls stuff/
notas1.txt notas2.txt
root@7f3d34dfa53a:/# exit
exit
$

19. Suponiendo que necesitamos que el contenedor ejecute un script al arrancarlo, lo construimos con la opción ENTRYPOINT 

user@computer:$ cat entrypoint.sh
#!/bin/bash
ls -la
echo "Hola desde entrypoint"
$ cat Dockerfile
FROM debian
RUN apt-get update && apt-get install vim -qqy
COPY ./archivos/ /stuff
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh
$ ls
archivos Dockerfile entrypoint.sh
$ sudo docker build -t cosasaxl .
[sudo] password for alex.callejas:
Sending build context to Docker daemon 557.1 kB
Step 1/5 : FROM debian
---> a20fd0d59cf1
Step 2/5 : RUN apt-get update && apt-get install vim -qqy
---> Using cache
---> 56193462f153
Step 3/5 : COPY ./archivos/ /stuff
---> Using cache
---> 83e969244bce
Step 4/5 : COPY entrypoint.sh /entrypoint.sh
---> e403afe2511c
Removing intermediate container b0c28c21c8ff
Step 5/5 : ENTRYPOINT /entrypoint.sh
---> Running in 4ad3f139001d
---> 2b76fbb9ebba
Removing intermediate container 4ad3f139001d
Successfully built 2b76fbb9ebba
$ sudo docker run -it cosasaxl bash
total 68
drwxr-xr-x. 1 root root 4096 Aug 12 17:18 .
drwxr-xr-x. 1 root root 4096 Aug 12 17:18 ..
-rwxr-xr-x. 1 root root 0 Aug 12 17:18 .dockerenv
lrwxrwxrwx. 1 root root 7 Jul 23 00:00 bin -> usr/bin
drwxr-xr-x. 2 root root 4096 Jul 13 13:04 boot
drwxr-xr-x. 5 root root 360 Aug 12 17:18 dev
-rwxrwxr-x. 1 root root 49 Aug 12 17:14 entrypoint.sh
drwxr-xr-x. 1 root root 4096 Aug 12 17:18 etc
drwxr-xr-x. 2 root root 4096 Jul 13 13:04 home
lrwxrwxrwx. 1 root root 7 Jul 23 00:00 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Jul 23 00:00 lib32 -> usr/lib32
lrwxrwxrwx. 1 root root 9 Jul 23 00:00 lib64 -> usr/lib64
lrwxrwxrwx. 1 root root 10 Jul 23 00:00 libx32 -> usr/libx32
drwxr-xr-x. 2 root root 4096 Jul 23 00:00 media
drwxr-xr-x. 2 root root 4096 Jul 23 00:00 mnt
drwxr-xr-x. 2 root root 4096 Jul 23 00:00 opt
dr-xr-xr-x. 337 root root 0 Aug 12 17:18 proc
drwx------. 2 root root 4096 Jul 23 00:00 root
drwxr-xr-x. 4 root root 4096 Jul 23 00:00 run
lrwxrwxrwx. 1 root root 8 Jul 23 00:00 sbin -> usr/sbin
drwxr-xr-x. 2 root root 4096 Jul 23 00:00 srv
drwxr-xr-x. 2 root root 4096 Aug 12 17:09 stuff
dr-xr-xr-x. 13 root root 0 Aug 12 14:27 sys
drwxrwxrwt. 1 root root 4096 Aug 12 17:09 tmp
drwxr-xr-x. 1 root root 4096 Jul 23 00:00 usr
drwxr-xr-x. 1 root root 4096 Jul 23 00:00 var
Hola desde entrypoint
$

En un siguiente post, cuando nos den la segunda parte del curso: Intermedio, les compartiré de igual forma mis notas.

P.D.: Hace ya algún tiempo, aquí en el blog, había publicado una muy buena introducción a docker [ver] 😉

Espero les sirva…