Introdução: Por que Docker e Swift são a dupla ideal para o desenvolvimento moderno
O mundo do desenvolvimento para iOS e macOS por muito tempo foi associado exclusivamente ao Xcode e às compilações locais. No entanto, com o surgimento do Swift no servidor (especialmente o framework Vapor) e o crescimento da popularidade da arquitetura de microsserviços, a conteinerização deixou de ser apenas uma tendência e se tornou uma necessidade. Docker para o desenvolvedor Swift não é apenas sobre isolamento de ambiente, mas também sobre uniformidade de compilações, simplicidade de CI/CD e deploy fácil em qualquer servidor.
Neste artigo, abordaremos o ciclo completo de trabalho com Docker e Swift: desde a escrita de um simples Dockerfile para macOS/Linux até a implantação de uma aplicação web completa em Vapor. Você aprenderá como evitar erros comuns e tornar seus contêineres leves e seguros.
Parte principal: Guia passo a passo para conteinerização de Swift
1. Fundamentos: Dockerfile para aplicação Swift (macOS vs Linux)
A primeira coisa a entender: Swift é uma linguagem multiplataforma, mas o Docker tradicionalmente funciona com contêineres Linux. Para desenvolvimento macOS, você pode usar imagens com compilação Linux do Swift (por exemplo, swift:5.9-focal) ou, se o ambiente macOS for essencial, usar virtualização (Docker Desktop for Mac). No entanto, para aplicações de servidor (Vapor, Kitura), as imagens Linux são o padrão.
Dockerfile básico para uma aplicação Swift de servidor (Vapor):
# Usamos a imagem oficial do SwiftFROM swift:5.9-focal AS build
# Definimos o diretório de trabalhoWORKDIR /app
# Copiamos os arquivos Package.swift e Package.resolved para cache de dependênciasCOPY Package.swift Package.resolved ./RUN swift package resolve
# Copiamos o código-fonteCOPY Sources ./SourcesRUN swift build -c release
# Imagem final (mínima)FROM ubuntu:focalWORKDIR /appCOPY --from=build /app/.build/release /appEXPOSE 8080CMD ["./Run"]Esta abordagem usa compilação em múltiplos estágios (multi-stage build): o primeiro estágio compila a aplicação, o segundo cria uma imagem mínima contendo apenas o binário e as bibliotecas necessárias. A imagem final pesa ~60-80 MB em vez de 2 GB.
2. Otimização de imagens: cache e dependências
Swift é uma linguagem compilada, e cada compilação pode levar minutos. Para acelerar o processo, use o cache de camadas do Docker. A técnica chave: primeiro copie Package.swift e Package.resolved, depois execute swift package resolve, e só então copie os fontes. Isso garante que as dependências sejam recompiladas apenas quando Package.swift for alterado, e não a cada mudança de código.
Otimização adicional: usar .dockerignore:
.git.gitignore.build*.xcworkspace*.xcodeprojDerivedDataPackagesREADME.mdTestsIsso impede que arquivos desnecessários (testes, git, projetos Xcode) entrem no contexto de compilação, acelerando a transferência do contexto e reduzindo o tamanho da imagem.
3. Docker Compose: conectando Swift ao banco de dados e cache
Aplicações reais raramente vivem isoladas. Para um backend típico em Vapor, você precisará de PostgreSQL (ou Fluent), Redis para cache e, possivelmente, Nginx. O docker-compose.yml permite executar tudo com um único comando.
Exemplo de docker-compose.yml para aplicação Swift com PostgreSQL e 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: