Tutorial Presentación disponible

Docker en el DTI

Qué es Docker, qué problema resuelve, cómo se instala, los 8 comandos básicos y cómo se conecta con el CI/CD del DTI. Pensado para colaboradores nuevos, técnicos y no técnicos.

DTI UNACH ·
docker ci-cd devops workflow
Abrir presentación

Este artículo es complementario al de Trabajar con Git y GitLab en el DTI. Aquel explica cómo viaja tu cambio (rama → MR → merge). Este explica qué se construye después del merge: una imagen Docker que va a parar a producción.

1. ¿Qué es Docker?

Antes del año 1956, cada producto que viajaba en barco se cargaba como podía: cajas de madera, sacos, barriles. Cada puerto tenía que reinventar cómo recibir esa carga, los productos se rompían y descargar un barco tomaba semanas. Entonces alguien tuvo una idea muy simple: estandarizar la caja. Nació el contenedor de transporte marítimo: una caja de medidas fijas que cualquier puerto del mundo sabe levantar, cualquier camión sabe cargar y cualquier barco sabe apilar. Lo que va adentro del contenedor es problema de quien envía; el contenedor en sí se ve y se mueve igual siempre.

Contenedores de transporte marítimo apilados en un puerto

Docker hace exactamente lo mismo, pero con software. Empaqueta tu aplicación junto con todo lo que necesita para funcionar —el lenguaje, las librerías, las dependencias del sistema— en una “caja estándar” llamada contenedor. Esa caja se ve y se comporta igual en el computador del desarrollador, en el servidor de staging y en producción.

Así de simple es la idea. El resto del artículo se trata de cómo usamos esa idea en el DTI.

2. El problema que Docker resuelve

Antes de Docker, la frase más temida en cualquier equipo de software era: “funciona en mi máquina”. Una persona escribía código en su computador, lo subía al servidor, y se rompía. ¿Por qué? Porque en su computador tenía una versión de Node, una librería con cierto parche, una variable de entorno especial; en el servidor algo de eso era diferente.

Docker elimina ese problema. Si el sistema funciona dentro del contenedor en tu computador, va a funcionar igual dentro del mismo contenedor en el servidor. No hay sorpresas: el contenedor lleva todo lo que necesita adentro.

Para el DTI esto significa tres cosas concretas:

  1. Despliegues predecibles. Lo que el equipo prueba en staging es exactamente lo que sale a producción.
  2. Onboarding rápido. Una persona nueva levanta un proyecto entero en su máquina con un solo comando, sin instalar 20 cosas a mano.
  3. Servidores limpios. El servidor no necesita tener instaladas las librerías de cada proyecto: cada contenedor las lleva consigo.

3. Tres palabras que aparecen siempre: Dockerfile, imagen, contenedor

Vas a escuchar estas tres palabras una y otra vez. Vale la pena distinguirlas desde el principio:

Diagrama mostrando el flujo de Dockerfile a imagen a contenedor, con el registry como destino intermedio
  • Dockerfile — un archivo de texto que describe cómo construir tu aplicación. Es la receta. Lo escribe el equipo de desarrollo una sola vez y queda guardado en el repositorio del proyecto.
  • Imagen Docker — el paquete construido a partir del Dockerfile: tu aplicación más todas sus dependencias, listas para ejecutarse. La imagen es inmutable: una vez construida, no cambia. En el DTI las imágenes viven en registry.gitlab.unach.cl (nuestro registry interno), etiquetadas con la versión del proyecto.
  • Contenedor — la imagen corriendo. Puedes tener varios contenedores corriendo a partir de la misma imagen, como puedes tener varias copias del mismo programa abiertas en tu computador.

Una buena forma de recordarlo: si el Dockerfile es la receta y la imagen es el plato terminado guardado en el refrigerador, el contenedor es ese plato en la mesa, caliente y listo para comer.

Para quienes van a usar Docker

Esta sección y las siguientes (4, 5 y 6) son opcionales si sólo te interesa entender cómo encaja Docker en el flujo del DTI. Salta directo a la sección 7 si ese es tu caso. Si vas a correr proyectos localmente, sigue leyendo.

4. Cómo lo instalas

Para el día a día, lo que necesitas es Docker Desktop (en Windows o macOS) o Docker Engine (en Linux). Ambos te dan el comando docker en la terminal y la capacidad de correr contenedores. Docker Desktop además incluye una interfaz gráfica para ver qué tienes corriendo.

Panel Containers de Docker Desktop mostrando contenedores en ejecución

Windows

  1. Activa WSL2 (subsistema de Linux para Windows). Sigue la guía oficial de Microsoft.
  2. Descarga Docker Desktop for Windows desde docker.com/products/docker-desktop.
  3. Instálalo y reinicia.

macOS

  1. Descarga Docker Desktop for Mac desde docker.com/products/docker-desktop (elige Intel o Apple Silicon según tu Mac).
  2. Arrástralo a Aplicaciones y ábrelo.

Linux

  1. Instala Docker Engine siguiendo las instrucciones para tu distribución en docs.docker.com/engine/install.
  2. Agrega tu usuario al grupo docker para no tener que usar sudo en cada comando.

Si te trabas en la instalación, escribe a tu mentor DTI. Es lo más común que pase mal y se resuelve en 10 minutos con ayuda.

5. Ocho comandos básicos

Estos son los comandos que cubren el 90% de lo que vas a hacer. No necesitas memorizarlos: en general los vas a copiar del README de cada proyecto.

