Docker y Go: contenedorización de aplicaciones en Golang

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Docker y Go: contenedorización de aplicaciones en Golang



En el desarrollo moderno, la contenedorización se ha convertido en el estándar de facto para el despliegue y escalado de aplicaciones. Docker y Go son la pareja ideal para crear microservicios ligeros, rápidos y seguros. Go se compila en un binario estático, lo que lo hace especialmente atractivo para la contenedorización: la imagen final puede pesar solo unos pocos megabytes. En este artículo, analizaremos cómo contenedorizar correctamente aplicaciones Go, optimizar el Dockerfile y evitar errores típicos.



¿Por qué Docker y Go son la combinación ideal?



Go (Golang) fue creado pensando en las arquitecturas cloud modernas. Sus características clave son la compilación estática, el soporte integrado para concurrencia y la ausencia de dependencias externas en runtime. Docker, por su parte, proporciona un entorno aislado para ejecutar aplicaciones. Juntos permiten crear imágenes que:



  • Ocupan mínimo espacio — la imagen de una aplicación Go puede ser menor a 10 MB.
  • Se inician rápidamente — el binario estático no requiere intérprete ni máquina virtual.
  • Se escalan fácilmente — ideales para orquestación en Kubernetes.
  • Son más seguras — la imagen mínima reduce la superficie de ataque.


Creación de una aplicación Go simple para contenedorizar



Para empezar, escribamos una aplicación web simple en Go que contenedorizaremos. Cree el archivo main.go:



package main

import ( "fmt" "log" "net/http" "os")

func main() { port := os.Getenv("PORT") if port == "" { port = "8080" }

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello from Go in Docker! 🐳") })

log.Printf("Server starting on port %s", port) log.Fatal(http.ListenAndServe(":"+port, nil))}


Esta aplicación escucha peticiones HTTP y devuelve un mensaje de bienvenida. El puerto se puede configurar mediante la variable de entorno PORT.



Escritura del Dockerfile para la aplicación Go



Ahora crearemos el Dockerfile. Comenzaremos con un enfoque básico y luego lo optimizaremos.



Dockerfile básico (sin optimización)



FROM golang:1.22-alpine AS builder

WORKDIR /app

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

COPY . .RUN go build -o main .

FROM alpine:latest

WORKDIR /root/

COPY --from=builder /app/main .

EXPOSE 8080

CMD ["./main"]


Este Dockerfile utiliza multi-stage build — uno de los mejores patrones para Go. La primera etapa (builder) compila la aplicación, la segunda (imagen final) contiene solo el binario compilado. Este enfoque evita incluir el compilador y las herramientas de Go en la imagen final.



Dockerfile optimizado (best practices)



Para hacer la imagen aún más pequeña y segura, usamos scratch — una imagen vacía sin shell ni utilidades:



FROM golang:1.22-alpine AS builder

WORKDIR /app

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

COPY . .

# Deshabilitamos CGO, activamos optimizacionesRUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o main .

FROM scratch

WORKDIR /root/

COPY --from=builder /app/main .

# Añadimos certificados raíz para HTTPSCOPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

EXPOSE 8080

CMD ["./main"]


Optimizaciones clave:

  • CGO_ENABLED=0 — deshabilita CGO, lo que reduce el tamaño del binario.
  • -ldflags="-s -w" — elimina la tabla de símbolos y la información de depuración.
  • scratch — imagen mínima sin capas innecesarias.
  • Copia de ca-certificates.crt — necesaria para trabajar con HTTPS.

Blogs

Book Recommendations