Skip to content

Imágenes Docker ​

Todas las imágenes usan build multi-etapa: una etapa de construcción con las herramientas de compilación y una etapa final mínima con solo lo necesario para ejecutar.

Las imágenes se publican en el registry de GitLab:

git.eje.gob.bo:5050/proceso-seleccion/<repositorio>:<tag>

Backends (Django) ​

Aplica a auth-backend y backend-seleccion-postulantes.

Etapas ​

EtapaBaseContenido
builderpython:3.11-slimInstala requirements.prod.txt en /install (pip --prefix)
runtimepython:3.11-slimCopia /install a /usr/local, el código fuente, nginx y entrypoint.sh

Paquetes de sistema en runtime:

  • auth-backend: nginx, curl.
  • backend-seleccion-postulantes: nginx, curl, ghostscript y librerías nativas que WeasyPrint y OpenCV cargan en tiempo de ejecución (libpango, libpangocairo, libgdk-pixbuf, libcairo2, libffi8, libglib2.0-0, libgl1, libsm6, libxext6, libxrender1, shared-mime-info, fuentes liberation y dejavu). La etapa builder instala además las librerías de desarrollo necesarias para compilar estas dependencias.

Usuario y permisos ​

El contenedor corre como appuser (no root). nginx (www-data) y gunicorn (appuser) comparten acceso a los volúmenes:

dockerfile
RUN useradd -m appuser \
    && mkdir -p /app/public_files /app/private_files \
    && chown -R appuser:www-data /app \
    && chmod -R 775 /app/public_files /app/private_files

TIP

Si en el host los directorios storage/public o storage/private tienen otro propietario, el backend no podrá escribir archivos. Deben ser escribibles por el UID de appuser dentro del contenedor.

Procesos dentro del contenedor ​

Cada contenedor de backend ejecuta nginx + gunicorn:

  • gunicorn: 2 workers, timeout 60 s, logs de acceso y error a stdout/stderr.
  • nginx: proxy_read_timeout 60s y cabeceras Host, X-Real-IP, X-Forwarded-For, X-Forwarded-Proto hacia gunicorn.
  • La ruta /private_files/ es internal: solo se sirve cuando Django responde con la cabecera X-Accel-Redirect tras validar el acceso.

Health check ​

dockerfile
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
    CMD curl -fsS http://localhost/health/ || exit 1

El endpoint /health/ está definido en Django (auth_interop_backend/urls.py y seleccion_backend/urls.py).

entrypoint.sh ​

Se ejecuta en cada arranque del contenedor.

auth-backend

sh
python manage.py migrate --noinput
python manage.py collectstatic --noinput --clear -v 0
python manage.py rotate_signing_keys
python manage.py create_default_scopes
python manage.py create_claim_definitions
nginx -g "daemon off;" &
exec gunicorn auth_interop_backend.wsgi:application --bind 127.0.0.1:8000 ...

backend-seleccion-postulantes

sh
python manage.py migrate --noinput
python manage.py collectstatic --noinput --clear -v 0
# Bucle en segundo plano: cada 30 min
python manage.py limpiar_segmentos_huerfanos
nginx -g "daemon off;" &
exec gunicorn seleccion_backend.wsgi:application --bind 127.0.0.1:8000 ...

INFO

Las migraciones se aplican automáticamente al desplegar. Los comandos de arranque se describen en Scripts útiles de los backends.

Frontends (Vue + Vite) ​

Aplica a los portales del IDP, del SPS y a la estación de examen.

EtapaBaseContenido
buildernode:24-alpinepnpm@11.3.0 vía corepack, pnpm install --frozen-lockfile, pnpm run build
runtimenginx:alpineCopia /app/dist a /usr/share/nginx/html y nginx.conf

Variables de build (VITE_*) ​

Las variables VITE_* se incrustan en el bundle durante el build (se pasan como --build-arg). No pueden cambiarse en runtime: cualquier cambio requiere un nuevo build.

