Introducción a Docker

Gustavo Morales

Contenido

  1. ¿Cómo funciona Docker?
  2. Images, Docker hub y Dockerfile
  3. Containers
  4. Network
  5. Volumes
  6. Docker compose
  7. Swarm mode

¿Como funciona Docker?

VM

Docker container

Virtual Machines vs Docker containers

¿Como se ejecuta en el sistema?

Es un proceso

¿Que es Docker?

Docker

  • docker
  • docker version
  • docker info

Images

Docker images

  • Son los binarios y dependencias
  • La información y como ejecutarla
  • NO es un sistema operativo
  • NO es un kernel ni tampoco kernel modules

Docker images are the basis of containers. An Image is an ordered collection of root filesystem changes and the corresponding execution parameters for use within a container runtime. An image typically contains a union of layered filesystems stacked on top of each other. An image does not have state and it never changes.

Docker hub

https://hub.docker.com

Docker images

docker pull [image][:tag]
docker image ls
docker image inspect [name]
docker image history [name]
docker image build -t [name] [DockerfilePath]
docker pull nginx

Docker images

FROM nginx:latest
COPY monster-battle/src /usr/share/nginx/html
git clone https://github.com/gmoralesc/monster-battle

Dockerfile

docker image build -t pokemon .
docker container run -p 80:80 pokemon

Docker images

Crear una imagen llamada node_auth_simple

1. (FROM) A partir de la imagen node:14

2. (WORKDIR) Establecer el directorio de trabajo /usr/src/app

3. (RUN) Ejecutar git clone https://github.com/gmoralesc/node-auth --branch develop .

5. (COPY) Copiar el archivo .env

6. (RUN) Ejecutar el comando npm install

6. (EXPOSE) Exponer el puerto 3000

7. (CMD) Establecer el comando npm start

B. Dockerfile

C. Crear el contenedor

Ejecutar la app en un contenedor modo detach en el puerto 3000

Instrucciones en https://github.com/gmoralesc/node-auth

SERVER_HOSTNAME=0.0.0.0

SERVER_PORT=3000

JWTSECRET=rickandmorty

A. .env

Docker images

FROM node:16
WORKDIR /usr/src/app
RUN git clone https://github.com/gmoralesc/node-auth --branch develop .
COPY .env .
RUN npm install
EXPOSE 3000
CMD ["npm","start"]

Dockerfile

Containers

Docker containers

Es una instancia de una imagen corriendo como proceso en el sistema

  • docker container --help
    
  • docker container run
  • docker container ls
  • docker container stop
  • docker container start
  • docker container logs

Docker containers

  1. Busca la imagen de nginx en el repositorio local
  2. Si no la encuentra descarga la imagen de Docker hub y la almacena en el repositorio local
  3. Crea el contenedor en base a la imagen de nginx
  4. Expone el puerto 80 (guest) y 80 (host)
  5. Le asigna un nombre aleatorio
docker container run --publish 80:80 nginx

Docker containers

docker container run --publish 80:80 --detach nginx
docker container ls
docker container stop [hash]
docker container ls -a
docker container run -p 80:80 -d --name web nginx
docker container logs web
docker container top web
docker container rm [-f] web

Docker containers

De las siguientes imágenes en sus respectivos puertos 

  • nginx (puerto 80:80)
  • httpd (puerto 8080:80)
    
  • mysql (puerto 3306:3306)
  • Cada uno de estos en detach mode (-d) 
  • Especificar un nombre (--name) para cada uno de ellos
  • Para mysql establecer la variable de entorno (-e) MYSQL_RANDOM_ROOT_PASSWORD=yes
  • Listar los contenedores corriendo
  • Probar los servidores Web en el navegador
  • Detener todos los contenedores y ver el listado de contenedores
  • Verificar en los logs cual fue el password asignado para mysql

A. Ejecutar los contenedores

B. Administrar los contenedores

Docker containers

  • docker container run -p 80:80 -d --name nginx nginx
  • container run -p 8080:80 -d --name apache httpd
    
  • docker container run -p 3306:3306 -d -e MYSQL_RANDOM_ROOT_PASSWORD=yes --name mysql mysql
  • docker container ls
  • docker container logs mysql
     

