Índice:
- Sección A. Estructurar un proyecto: apartado I, apartado II, apartado III, apartado IV, apartado V, apartado VI, apartado VII, apartado VIII, apartado IX, apartado X.
En este apartado crearemos lo necesario para trabajar con la virtualización de entornos.
Crear una nueva rama
Empezamos con la creación de la rama release/000-virtualization:
git checkout -b 'release/000-virtualization' Ahora actualizamos el archivo .gitignore añadiendo:
.env.production Docker
Empezaremos añadiendo el archivo .dockerignore:
_temp_/ .git .gitignore .env* .vscode/ .venv/ .pytest* tests/ Dockerfile compose.yml compose.override.yml Ahora prepararemos los entornos para Linux y Windows por separado.
Docker en el entorno Linux
Creamos el archivo Dockerfile:
# Dockerfile FROM python:3.12-slim AS base # Configuración de entorno ARG APP_PATH=/opt/la_fragua ENV APP_PATH=${APP_PATH} ARG APP_ENV=production ENV APP_ENV=${APP_ENV} ARG APP_PORT=8080 ENV APP_PORT=${APP_PORT} ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ POETRY_VIRTUALENVS_CREATE=false \ PATH="/root/.local/bin:$PATH" \ DISPLAY=:99 \ QT_QPA_PLATFORM=offscreen # Crear directorio de la aplicación WORKDIR ${APP_PATH} # Instalar dependencias del sistema necesarias para nicegui (qt, chrome, etc.) RUN apt-get update && apt-get install -y \ git curl build-essential \ libglib2.0-0 libnss3 libx11-6 libxcomposite1 \ libxdamage1 libxrandr2 libxkbcommon0 libxshmfence1 \ libasound2 libatk1.0-0 libatk-bridge2.0-0 libcups2 \ libdrm2 libxext6 libgbm1 libxfixes3 libxrender1 \ xvfb x11vnc fluxbox wmctrl \ && rm -rf /var/lib/apt/lists/* # ---- desarrollo ---- FROM base AS dev COPY requirements.txt . COPY requirements-dev.txt . RUN pip install --upgrade pip && pip install -r requirements.txt -r requirements-dev.txt CMD ["python3", "-m", "app.main"] # ---- producción ---- FROM base AS production COPY requirements.txt . RUN pip install --upgrade pip && pip install -r requirements.txt COPY . ${APP_FOLDER} EXPOSE ${APP_PORT} RUN echo '#!/bin/bash\nXvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &\npython3 -m app.main' > /opt/start.sh && \ chmod +x /opt/start.sh CMD ["/opt/start.sh"] Una vez que tenemos el archivo Dockerfile vamos a preparar los archivos 'compose' para automatizar la creación y ejecución de los entornos.
Creamos el archivo compose.yml:
# compose.yml para producción services: la_fragua: image: "${DOCKER_LOGIN}/${APP_NAME}-linux:latest" build: context: . dockerfile: "Dockerfile" target: production env_file: - .env.production ports: - "${APP_PORT}:8080" environment: - APP_ENV=container - APP_PATH=/opt/la_fragua restart: always Creamos el archivo compose.override.yml:
# compose.override.yml para dev services: la_fragua: image: "${APP_NAME}-linux:dev" build: context: . dockerfile: "Dockerfile" target: dev env_file: - .env ports: - "${APP_PORT}:8080" environment: - APP_ENV=container - APP_PATH=/opt/la_fragua volumes: - .:/opt/la_fragua stdin_open: true tty: true Docker en el entorno Windows
Añadimos al archivo .dockerignore el siguiente contenido:
Dockerfile.windows compose.windows.yml compose.windows.override.yml Creamos el archivo Dockerfile.windows:
# Dockerfile.windows FROM mcr.microsoft.com/windows/servercore:ltsc2022 AS base # Shell Powershell SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"] # Instalar Python RUN Invoke-WebRequest -UseBasicParsing https://www.python.org/ftp/python/3.12.0/python-3.12.0-amd64.exe -OutFile python-installer.exe; \ Start-Process python-installer.exe -Wait -ArgumentList '/quiet', 'InstallAllUsers=1', 'PrependPath=1', 'DefaultAllUsersTargetDir=C:\Python312'; \ Remove-Item python-installer.exe -Force # Actualizar pip RUN python -m pip install --upgrade pip --disable-pip-version-check # Configuración de entorno ARG APP_PATH="C:/la_fragua" ENV APP_PATH=${APP_PATH} ARG APP_ENV=production ENV APP_ENV=${APP_ENV} ARG APP_PORT=8080 ENV APP_PORT=${APP_PORT} ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ APP_VIRTUALIZATION=container \ QT_QPA_PLATFORM=minimal # Crear directorio de la aplicación WORKDIR ${APP_PATH} # ---------- Dev stage ---------- FROM base AS dev COPY requirements.txt . COPY requirements-dev.txt . RUN pip install --no-cache-dir -r requirements.txt -r requirements-dev.txt CMD ["python", "-m", "app.main"] # ---------- Production stage ---------- FROM base AS production COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . ${APP_FOLDER} EXPOSE ${APP_PORT} CMD ["python", "-m", "app.main"] Creamos el archivo compose.windows.yml
# compose.windows.yml para producción services: la_fragua: image: "${DOCKER_LOGIN}/${APP_NAME}-windows:latest" build: context: . dockerfile: "Dockerfile.windows" target: production env_file: - .env.production ports: - "${APP_PORT}:8080" environment: - APP_ENV=container - APP_PATH="C:/la_fragua" restart: always Creamos el archivo compose.windows.override.yml
# compose.windows.override.yml para dev services: la_fragua: image: "${APP_NAME}-windows:dev" build: context: . dockerfile: "Dockerfile.windows" target: dev env_file: - .env ports: - "${APP_PORT}:8080" environment: - APP_ENV=container - APP_PATH="C:/la_fragua" volumes: - .:C:/la_fragua stdin_open: true tty: true Ya tenemos preparados los entornos docker de Linux y Windows.
Hemos cometido un par de errores en los Dockerfile para obligarnos a realizar una corrección. En el siguiente artículo trabajaremos sobre ello.
Apuntes
En los archivos Dockerfile habrás visto que utilizamos FROM python:3.12-slim AS base al inicio, y posteriormente FROM base AS dev y FROM base AS production. Esto, unido al target de los archivos compose nos define qué parte del Dockerfile está generándose. Con esta dinámica hemos conseguido no repetir información en innecesariamente. En el siguiente artículo continuamos trabajando sobre los entornos.
En los archivos compose verás que en producción tenemos la variable DOCKER_LOGIN pero en desarrollo no lo está. Esto tiene una razón: la imagen docker que se genere para producción querremos poder llevarla al hub de docker, pero la imagen de desarrollo no debemos llevarla nunca al hub.
Enlaces
Repositorio del proyecto:
Enlaces de interés:
- Multi-stage builds: https://docs.docker.com/build/building/multi-stage/
- Merge Compose files: https://docs.docker.com/compose/how-tos/multiple-compose-files/merge/
Siguiente artículo:
- Sección A. Estructurar un proyecto: apartado VII: Corregir errores y no morir en el intento.
Top comments (0)