Categorías Programación Etiquetas , ,

¿Cómo utilizar Docker y Dockerfile para desplegar aplicaciones en la nube?

Solomon Hykes, un ingeniero de software francés, fundó dotCloud en 2010, una plataforma como servicio (PaaS) que proporcionaba a los desarrolladores un entorno preconfigurado para desplegar, gestionar y escalar aplicaciones web. Durante su trabajo en dotCloud, Hykes y su equipo desarrollaron Docker, una herramienta que permite empaquetar aplicaciones y sus dependencias en contenedores, garantizando una ejecución consistente en cualquier entorno. Docker se lanzó como un proyecto de código abierto en 2013, y su éxito transformó la industria del software, facilitando la adopción de prácticas de desarrollo ágiles como la integración continua (CI) y el despliegue continuo (CD).

En el corazón de Docker se encuentra el Dockerfile, un archivo de texto que define cómo construir una imagen de Docker mediante una serie de instrucciones. Estas instrucciones incluyen la especificación de la imagen base, la copia de archivos, la ejecución de comandos y la configuración de la aplicación.

Un Dockerfile es un archivo de texto con una secuencia de comandos (instrucciones) que Docker utiliza para construir una imagen. Cada instrucción en el Dockerfile crea una capa en la imagen. Las capas son fundamentales para la eficiencia de Docker, ya que permiten compartir y reutilizar partes de las imágenes entre diferentes contenedores.

Los Dockerfiles sirven para definir el entorno en el que se ejecutará una aplicación, asegurando que siempre sea el mismo, independientemente de dónde se ejecute. Esto incluye:

➜ Sistema operativo base

➜ Dependencias de la aplicación

➜ Configuración y scripts de inicio

➜ Variables de entorno

La consistencia y la reproducibilidad son claves en el despliegue de aplicaciones. Con un Dockerfile, podemos garantizar que el entorno de producción sea idéntico al de desarrollo. Esto reduce errores y facilita la integración continua (CI) y el despliegue continuo (CD), automatizando el proceso de construcción, prueba y despliegue de aplicaciones.

Docker y los Dockerfiles son especialmente útiles para:

• Microservicios: Facilitan el despliegue y la gestión de aplicaciones compuestas por múltiples servicios.

• Aplicaciones en la nube: La portabilidad de Docker permite mover aplicaciones entre distintos proveedores de nube sin cambios significativos.

• Entornos de desarrollo consistentes: Los desarrolladores pueden trabajar en un entorno idéntico al de producción.

• Aplicaciones legacy: Encapsular aplicaciones antiguas en contenedores para facilitar su despliegue en nuevas infraestructuras.

Imágenes oficiales de Docker

Las imágenes oficiales de Docker son mantenidas por Docker Inc. y la comunidad, proporcionando bases estables y seguras para construir aplicaciones. En nuestros ejemplos, utilizamos imágenes oficiales como node:14 para una aplicación Node.js y python:3.9 para una aplicación Python con Flask.

Ejemplo 1: aplicación Node.js

El Dockerfile para una aplicación Node.js permite empaquetar la aplicación y sus dependencias en un contenedor, asegurando un entorno de ejecución consistente. Utiliza una imagen base oficial de Node.js (FROM node:14), establece el directorio de trabajo (WORKDIR /usr/src/app), y copia los archivos de dependencias (COPY package*.json ./). Luego, instala las dependencias (RUN npm install) y copia el código fuente de la aplicación (COPY . .). Finalmente, expone el puerto 8080 (EXPOSE 8080) y define el comando para iniciar la aplicación (CMD ["node", "app.js"]).

# Usa una imagen base oficial de Node.js
FROM node:14

# Establece el directorio de trabajo en el contenedor
WORKDIR /usr/src/app

# Copia el package.json y el package-lock.json
COPY package*.json ./

# Instala las dependencias del proyecto
RUN npm install

# Copia el resto del código de la aplicación
COPY . .

# Expone el puerto en el que la aplicación se ejecutará
EXPOSE 8080

# Define el comando para ejecutar la aplicación
CMD ["node", "app.js"]

Para construir y ejecutar la imagen, se utiliza el comando docker build -t myapp:latest ., que crea una imagen llamada myapp con la etiqueta latest. Luego, se ejecuta el contenedor con docker run -d -p 8080:8080 --name myapp_container myapp:latest, mapeando el puerto 8080 del host al contenedor y asignándole el nombre myapp_container. Este proceso garantiza que la aplicación Node.js funcione de manera consistente en cualquier entorno, facilitando el desarrollo y el despliegue.

