Practica de Docker - Virtualizar un proyecto de Django

By rogerarjona July 6, 2023, 5:04 p.m. Docker Virtualización Django

1.- Instalar Docker

Para ello debe ejecutarse lo siguiente en la terminal, linea por linea.

sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt update
apt-cache policy docker-ce
sudo apt install docker-ce
sudo systemctl status docker

Manual: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04-es

¿Que es la Virtualización?

Es la forma en la cual el Sistema Operativo se encarga de aislar recursos (RAM, Espacio en Disco y Particiones, SO, Usuarios, etc) y proporcionar herramientas para la administracion de ese apartado. En sistemas ubuntu del pasado se utilizaba chroot pero esto solo aislaba información entre usuarios y aplicaciones, pero no recursos.

¿Que es Docker?

Docker no es una tecnologia, si no la forma en la que se accede a ella (Los containers/contenedores). Docker facilita la creacíón y manipulación de los contenedores.

Componentes:

  • Docker Engine
  • Docker Hub
  • Docker Cloud
  • Docker Compose

¿Que resuelve?

  • No se requiere alguien que sepa de la instalación y orquestamiento del proyecto.
  • Los administradores de sistema pueden compartir el entorno correcto.
  • Velocidad en la implementación y desarrollo.

Problemas con Docker

  • No hay Alta Disponibilidad
  • Falta de Seguridad
  • Inestibilidad entre entornos (Windows, Mac, Linux)

Contenedores

Un contenedor es un espacio aislado, virtualizado en un sistema Operativo, que tiene todo lo necesario para ejecutar una o varias aplicaciones:

  • Bibliotecas del Sistema Operativo
  • Herramientas del Sistema
  • Runtime

Imágenes

Una imagen es compuesto de distintas capas de datos (Distribucion/SO, Software, Bibliotecas, Elementos Personalizados) que sirve como esqueleto/base para correr un contenedor.

¿Como podemos ver una imagen de Docker? Podemos descargar la imagen de "hello-world" de Docker Hub, y correrlo como contenedor en nuestro local:

docker run hello-world

Esto nos arrojará lo siguiente:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
719385e32844: Pull complete 
Digest: sha256:a13ec89cdf897b3e551bd9f89d499db6ff3a7f44c5b9eb8bca40da20eb4ea1fa
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

A partir de aqui podemos empezar a utilizar la consola de ubuntu para ejecutar comandos de docker para ver imagenes, contenedores, volumenes, entre otros. Observemos la imagen:

docker image ls

Observemos el contenedor:

docker ps -a

Más comandos:

  • https://devhints.io/docker
  • https://docs.docker.com/engine/reference/commandline/cli/

Crear una imagen

1.- Clonar el siguiente proyecto en su local:

git clone [email protected]:rogerwh/djtable.git

2.- Crear un archivo llamado "Dockerfile".

nano Dockerfile

Agregar el siguiente contenido:

# Imagen base de Python
FROM python:2.7

# Directorio de trabajo dentro del contenedor
WORKDIR /app

# Copiar los archivos de tu proyecto al contenedor
COPY . /app

# Instalar las dependencias del proyecto
RUN pip install -r requirements.txt

# Exponer el puerto que utiliza tu aplicación de Django (por ejemplo, 8000)
EXPOSE 8000

# Comando para ejecutar tu aplicación de Django
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

Comandos: https://devhints.io/dockerfile

Necesitamos construir (build) una imagen, para esto nos ayuda el archivo Dockerfile. Ejecuta:

docker build -t <nombre-imagen> .

Esto genera una nueva imagen, cuyo tag es "latest".

Ejecutar un contenedor

Para correr la imagen como contenedor, ejecutamos lo siguiente:

docker run -p 8000:8000 djtable

Podemos usar -d para que se ejecute en background.

El parametro -p permite ligar el puerto del host (izquierda) con el puerto del contenedor (derecha) El nombre de la imagen se puede acompañar con un "tag" de la siguiente forma <nombre-imagen>:<tag> Accede a 0.0.0.0:8000 de tu navegador para ver el proyecto de Django corriendo.</tag></nombre-imagen>

Importante:

Puedes Correr un contenedor aunque este detenido:

docker start <container_id>

Tambien puedes acceder al contenedor de la siguiente forma:

docker exec -it <container_id> /bin/bash

Docker Compose

En lugar de utilizar comandos individuales de Docker para crear y configurar cada contenedor por separado, Docker Compose permite definir la configuración de todos los servicios relacionados en un solo archivo. Esto simplifica el proceso de configuración y despliegue de aplicaciones que constan de múltiples contenedores.

Para ello se necesita de un archivo llamado docker-compose.yml, en el cual se pueden definir, servicios, volumenes, y redes para la conexion, al igua que apartados de seguridad.

Creemos el nuestro:

nano docker-compose.yml

Agrega lo siguiente:

version: '3.7'

services:
  backend:
    build:
      context: .
  proxy:
    build:
      context: ./proxy
    ports:
      - "80:80"
    depends_on:
      - backend

Explicación:

  • version: '3.7': Esta línea especifica la versión de la sintaxis de Docker Compose que se utilizará en este archivo.
  • En el apartado de services se definen todo aquello que se levantara como contenedor, en este caso hay 2: backend y proxy
  • En build es donde se especifica el archivo Dockerfile que se utilizara para crear el contenedor

Mas información: https://devhints.io/docker-compose

Creamos una carpeta llamada "proxy"

mkdir proxy
cd proxy

Creamos el archivo Dockerfile y pega el siguiente contenido

FROM nginx:1.19.0-alpine

RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d

Creamos el archivo nginx.conf

server {
    listen 80;
    location / {
        proxy_pass http://backend:8000;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host; # with exact server port
        proxy_redirect off;
    }
}

Para levantar estos dos contenedores, ejecutamos:

docker-compose up