A. Ejecutar los contenedores

B. Administrar los contenedores

Docker containers

docker container top [name]
docker container inspect [name]
docker container stats

Docker containers

docker container run -it 
docker container exec
docker container run -it --name alpha ubuntu
docker container start -ai alpha
docker container start alpha
docker container exec alpha ls -l
docker container stop alpha
docker container run -it alpine bash
docker container run -it alpine sh

Docker containers

  • centos:7
  • ubuntu:14.04
  • Cada uno en una consola diferente
  • Agregar la opción --rm para cuando se termine de utilizar el contenedor se remueva automáticamente
  • centos: yum install curl
  • ubuntu: apt-get update && apt-get install curl

A. Ejecutar los contenedores

B. Instalar cURL

  • curl --version

C. Comprobar la versión de cURL

Docker containers

  • docker container run -it --name beta centos:7
  • docker container run -it --rm --name delta ubuntu:14.04
  • centos: yum install curl
  • ubuntu: apt-get update && apt-get install curl

A. Ejecutar los contenedores

B. Instalar cURL

  • curl --version

C. Comprobar la versión de cURL

Networks

Docker networks

Docker crea una red virtual donde están todos los contenedores por defecto

docker network ls
docker network inspect
docker network create --driver
docker network connect
docker network disconnect

Docker networks DNS

docker network create webnetwork
docker container run -d --name beta --network webnetwork alpine sleep 1d
docker container run -d --name gamma --network webnetwork alpine sleep 1d
docker exec -it beta apk add iputils
docker inspect gamma | grep IPAddress
docker exec -it container1 ping [IP]

Docker networks DNS

  • Las direcciones IP son variables y pueden cambiar
  • Una de las mejores practicas para encontrar los contenedores son los DNS
  • El servicio de DNS esta incluido en Docker

Docker networks DNS

  • Crear una red

  • Crear 3 contenedores basados en la imagen nginx con la opción --net-alias webserver, en la misma red y ejecutarlos en segundo plano

  • imagen: alpine 
    comando: apk add curl
    curl -s my-webserver
    
    

A. Crear y ejecutar los contenedores

B. Escanear los contenedores en la red

Docker networks DNS

  • docker network create my_custom_network
  • docker run -d --network my_custom_network --net-alias my-webserver nginx
  • docker run -d --network my_custom_network --net-alias my-webserver nginx
  • docker run -d --network my_custom_network --net-alias my-webserver nginx
  • docker run -it --network my_custom_network alpine sh
    
  • apk add curl
  • curl -s my-webserver

A. Crear y ejecutar los contenedores

B. Escanear los contenedores en la red

Volumes

Docker volumes

  • Los Docker containers deberian ser inmutables
  • ¿Donde quedan los datos persistentes?
  • Los Docker Volumes y Bind Mounts es la solución

 

MySQL Official Image

docker image pull mysql
docker container run -d --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=yes mysql
docker container inspect mysql

Docker volumes

docker volume ls
docker container run -d --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=yes -v mysql-data:/var/usr/mysql mysql
docker container inspect mysql
docker volume ls
docker volume inspect [id]

Docker volumes

Ejecutar un contenedor a partir con las siguientes caracteristicas:

  • image: postgres:14

  • volume: pg-data

  • Detach mode (-d)

 

A. Crear contenedor inicial

B. Comprobar el entorno

C. Reutilizar el volume

Verificar los logs para garantizar que imagen se ejecutó correctamente y luego detener el contenedor

Ejecutar otro contenedor con las mismas características del primero pero esta vez utilizar la imagen de postgres:14.9 y debe utilizar el mismo volumen creado anteriormente.

Si es posible interactuar con el primer contenedor y guardar datos, luego comprobar que los datos no se perdieron con el segundo contenedor

Docker volumes

  • docker run --name pg-14 -e POSTGRES_PASSWORD=mysecretpassword -v pg-data:/var/lib/postgresql/data -d postgres:14
  • docker exec -it pg-14 psql -U postgres -c "CREATE DATABASE testdb;"

