Saltar a contenido

Docker

¿Qué es Docker?#

Es una herramienta que permite desplegar aplicaciones en contenedores de forma rápida y portable. Los términos que más escucharemos cuando hablamos de Docker serán "contenedores" e "imágenes".

Docker se encuentra disponible para las principales plataformas, como Windows, Linux o MacOS. La máquina que aloja el servicio "Docker" se denomina Docker Host. Dentro de Docker podemos destacar tres conceptos.

  • Docker Daemon: representa el servidor de Docker.
  • Rest API: utilizado para la comunicación bidireccional entre cliente y servidor.
  • Docker CLI (Command Line Interface): representa el cliente de Docker.

*A pesar de que se haya mencionado la línea de comandos como cliente Docker, también existe entorno gráfico para interactuar con el servidor Docker.

Cuando interactuamos con contenedores o imágenes, lo hacemos a través del cliente de Docker, con lo cual nos interesa saber que es lo que podemos gestionar.

Docker Compose#

Es una herramienta que nos ayuda a orquestar contenedores en Docker, gestionar los diferentes contenedores de los que depende una aplicación. Existen aplicaciones que para su correcto funcionamiento dependen de varios servicios, para seguir con la simplicidad de "un servicio = un contenedor", Docker Compose nos permitirá administrar los diferentes contenedores de forma grupal.

Docker Compose trabaja con ficheros de tipo yaml, en los que se definen los contenedores, volúmenes, redes, etc. Después de completar el fichero, docker-compose como comando se encarga de la lectura del fichero y lanzar todos los contenedores definidos en dichero fichero.

Durante la instalación de Docker-CE esta herramienta no se instala, por lo que será necesaria la instalación de forma independiente. En la documentación oficial se encuentran diferentes guías para la instalación en los diferentes Sistemas Operativos.

En la máquina actual, en la que estamos trabajando bajo Linux, la instalación se haría del siguiente modo:

  1. Descargamos Docker-Compose.
  2. sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    
  3. Aplicar permisos de ejecución al ejecutable que hemos descargado.
  4. sudo chmod +x /usr/local/bin/docker-compose
    

Comenzando con Docker Compose#

El nombre del fichero que debemos utilizar es docker-compose.yml, donde definiremos los diferentes contenedores.

Este fichero cuenta con cuatro grandes partes:

  1. Version (obligatorio): para saber que número de versión (Docker-Compose) debemos establecer, buscamos en la documentación cual es la última versión, suele ser la que se recomienda utilizar.
  2. Services (obligatorio): los servicios hacen referencia a los contenedores. En primera instancia definimos los nombres de cada servicio (podemos elegir el que queramos), y debajo de ellos irán los parámetros que hacen referencia al propio contenedor, como el nombre del contenedor, la imagen a la que hace referencia, puertos, variables de entorno, etc.
  3. Volumes (opcional):
    • Volúmenes nombrados: funcionan del mismo modo que ejecutando docker run. Lo que hacemos es definir en primer lugar el volumen que crearíamos con la instrucción docker volume create en "volumes" con el nombre que queramos. A continuación lo definimos dentro del servicio.
    • version: '3'
      services:
        web:
          image: nginx
          container_name: nginx-prueba
          volumes:
            - "html:/usr/share/nginx/html"
      volumes:
        html:
      
    • Volúmenes host: no necesitamos la parte volumes dentro del fichero docker-compose.yml sino que directamente en el contenedorlo podemos parametrizar.
    version: '3'
    services:
      web:
        image: nginx
        container_name: nginx-prueba
        volumes:
          - "/home/miusuario/html:/usr/share/nginx/html"
    
  4. Networks (opcional):
    • Red Host: es importante establecer la versión 3.4 para que funcione correctamente. Para que funcione es necesario añadir build, y además añadir el contexto, que hace referencia a un directorio que contenga un Dockerfile o una url a un repositorio git. Si establecemos la ruta relativa hace referencia a la ubicación del archivo de composición.
    • version: '3.4'
      services:
        web:
          build:
            context: .
            network: host
          image: nginx
          container_name: nginx-prueba
          ports:
            - "8181:80"
      
    • Creación de una nueva red con subnet. Aún no se permite establecer gateway.
    version: '3'
    services:
      web:
        image: nginx
        container_name: nginx-prueba
         ports:
          - "8181:80"
        networks:
          red-prueba:
            - ipv4_address: 192.168.50.10
    networks:
      red-prueba:
        ipam:
          driver: default
          config:
            - subnet: "192.168.50.0/24"
    
    En cuanto a las redes, cuando ejecutamos el comando docker-compose up -d se genera una red específica para docker-compose. Si no definimos una red, la red utilizada será la red por defecto (docker-compose_default). Cuando se crea la red, el nombre que es otorgado "directorioactual_nombredelared". Es posible modificar la parte del nombre que hace referencia al "directorioactual", pasando el parámetro -p. Por lo tanto si nuestro directorio actual se denomina docker-compose y queremos que el prefijo sea por ejemplo dcprueba ejecutaríamos el siguiente comando:
    #Modificar el nombre de red a "dcprueba_default"
    
    docker-compose -p dcprueba up -d
    