Ejemplo 2: aplicación Python con Flask

El Dockerfile para una aplicación Python con Flask permite empaquetar la aplicación y sus dependencias en un contenedor Docker, garantizando un entorno de ejecución consistente. Este Dockerfile utiliza una imagen base oficial de Python (FROM python:3.9), establece el directorio de trabajo (WORKDIR /usr/src/app), y copia los archivos de requisitos (COPY requirements.txt ./). Luego, instala las dependencias del proyecto (RUN pip install --no-cache-dir -r requirements.txt) y copia el código fuente de la aplicación (COPY . .). Finalmente, expone el puerto 5000 (EXPOSE 5000) y define el comando para ejecutar la aplicación (CMD ["python", "app.py"]).

# Usa una imagen base oficial de Python
FROM python:3.9

# Establece el directorio de trabajo en el contenedor
WORKDIR /usr/src/app

# Copia los archivos de requisitos
COPY requirements.txt ./

# Instala las dependencias del proyecto
RUN pip install --no-cache-dir -r requirements.txt

# Copia el resto del código de la aplicación
COPY . .

# Expone el puerto en el que la aplicación se ejecutará
EXPOSE 5000

# Define el comando para ejecutar la aplicación
CMD ["python", "app.py"]

Para construir y ejecutar la imagen, se utiliza el comando docker build -t myflaskapp:latest ., que crea una imagen llamada myflaskapp con la etiqueta latest. Luego, se ejecuta el contenedor con docker run -d -p 5000:5000 --name myflaskapp_container myflaskapp:latest, mapeando el puerto 5000 del host al contenedor y asignándole el nombre myflaskapp_container. Este proceso asegura que la aplicación Flask se ejecute de manera consistente en cualquier entorno, facilitando el desarrollo y el despliegue continuo de la aplicación.

Despliegue de una aplicación con Docker

Despliegue con Docker Compose

Docker Compose es una herramienta poderosa que permite orquestar la ejecución de múltiples contenedores Docker, facilitando el despliegue de aplicaciones que dependen de varios servicios. Utilizando un archivo docker-compose.yml, se pueden definir todos los servicios necesarios, sus configuraciones y las relaciones entre ellos. Por ejemplo, se puede definir un servicio web y una base de datos PostgreSQL, especificar las variables de entorno y montar volúmenes para la persistencia de datos. Esto simplifica la gestión y el escalado de aplicaciones complejas, asegurando que todos los servicios necesarios se inicien y se configuren correctamente con un solo comando.

Construcción de una imagen

Para construir una imagen a partir de un Dockerfile, debemos usar el comando docker build:

docker build -t myapp:latest .

-t myapp:latest: Etiqueta la imagen con el nombre myapp y la etiqueta latest.

.: Indica que el contexto de construcción es el directorio actual.

Ejecución de un contenedor

Una vez que tengamos la imagen construida, podemos ejecutar un contenedor con el comando docker run:

docker run -d -p 8080:8080 --name myapp_container myapp:latest

-d: Ejecuta el contenedor en modo desatendido (detached).

-p 8080:8080: Mapea el puerto 8080 del contenedor al puerto 8080 del host.

--name myapp_container: Asigna un nombre al contenedor.

myapp:latest: Especifica la imagen a utilizar.

Publicación de una imagen en Docker Hub

Para compartir la imagen con otros, podemos subirla a Docker Hub. Primero, inicia sesión:

docker login

Luego, etiqueta la imagen con tu nombre de usuario de Docker Hub:

docker tag myapp:latest myusername/myapp:latest

Finalmente, sube la imagen:

docker push myusername/myapp:latest

Despliegue en un servidor

En un servidor, podemos usar Docker Compose para orquestar la ejecución de múltiples contenedores. Acá vemos un ejemplo de un archivo docker-compose.yml para una aplicación web y una base de datos PostgreSQL:

version: '3.8'

services:
  web:
    image: myusername/myapp:latest
    ports:
      - "8080:8080"
    depends_on:
      - db

  db:
    image: postgres:13
    environment:
      POSTGRES_USER: example
      POSTGRES_PASSWORD: example
      POSTGRES_DB: exampledb
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Para iniciar los servicios definidos en docker-compose.yml, hay que usar:

docker-compose up -d

Este comando va a construir y ejecutar los contenedores en segundo plano.

Dockerfile crea imágenes Docker definiendo instrucciones para configurar el entorno y las dependencias, ideal para microservicios y aplicaciones en la nube.