RepositorioBuild args
auth-authorization-frontendVITE_TITLE_APP, VITE_API_ENDPOINT, VITE_API_ENDPOINT_FILES, VITE_PUBLIC_AUTH_PORTAL, VITE_ADMIN_AUTH_PORTAL
auth-frontend-adminVITE_TITLE_APP, VITE_API_ENDPOINT, VITE_API_ENDPOINT_PATH, VITE_API_ENDPOINT_FILES, VITE_LOGIN_REDIRECT_URL, VITE_MANUAL_TECNICO_URL, VITE_MANUAL_USUARIO_URL
frontend-public-authVITE_TITLE_APP, VITE_API_ENDPOINT, VITE_API_ENDPOINT_PATH, VITE_API_ENDPOINT_FILES, VITE_API_FILES_PRIVATE, VITE_LOGIN_REDIRECT_URL, VITE_JACOBITUS_API_URL
frontend-portal-admin-seleccion-postulantesVITE_TITLE_APP, VITE_API_ENDPOINT, VITE_API_ENDPOINT_PATH, VITE_API_ENDPOINT_FILES, VITE_AUTH_ORIGIN_PORTAL, VITE_API_FILES_PRIVATE, VITE_MANUAL_USUARIO_URL, VITE_MANUAL_TECNICO_URL, VITE_AUTH_PUBLIC_URL
frontend-portal-comisiones-seleccion-postulantesVITE_TITLE_APP, VITE_API_ENDPOINT, VITE_API_ENDPOINT_PATH, VITE_API_ENDPOINT_FILES, VITE_API_FILES_PRIVATE, VITE_AUTH_ORIGIN_PORTAL, VITE_AUTH_PUBLIC_URL
frontend-portal-postulantes-seleccion-postulantesVITE_TITLE_APP, VITE_API_ENDPOINT, VITE_API_ENDPOINT_PATH, VITE_API_ENDPOINT_FILES, VITE_API_FILES_PRIVATE, VITE_LOGIN_REDIRECT_URL, VITE_AUTH_ORIGIN_PORTAL, VITE_DOMAIN_PUBLIC_URL
frontend-estacion-examenVITE_TITLE_APP, VITE_API_ENDPOINT, VITE_API_ENDPOINT_PATH, VITE_API_FILES_PRIVATE

Los valores se toman de las variables CI/CD DEV_VITE_* o PROD_VITE_* según la rama. Ver Variables y secretos de CI/CD.

nginx de los frontends ​

nginx
server {
   listen 80;
   root /usr/share/nginx/html;
   index index.html;

   gzip on;
   gzip_types text/plain text/css application/javascript application/json image/svg+xml;

   location /health {
      access_log off;
      default_type text/plain;
      return 200 'OK';
   }

   # SPA: rutas del router resuelven a index.html
   location / {
      try_files $uri $uri/ /index.html;
   }

   location ~* \.(js|css|png|jpg|svg|ico|woff2)$ {
      expires 1y;
      add_header Cache-Control "public, immutable";
   }
}

Manuales (VitePress) ​

Aplica a frontend-manual-tecnico y frontend-manual-de-usuario.

Misma estructura que los frontends, con estas diferencias:

  • El build ejecuta pnpm run docs:build.
  • Se copia /app/.vitepress/dist en lugar de /app/dist.
  • No reciben build args.
  • Usan la misma configuración de nginx que los frontends.

Construcción local ​

Para validar una imagen antes de subir cambios:

sh
# Backend
docker build -t auth-backend:local ./auth-backend

# Frontend (los build args son obligatorios para un bundle funcional)
docker build \
  --build-arg VITE_TITLE_APP="..." \
  --build-arg VITE_API_ENDPOINT="..." \
  -t frontend-portal-admin:local ./frontend-portal-admin-seleccion-postulantes