Docker y Swift: contenedorización de aplicaciones en iOS y macOS

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é un desarrollador de Swift necesita Docker?



Muchos desarrolladores de Swift (especialmente en el mundo de iOS y macOS) están acostumbrados a Xcode, simuladores y la gestión manual de dependencias. Sin embargo, con la creciente popularidad de Swift del lado del servidor (por ejemplo, el framework Vapor) y la necesidad de automatizar pruebas y despliegues, la contenerización se convierte en una habilidad obligatoria.



Docker permite empaquetar tu aplicación Swift junto con todas sus dependencias en un contenedor aislado. Esto garantiza que el código funcione igual en tu máquina local, en el servidor CI/CD y en producción. En este artículo, veremos cómo crear una imagen Docker para un proyecto Swift, optimizar su tamaño y ejecutarlo en un contenedor.



1. Fundamentos de Docker para Swift: Dockerfile y compilación multi-etapa



El enfoque estándar para la contenerización de aplicaciones Swift es el uso de la compilación multi-etapa. Esto permite separar la fase de compilación (donde se necesitan las herramientas pesadas de Swift) de la fase de ejecución (donde solo se necesita el binario compilado).



Consideremos un proyecto típico en Swift, por ejemplo, un servidor en Vapor. Crearemos un archivo Dockerfile en la raíz del proyecto:



# Primera etapa: compilaciónFROM swift:5.9-focal AS build

WORKDIR /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 . .

# Compilación en modo releaseRUN swift build -c release --static-swift-stdlib

# Segunda etapa: imagen mínima para ejecuciónFROM ubuntu:focal

WORKDIR /app

# Copiamos el binario compilado de la primera etapaCOPY --from=build /app/.build/release/Run .

# Abrimos el puerto (por defecto Vapor usa el 8080)EXPOSE 8080

# Ejecutamos la aplicaciónCMD ["./Run"]


Puntos importantes:

  • --static-swift-stdlib — el enlace estático de la librería estándar de Swift reduce las dependencias en la fase de ejecución.
  • Copiar Package.swift antes que el código fuente es un truco para cachear la capa de dependencias de Docker.
  • La imagen base ubuntu:focal es ligera, pero contiene todas las librerías del sistema necesarias.


2. Compilación y ejecución del contenedor



Ahora que el Dockerfile está listo, compilemos la imagen y ejecutemos el contenedor:



# Compilación de la imagendocker build -t my-swift-app .

# Ejecución del contenedor en segundo plano con reenvío de puertodocker run -d -p 8080:8080 --name swift-container my-swift-app

# Verificación de logsdocker logs swift-container

# Prueba (si la aplicación es un servidor HTTP)curl http://localhost:8080/


Si usas Swift Package Manager sin Vapor, el binario puede tener otro nombre. En ese caso, cambia la ruta en COPY --from=build y CMD. Puedes saber el nombre exacto del binario con el comando:



swift build -c release --show-bin-path


2.1. Trabajar con .dockerignore



Para no copiar archivos innecesarios al contexto de compilación (por ejemplo, .git, build/), crea un archivo .dockerignore:



.git.gitignore.build/*.xcodeproj*.xcworkspace.DS_StoreREADME.md


3. Docker Compose para aplicaciones Swift



Si tu proyecto usa una base de datos (PostgreSQL, Redis) o varios microservicios, es conveniente usar docker-compose.yml. Ejemplo para Vapor + PostgreSQL:



version: '3.8'

services: app: build: . ports: - "8080:8080" environment: - DATABASE_HOST=db - DATABASE_PORT=5432 - DATABASE_NAME=vapor_db - DATABASE_USER=vapor_user - DATABASE_PASSWORD=secret depends_on: - db

db: image: postgres:15 environment: POSTGRES_DB: vapor_db POSTGRES_USER: vapor_user POSTGRES_PASSWORD: secret ports:

Blogs

Book Recommendations