ComandoPara qué sirve (analogía)Ejemplo
docker --version”¿Está instalado?”docker --version
docker pull <imagen>”Tráeme el paquete desde el registry.”docker pull node:22
docker run <imagen>”Arranca un contenedor a partir de la imagen.”docker run -p 4321:4321 sigae:1.4.0
docker ps”¿Qué tengo corriendo?”docker ps
docker logs <contenedor>”Muéstrame lo que el contenedor está imprimiendo.”docker logs sigae-app
docker stop <contenedor>”Detén ese contenedor.”docker stop sigae-app
docker compose up”Levanta TODO el proyecto” (la app + base de datos + dependencias).docker compose up
docker compose down”Bájalo todo y limpia.”docker compose down

6. docker compose: levantar todo el proyecto

docker compose up es el comando que más vas a usar en el DTI. Es el equivalente a apretar el botón “encender” del proyecto completo.

¿Por qué? Casi todos nuestros sistemas no son una sola aplicación. Sigae, por ejemplo, necesita: el backend, una base de datos PostgreSQL, un Redis para caché, y a veces un worker en segundo plano. Cada uno corre en su propio contenedor. docker compose lee un archivo llamado docker-compose.yml que describe esos contenedores y los levanta juntos, conectados entre sí.

Flujo típico para correr un proyecto del DTI localmente:

  1. Clonas el repositorio desde gitlab.unach.cl (ver artículo de Git).
  2. Abres una terminal en la carpeta del proyecto.
  3. Corres docker compose up.
  4. Esperas un par de minutos (la primera vez descarga las imágenes).
  5. Abres el navegador en la URL que indique el README del proyecto.

Cuando termines: docker compose down y todo se apaga limpio.

7. Cómo se conecta con el flujo del DTI

Aquí cierra el círculo. Si ya leíste el artículo de Git workflow, recordarás que después de un merge a staging o a main, el CI/CD de GitLab dispara un pipeline. Una de las etapas de ese pipeline construye la imagen Docker del proyecto.

Pipeline CI/CD de GitLab con la etapa Image construyendo la imagen Docker

El job image:build toma el Dockerfile del repositorio, construye la imagen, la etiqueta con la versión (ej. sigae:1.4.0) y la publica en registry.gitlab.unach.cl. Inmediatamente después, el job deploy le dice al servidor de staging o de producción que baje esa imagen y arranque un contenedor con ella. Listo, la nueva versión está viva.

Lo importante de esto: como colaborador del DTI, tú casi nunca corres docker build ni docker push a mano. Eso lo hace CI/CD automáticamente. Lo único que tú corres en tu computador es docker compose up cuando necesitas ver el proyecto localmente.

Lo mínimo que tienes que recordar

  1. Docker empaqueta tu aplicación + sus dependencias en una “caja” llamada contenedor.
  2. La receta de cómo construir la caja vive en el Dockerfile del repositorio.
  3. El producto construido se llama imagen y vive en registry.gitlab.unach.cl.
  4. El contenedor es la imagen corriendo.
  5. En tu computador, usa docker compose up y docker compose down. Nada más.
  6. La construcción y el despliegue los hace CI/CD automáticamente tras un merge aprobado.

Cheatsheet copy-paste

# Verificar instalación
docker --version

# Levantar el proyecto completo (lo que más usarás)
docker compose up        # arrancar
docker compose up -d     # arrancar en segundo plano
docker compose down      # detener y limpiar
docker compose logs -f   # ver logs en vivo

# Operar contenedores sueltos
docker ps                # ver qué corre
docker logs <nombre>     # ver salida
docker stop <nombre>     # detener
docker pull <imagen>     # bajar imagen del registry

Anexo: lee un Dockerfile real

Para que veas cómo se ve un Dockerfile en la práctica, este es el Dockerfile de esta misma wiki (el sitio que estás leyendo), comentado paso a paso:

# ── Etapa 1: builder ──
# "FROM" elige una imagen base; aquí Node.js 22 sobre Debian Bookworm.
FROM node:22-bookworm AS builder

# El directorio de trabajo dentro del contenedor.
WORKDIR /app

# Instala pnpm (el gestor de paquetes que usamos en este proyecto).
RUN npm install -g pnpm@10

# Copia los archivos que describen las dependencias e instálalas.
# Esto se hace ANTES de copiar el código para aprovechar caché de Docker.
COPY package.json pnpm-lock.yaml* ./
RUN pnpm install --frozen-lockfile

# Copia el resto del código fuente.
COPY . .

# Crea la carpeta donde vivirá la base de datos SQLite.
RUN mkdir -p /app/db

# Construye el sitio estático (Astro build).
RUN pnpm run build

# ── Etapa 2: runner ──
# Una segunda etapa más liviana, sólo con lo necesario para correr.
# Esto se llama "multi-stage build" y produce imágenes más pequeñas.
FROM node:22-bookworm-slim AS runner

WORKDIR /app

# Trae sólo los artefactos compilados y las dependencias necesarias.
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

# Carpeta para la base de datos (se monta como volumen en producción).
RUN mkdir -p /app/db

# Expone el puerto donde escucha el servidor.
EXPOSE 4321

# Variables de entorno con los defaults de producción.
ENV HOST=0.0.0.0
ENV PORT=4321
ENV NODE_ENV=production

# El comando que se ejecuta cuando arrancas el contenedor.
CMD ["node", "dist/server/entry.mjs"]

No tienes que entender cada detalle. La idea es que cuando veas un Dockerfile de otro proyecto del DTI, reconozcas la estructura: FROM (qué uso como base) · COPY (qué meto adentro) · RUN (qué pasos ejecuto al construir) · CMD (qué corre al arrancar).

Versión presentación

Versión condensada para proyectar en charlas y onboarding. Usa flechas para navegar o haz clic en Abrir presentación.


¿Dudas, problemas instalando, o quieres profundizar? Habla con tu mentor DTI o revisa la documentación oficial de Docker.