Configuración de despliegue en Docker y cloud

Lectura
25 min~5 min lectura

Concepto clave

La configuración de despliegue en Docker y cloud es el proceso de empaquetar tu aplicación Go en contenedores estandarizados que pueden ejecutarse de manera consistente en cualquier entorno, desde tu máquina local hasta servidores en la nube. Imagina que Docker es como una caja de herramientas portátil: tu microservicio, todas sus dependencias y configuraciones van dentro de un contenedor que funciona igual en cualquier lugar donde lo abras.

Para APIs de alto rendimiento en Go, esto es crucial porque garantiza que el entorno de ejecución sea idéntico en desarrollo, pruebas y producción. Los contenedores Docker encapsulan tu aplicación Go junto con el runtime necesario, eliminando el clásico problema de "funciona en mi máquina". Cuando combinas esto con servicios cloud como AWS, Google Cloud o Azure, obtienes escalabilidad automática, balanceo de carga y alta disponibilidad para tus microservicios.

Cómo funciona en la práctica

El flujo típico comienza con la creación de un Dockerfile, que es una receta que describe cómo construir la imagen de tu aplicación. Para Go, esto implica usar una imagen base oficial de Go, copiar tu código, compilar el binario y luego crear una imagen final más ligera usando una imagen base minimalista como alpine.

Paso a paso: primero escribes el Dockerfile en tu proyecto. Luego construyes la imagen con docker build. Después, pruebas localmente con docker run. Finalmente, subes la imagen a un registro como Docker Hub o Amazon ECR y la despliegas en tu plataforma cloud preferida usando servicios como AWS ECS, Google Kubernetes Engine o Azure Container Instances.

Codigo en accion

Aquí tienes un Dockerfile optimizado para una API Go con gorilla/mux:

# Etapa 1: Compilación
FROM golang:1.21-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main ./cmd/api

# Etapa 2: Imagen final minimalista
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
COPY --from=builder /app/.env .

EXPOSE 8080
CMD ["./main"]

Y este es el docker-compose.yml para desarrollo local con base de datos:

version: '3.8'
services:
  api:
    build: .
    ports:
      - "8080:8080"
    environment:
      - DB_HOST=postgres
      - DB_PORT=5432
    depends_on:
      - postgres
    networks:
      - app-network

  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - app-network

volumes:
  postgres-data:

networks:
  app-network:
    driver: bridge

Errores comunes

  • No usar multi-stage builds: Construir directamente en la imagen final resulta en imágenes enormes (1GB+). La solución es usar dos etapas como en el ejemplo anterior.
  • Exponer puertos incorrectos: Si tu API Go escucha en el puerto 8080 pero expones el 80 en Docker, la aplicación no será accesible. Verifica que el puerto en EXPOSE coincida con el que usa tu servidor.
  • Olvidar variables de entorno: Las configuraciones como conexiones a BD deben pasarse como variables de entorno, no hardcodeadas. Usa os.Getenv() en Go y defínelas en docker-compose o en la configuración del cloud.
  • No optimizar las capas de Docker: Cada instrucción RUN, COPY o ADD crea una nueva capa. Combina comandos relacionados y usa .dockerignore para excluir archivos innecesarios.
  • Ignorar health checks: En producción, configura health checks en tu Dockerfile o en la plataforma cloud para que el orquestador sepa si tu contenedor está saludable.

Checklist de dominio

  1. Puedo escribir un Dockerfile eficiente con multi-stage build para una aplicación Go
  2. Sé configurar docker-compose.yml para desarrollo local con servicios dependientes
  3. Entiendo cómo subir imágenes a un registro (Docker Hub, ECR, GCR)
  4. Puedo desplegar contenedores en al menos una plataforma cloud (AWS ECS, GKE, etc.)
  5. Sé configurar variables de entorno para diferentes entornos (dev, prod)
  6. Comprendo cómo escalar contenedores horizontalmente en la nube
  7. Puedo monitorear y hacer logging de contenedores desplegados

Despliega tu API Go en AWS ECS usando Fargate

En este ejercicio practico, vas a llevar tu API Go con gorilla/mux a produccion en AWS.

  1. Prepara tu proyecto: Asegurate de tener un Dockerfile como el del ejemplo anterior en tu proyecto Go. Tu API debe escuchar en el puerto 8080.
  2. Construye y prueba localmente: Ejecuta docker build -t my-go-api . y luego docker run -p 8080:8080 my-go-api. Verifica que tu API responda en http://localhost:8080/health.
  3. Sube a Amazon ECR: Crea un repositorio en Amazon ECR, autenticate con AWS CLI, etiqueta tu imagen y subela con:
    docker tag my-go-api:latest [account-id].dkr.ecr.[region].amazonaws.com/my-go-api:latest
    docker push [account-id].dkr.ecr.[region].amazonaws.com/my-go-api:latest
  4. Crea un cluster ECS con Fargate: En la consola de AWS, ve a ECS y crea un nuevo cluster usando el launch type Fargate.
  5. Define tu tarea (Task Definition): Crea una nueva task definition que use tu imagen de ECR, asigne 0.5 vCPU y 1GB de memoria, y exponga el puerto 8080.
  6. Despliega el servicio: Crea un servicio en tu cluster que ejecute 2 tareas de tu definicion, con un Application Load Balancer que distribuya trafico.
  7. Verifica el despliegue: Obtén la URL del load balancer y prueba tu API desplegada.
Pistas
  • Usa AWS CLI configurado con credenciales validas para interactuar con ECR
  • En la task definition, asegurate de mapear el puerto del contenedor (8080) al puerto del host (tambien 8080)
  • Si tienes problemas de conectividad, revisa los security groups del load balancer y las tareas

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.