¿Qué es Docker?

Docker es una plataforma para desarrollar, desplegar y ejecutar aplicaciones usando contenedores.

Los principales usuarios de Docker son:

  • desarrolladores
  • administradores de sistemas

Conceptos básicos

Una imágen es un paquete ejecutable, que incluye todo lo necesario para ejecutar una aplicación:

  • el código
  • a runtime
  • bibliotecas
  • variables de ambiente
  • archivos de configuración

Un contenedor es una instancia ejecutable de una imágen, esto es, una imágen con estado.

Contenedores vs Máquinas Virtuales

Un contenedor se ejecuta de forma nativa en Linux y comparte el núcleo del sistema operativo con otros contenedores.

Un contenedor ejecuta un proceso discreto (o varios), tomando no más memoria que otro ejecutable.

Contenedores vs Máquinas Virtuales

Por el contrario, una máquina virtual ejecuta un sistema operativo completo con acceso virtual a los recursos de la máquina a través de un hipervisor.

En general, las VMs proveen un ambiente con más recursos de los requeridos por la mayoría de las aplicaciones.

Ejecutando un contenedor

Ejecutar Python 3.6 en un contenedor.

docker run -it python:3.6
Python 3.6.8 (default, Jan  9 2019, 04:19:48) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>  
>>> print("Hello world!")
Hello world!
>>>

Lista de imágenes

Listar las imágenes locales.

docker images
REPOSITORY  TAG     IMAGE ID      CREATED         SIZE
python      3.6     55fb8aca33df  2 months ago    922MB

Ejemplo 1

Configurar el comando pip para instalar los paquetes de Python desde un repositorio alternativo.

cat "Dockerfile"
FROM python:3.6

COPY pip.conf /etc/pip.conf
ls
Dockerfile  pip.conf

Construcción de una imágen

Construir la imágen del Ejemplo 1.

docker build -t "ejemplo1" .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM python:3.6
 ---> 55fb8aca33df
Step 2/2 : COPY pip.conf /etc/pip.conf
 ---> 509d9cc817f2
Successfully built 509d9cc817f2
Successfully tagged ejemplo1:latest

Ejemplo 2

Actualizar el comando pip e instalar Django.

cat "Dockerfile"
FROM ejemplo1

RUN pip install --upgrade pip

RUN pip install Django==1.11.10
docker build -t "ejemplo2" .

Historia de una imágen

Mostrar la historia de construcción de la imágen del Ejemplo 2.

docker history "ejemplo2"
IMAGE         CREATED BY                                      SIZE
7d1897368444  /bin/sh -c pip install Django==1.11.10          23.6MB              
1def5a96ce8f  /bin/sh -c pip install --upgrade pip            10.1MB             
509d9cc817f2  /bin/sh -c #(nop) COPY file:c3cdfdbb4b7f169e…   175B                
55fb8aca33df  /bin/sh -c #(nop)  CMD ["python3"]              0B  
...

Ejemplo 3

Crear un imágen con la aplicación.

cat "Dockerfile"
FROM ejemplo2

COPY app /home/app
WORKDIR /home/app

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
EXPOSE 8000

Ejecutando un servicio

Ejecutar la imágen de la aplicación.

Probar si la aplicación funciona:

  • acceder a http://localhost:8050.
docker run --name ejemplo3 -p 8050:8000 ejemplo3
[15/Apr/2019 14:17:15] "GET / HTTP/1.1" 200 376
[15/Apr/2019 14:17:20] "GET /touch? HTTP/1.1" 302 0
[15/Apr/2019 14:17:20] "GET / HTTP/1.1" 200 376

Detener el contenedor:

  • usar Ctrl+C en los sistemas Unix

Listar todos los contenedores

Listar los contenedores en ejecución y los contenedores detenidos

docker ps --all
CONTAINER ID        IMAGE                               
df526a2a7d95        ejemplo3

COMMAND                  CREATED             
"python manage.py ru…"   2 minutes ago

STATUS                       PORTS            NAMES
Exited (0) 15 seconds ago                    ejemplo3

Eliminar un contenedor

Eliminar el contenedor con nombre ejemplo3.

docker rm ejemplo3

Al eliminar el contenedor se pierde el estado de la aplicación del Ejemplo 3:

  • Se pierden los datos almacenados en la base de datos.

Ejemplo 4

Almacenar el directorio de la aplicación en un volúmen.

cat "Dockerfile"
FROM ejemplo2

COPY app /home/app
WORKDIR /home/app

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
EXPOSE 8000

VOLUME /home/app/

Ahora, la base de datos almacenada en el archivo /home/app/db.sqlite3 no se pierde al eliminar el contenedor.

Docker Volume

Permite almacenar el contenido de un directorio fuera del contenedor.

El contenido de un volúmen no se pierde al eliminar el contenedor.

Un volúmen puede ser compartido por varios contenedores y sistemas operativos.

¿Cómo copiar archivos?

Crear una copia de la base de datos de la aplicación.

docker cp ejemplo4:/home/app/db.sqlite3 .

El comando cp permite copiar archivos desde el sistema anfitrión hacia un contenedor y viceversa.

Ejemplo 5

Montar el directorio del código de la aplicación dentro del contenedor.

docker create -v app:/home/app -p 8050:8000 --name ejemplo3_1 ejemplo3
  • Si se modifica el código en el sistema anfitrión, el servidor de desarrollo que se ejecuta en el contenedor ve los cambios.

  • Si el servidor de desarrollo modifica la base de datos, el archivo de la base de datos en el sistema anfitrión cambia.

Bind Mount

Permite montar un directorio en el sistema de archivos del contenedor.

El directorio puede estar ubicado en el sistema de archivos del sistema anfitrión.

Ejemplo 6

cat Dockerfile
FROM ubuntu:bionic

WORKDIR /home

COPY hello.sh .
RUN chmod u+x hello.sh

CMD ./hello.sh
cat hello.sh
#!/bin/bash

echo Hello $NAME

Variables de ambiente

La variable de ambiente NAME no tiene valor.

docker run --rm ejemplo6
Hello

Definir un valor para la variable NAME

docker run --rm -e NAME=Pepe ejemplo6
Hello Pepe

Iniciar un contenedor

El comando start inicia un contenedor.

docker start ejemplo3_1
ejemplo3_1

Contenedores en ejecución

Listar los contenedores en ejecución.

docker ps
CONTAINER ID        IMAGE         COMMAND 
6c267469e48e        ejemplo3      "python manage.py ru…"

CREATED             STATUS              
6 minutes ago       Up 9 seconds 

PORTS                           NAMES
0.0.0.0:8050->8000/tcp          ejemplo3_1

Detener un contenedor

El comando stop detiene un contenedor.

docker stop ejemplo3_1
ejemplo3_1

Bibliografía