Por otro lado, tenemos dos partes importantes que se utilizan a la hora de crear contenedores.

  • Variables de entorno: estas se pueden definir de dos modos.
environment:
  - "VARIABLES1=docker"
environment:
  - variables.env
  • Command: se utiliza para establecer un CMD al contenedor.
commmand: mkdir /bin/bash

El comando docker-compose se encarga de realizar un proceso similar que el comando docker run, pero en este caso los diferentes parámetros se encuentran definidos en un fichero. Por lo tanto, las políticas de reinicio o la limitación de recursos también se pueden definir.

  • Políticas de reinicio:
#Reinicio siempre
restart: always

#Reinicio hasta que lo detengamos de forma manual
restart: unless-stopped

#Únicamente se reinicia el contenedor en caso de que haya habido un fallo
restart: on-failure
  • Limitar recursos:
#Limitar memoria
mem_limit: 20m

#Cpu
cpuset: "0"

Otras de las directivas relevantes de este fichero es depends_on, la cual hace referencia a las dependencias que tiene se contenedor respecto a los que se incluyan en esta directiva.

version: '3'
services:
  web:
    image: nginx
    container_name: nginx-prueba
    depends_on: db
  db:
  image: postgres
  container_name: nginx-database

El último paso será conocer como podemos eliminar un contenedor creado con la herramienta Docker-Compose. Para ello debemos ejecutar el siguiente comando, situados en el directorio donde se encuentra el fichero yaml.

docker-compose down

El comando anterior sigue el siguiente proceso:

  1. Detiene el contenedor.
  2. Elimina el contenedor.
  3. Elimina la red que ha creado por defecto.

Docker-compose build#

Ya conocemos el comando docker build, es el encargado de crear imágenes. El comando docker-compose build tiene un funcionamiento similar, se encarga de generar una imagen a partir de la definición de build en el fichero yaml. Esta imagen será utilizada como imagen base en la creación del contenedor.

Para que se construya una imagen, sabemos que necesitamos un fichero Dockerfile, en el cual se encuentran las capas para la construcción de una imagen. En la sentencia build nos encontramos con dos parámetros importantes.

  • Context: se indica la ruta donde se encuentra el Dockerfile que utilizaremos para crear la imagen. Si se encuentra en el mismo directorio se utilizará el punto (.).
  • Dockerfile: el nombre del fichero si este es diferente al nombre por defecto (Dockerfile).
version: '3'
services:
  web:
    container_name: web
    image: web-test
    build:
      context: .
      dockerfile: Dockerfile1

*Si el nombre que hace referencia al Dockerfile no se ha modificado, podemos obviar estos dos parámetros.

version: '3'
services:
  web:
    container_name: web
    image: web-test
    build: .

Otros conceptos#

Fuentes#