A. Crear contenedor inicial

B. Comprobar el entorno

C. Reutilizar el volume

  • docker stop pg-14
  • docker rm pg-14
  • docker run --name pg-14.9 -e POSTGRES_PASSWORD=mysecretpassword -v pg-data:/var/lib/postgresql/data -d postgres:14.9
  • docker exec -it pg-14.9 psql -U postgres -l

Docker bind mounting

  • Crea un acceso de los datos locales en el sistema al container
  • Las dos partes apuntan al mismo archivo
  • Si existe una sobre-escritura gana el sistema
  • Se utiliza siempre con
docker container run -v [absolute_path]:[image_path]

Docker bind mounting

docker container run -d -p 80:80 -v ./src/:/usr/share/nginx/html pokemon2

Tomando como referencia la imagen de my_website creada anteriormente y estando en el directorio que contiene el directorio academia

Realizar cambios en el código fuente y comprobarlos en el navegador

Compose

Docker compose

  • Esta conformado por un Archivo de configuración (docker-compose.yml) y la herramienta de composición (docker-compose)
  • Relacionar los contenedores
  • Guardar todas las opciones de ejecución
  • Crear con una sola linea de comando todo un entorno de desarrollo

docker-compose.yml

  • Version 1, 2, 3
version: 3.3
services:
  service-name:
    image:
    ports:
    environment: 
    volumes:
  service-name:
volumes:
networks:

docker-compose

  • docker-compose up
  • docker-compose down

docker-compose up nunca reconstruye las imágenes en ese caso es necesario utilizar docker-compose build

docker-compose

FROM node:16
WORKDIR /usr/src/app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["npm", "run", "dev"]

C. Dockerfile

D. docker-compose.yml

Crear un manifesto con los siguientes servicios:

  • db: basado en la imagen mongo (3.6.18)
  • node-auth: darle nombre a la imagen, construir la imagen con el Dockerfile, con los puerto asignados y la opción depends_on de db

A. Descargar proyecto

git clone https://github.com/gmoralesc/node-auth
mkdir -p node-auth/node_modules
SERVER_HOSTNAME=0.0.0.0
SERVER_PORT=3000
DATABASE_URL=mongodb://db/nodeauth
JWTSECRET=rickandmorty

B. .env
(Crear dentro del directorio de node-auth)

docker-compose

FROM node:16
WORKDIR /usr/src/app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["npm", "run", "dev"]

C. Dockerfile

A. Descargar proyecto

git clone https://github.com/gmoralesc/node-auth
SERVER_HOSTNAME=0.0.0.0
SERVER_PORT=3000
DATABASE_URL=mongodb://db/nodeauth
JWTSECRET=rickandmorty

B. .env

docker-compose

D. docker-compose.yml

version: '3.1'
services:
  server:
    build: .
    ports:
      - '3000:3000'
    depends_on:
      - db
  db:
    image: mongo:3.6.18
    ports:
      - '27017:27017'

docker-compose (editable)

...
    volumes:
      - ./node-auth:/usr/src/app
      - /usr/src/app/node_modules

A. Editar docker-compose.yml

B. Editar Dockerfile

FROM node:16
WORKDIR /usr/src/app
COPY package.json .
COPY package-lock.json .
COPY .env .
RUN npm install
EXPOSE 3000
CMD ["npm", "run", "dev"]
docker-compose up -- build

C. Construir y ejecutar

docker-compose (editable)

version: '3.1'
services:
  server:
    build: .
    ports:
      - '3000:3000'
    volumes:
      - ./:/usr/src/app
      - /usr/src/app/node_modules
    depends_on:
      - db
  db:
    image: mongo:3.6.18
    ports:
      - '27017:27017'

A. docker-compose.yml

docker-compose (editable)

B. Dockerfile

FROM node:16
WORKDIR /usr/src/app
COPY package.json .
COPY package-lock.json .
COPY .env .
RUN npm install
EXPOSE 3000
CMD ["npm", "run", "dev"]
docker-compose up -- build

C. Construir y ejecutar

Swarm mode

Introducción a Docker

By Gustavo Morales

Introducción a Docker

  • 511