Einleitung: Warum ein Swift-Entwickler Docker braucht
Viele Swift-Entwickler (insbesondere in der iOS- und macOS-Welt) sind an Xcode, Simulatoren und manuelles Abhängigkeitsmanagement gewöhnt. Mit der wachsenden Beliebtheit von Server-Side Swift (z. B. dem Framework Vapor) und der Notwendigkeit, Tests und Deployments zu automatisieren, wird Containerisierung jedoch zu einer unverzichtbaren Fähigkeit.
Docker ermöglicht es, Ihre Swift-Anwendung zusammen mit allen Abhängigkeiten in einen isolierten Container zu packen. Dies stellt sicher, dass der Code auf dem lokalen Rechner, auf dem CI/CD-Server und in der Produktion identisch funktioniert. In diesem Artikel werden wir erläutern, wie man ein Docker-Image für ein Swift-Projekt erstellt, dessen Größe optimiert und es in einem Container ausführt.
1. Docker-Grundlagen für Swift: Dockerfile und Multi-Stage-Build
Der Standardansatz zur Containerisierung von Swift-Anwendungen ist die Verwendung eines Multi-Stage-Builds. Dies ermöglicht die Trennung der Kompilierungsphase (in der die schweren Swift-Tools benötigt werden) von der Ausführungsphase (in der nur die kompilierte Binärdatei ausreicht).
Betrachten wir ein typisches Swift-Projekt, z. B. einen Vapor-Server. Erstellen wir eine Datei Dockerfile im Projektstammverzeichnis:
# Erste Stufe: BuildFROM swift:5.9-focal AS build
WORKDIR /app
# Kopieren von Package.swift und Package.resolved zum Caching der AbhängigkeitenCOPY Package.swift Package.resolved ./RUN swift package resolve
# Kopieren des QuellcodesCOPY . .
# Build im Release-ModusRUN swift build -c release --static-swift-stdlib
# Zweite Stufe: Minimales Image für die AusführungFROM ubuntu:focal
WORKDIR /app
# Kopieren der erstellten Binärdatei aus der ersten StufeCOPY --from=build /app/.build/release/Run .
# Port freigeben (standardmäßig verwendet Vapor 8080)EXPOSE 8080
# Anwendung startenCMD ["./Run"]Wichtige Punkte:
--static-swift-stdlib– statisches Linken der Swift-Standardbibliothek reduziert Abhängigkeiten zur Laufzeit.- Das Kopieren von
Package.swiftvor dem Quellcode ist ein Trick zum Caching der Docker-Abhängigkeitsebene. - Das Basis-Image
ubuntu:focalist leichtgewichtig, enthält aber alle notwendigen Systembibliotheken.
2. Container bauen und ausführen
Nachdem das Dockerfile fertig ist, bauen wir das Image und starten den Container:
# Image bauendocker build -t my-swift-app .
# Container im Hintergrund mit Portweiterleitung startendocker run -d -p 8080:8080 --name swift-container my-swift-app
# Logs überprüfendocker logs swift-container
# Testen (wenn die Anwendung ein HTTP-Server ist)curl http://localhost:8080/Wenn Sie Swift Package Manager ohne Vapor verwenden, kann die Binärdatei anders heißen. Ändern Sie in diesem Fall den Pfad in COPY --from=build und CMD. Den genauen Namen der Binärdatei erfahren Sie mit dem Befehl:
swift build -c release --show-bin-path2.1. Arbeiten mit .dockerignore
Um zu vermeiden, dass unnötige Dateien (z. B. .git, build/) in den Build-Kontext kopiert werden, erstellen Sie eine .dockerignore-Datei:
.git.gitignore.build/*.xcodeproj*.xcworkspace.DS_StoreREADME.md3. Docker Compose für Swift-Anwendungen
Wenn Ihr Projekt eine Datenbank (PostgreSQL, Redis) oder mehrere Microservices verwendet, ist die Verwendung von docker-compose.yml praktisch. Ein Beispiel für 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: