Docker y Swift: Contenerización de aplicaciones de la A a la Z

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

Introducción: Por qué Docker y Swift son la pareja ideal para el desarrollo moderno

El mundo del desarrollo para iOS y macOS durante mucho tiempo se asoció exclusivamente con Xcode y compilaciones locales. Sin embargo, con la llegada de Swift del lado del servidor (especialmente el framework Vapor) y el crecimiento de la popularidad de la arquitectura de microservicios, la contenerización se ha convertido no solo en una tendencia, sino en una necesidad. Docker para el desarrollador de Swift no se trata solo de aislamiento del entorno, sino también de uniformidad en las compilaciones, simplicidad en CI/CD y fácil despliegue en cualquier servidor.

En este artículo, analizaremos el ciclo completo de trabajo con Docker y Swift: desde escribir un simple Dockerfile para macOS/Linux hasta desplegar una aplicación web completa en Vapor. Aprenderá cómo evitar errores típicos y hacer que sus contenedores sean ligeros y seguros.



Parte principal: Guía paso a paso para la contenerización de Swift



1. Fundamentos: Dockerfile para una aplicación Swift (macOS vs Linux)

Lo primero que hay que entender: Swift es un lenguaje multiplataforma, pero Docker tradicionalmente funciona con contenedores Linux. Para el desarrollo en macOS, puede usar imágenes con la compilación de Swift para Linux (por ejemplo, swift:5.9-focal) o, si el entorno macOS es crítico para usted, usar virtualización (Docker Desktop for Mac). Sin embargo, para aplicaciones de servidor (Vapor, Kitura), las imágenes de Linux son el estándar.

Dockerfile básico para una aplicación Swift de servidor (Vapor):

# Usamos la imagen oficial de SwiftFROM swift:5.9-focal AS build

# Establecemos el directorio de trabajoWORKDIR /app

# Copiamos los archivos Package.swift y Package.resolved para cachear dependenciasCOPY Package.swift Package.resolved ./RUN swift package resolve

# Copiamos el código fuenteCOPY Sources ./SourcesRUN swift build -c release

# Imagen final (mínima)FROM ubuntu:focalWORKDIR /appCOPY --from=build /app/.build/release /appEXPOSE 8080CMD ["./Run"]

Este enfoque utiliza compilación en múltiples etapas (multi-stage build): la primera etapa compila la aplicación, la segunda crea una imagen mínima que contiene solo el binario y las bibliotecas necesarias. La imagen final pesa ~60-80 MB en lugar de 2 GB.



2. Optimización de imágenes: almacenamiento en caché y dependencias

Swift es un lenguaje compilado, y cada compilación puede llevar minutos. Para acelerar el proceso, use el almacenamiento en caché de capas de Docker. El truco clave: primero copie Package.swift y Package.resolved, luego ejecute swift package resolve, y solo después copie los archivos fuente. Esto garantiza que las dependencias se reconstruyan solo cuando cambie Package.swift, y no con cada cambio de código.

Optimización adicional: usar .dockerignore:

.git.gitignore.build*.xcworkspace*.xcodeprojDerivedDataPackagesREADME.mdTests

Esto evita que archivos innecesarios (pruebas, git, proyectos de Xcode) entren en el contexto de compilación, lo que acelera la transferencia del contexto y reduce el tamaño de la imagen.



3. Docker Compose: vinculando Swift con la base de datos y la caché

Las aplicaciones reales rara vez viven de forma aislada. Para un backend típico en Vapor, necesitará PostgreSQL (o Fluent), Redis para la caché y, posiblemente, Nginx. docker-compose.yml permite ejecutar todo con un solo comando.

Ejemplo de docker-compose.yml para una aplicación Swift con PostgreSQL y Redis:

version: '3.8'services:  app:    build: .    ports:      - "8080:8080"    environment:      - DATABASE_HOST=db      - DATABASE_PORT=5432      - REDIS_HOST=redis      - REDIS_PORT=6379    depends_on:      - db      - redis    restart: unless-stopped

db: image: postgres:15-alpine environment: POSTGRES_DB: myapp POSTGRES_USER: user POSTGRES_PASSWORD: password volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432"

redis: image:

Blogs

Book Recommendations