Containerisierung von Swift-Anwendungen mit Docker: Vollständiger Leitfaden für Entwickler

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Warum Swift und Docker das ideale Paar für die Serverentwicklung sind

\n\n

Wenn Sie gewohnt sind zu denken, dass Swift nur für die mobile Entwicklung unter iOS gedacht ist, wird es Zeit, sich zu wundern. Swift macht sich selbstbewusst auf die Serverseite: Vapor, Kitura, Perfect – Frameworks, die es ermöglichen, schnelle und sichere Backends zu schreiben. Aber es gibt ein Problem: Wie kann man garantieren, dass Ihre Anwendung sowohl auf dem Mac des Entwicklers als auch auf dem Produktionsserver unter Ubuntu gleich funktioniert?

\n\n

Die Antwort ist Containerisierung von Swift-Anwendungen mit Docker. Docker ermöglicht es, alles zu packen: die Binärdatei selbst, Systembibliotheken, Abhängigkeiten des Swift Package Manager (SPM) – und dies überall auszuführen. Kein „bei mir funktioniert es“ und „bei mir nicht“.

\n\n

In diesem Artikel werden wir durchgehen, wie man eine Swift-Anwendung in ein Docker-Image baut, seine Größe optimiert, einen mehrstufigen Build einrichtet und sogar Hot Reload für die Entwicklung hinzufügt. Los geht's!

\n\n

Schritt 1. Vorbereitung der Swift-Anwendung

\n\n

Als Beispiel nehmen wir eine minimale Webanwendung mit Vapor. Wenn Sie noch kein Projekt haben, erstellen Sie es:

\n\n
mkdir MySwiftApp && cd MySwiftApp\nswift package init --type executable
\n\n

Fügen wir Vapor in Package.swift hinzu:

\n\n
// swift-tools-version:5.7\nimport PackageDescription\n\nlet package = Package(\n    name: "MySwiftApp",\n    dependencies: [\n        .package(url: "https://github.com/vapor/vapor.git", from: "4.89.0")\n    ],\n    targets: [\n        .executableTarget(\n            name: "MySwiftApp",\n            dependencies: [\n                .product(name: "Vapor", package: "vapor")\n            ]\n        )\n    ]\n)
\n\n

Der einfachste main.swift:

\n\n
import Vapor\n\nvar env = try Environment.detect()\ntry LoggingSystem.bootstrap(from: &env)\nlet app = Application(env)\ndefer { app.shutdown() }\n\napp.get("hello") { req -> String in\n    return "Hello from Swift in Docker!"\n}\n\ntry app.run()
\n\n

Überprüfen Sie, ob das Projekt lokal kompiliert: swift build. Wenn alles in Ordnung ist, gehen wir zur Containerisierung über.

\n\n

Schritt 2. Dockerfile für Swift schreiben

\n\n

Das Hauptgeheimnis einer guten Containerisierung von Swift ist der mehrstufige Build. In der ersten Phase kompilieren wir die Binärdatei, in der zweiten kopieren wir nur diese und die Laufzeitabhängigkeiten. Das resultierende Image ist 5-10 Mal kleiner.

\n\n
# ---- Phase 1: Build ----\nFROM swift:5.9-jammy AS build\n\nWORKDIR /app\n\n# Kopieren von Package.swift und Package.resolved zum Caching der Abhängigkeiten\nCOPY Package.swift ./\nCOPY Package.resolved ./\n\n# Abhängigkeiten separat herunterladen – dies wird von Docker gecacht\nRUN swift package resolve\n\n# Quellcode kopieren\nCOPY Sources ./Sources\n\n# Build im Release-Modus\nRUN swift build -c release --static-swift-stdlib\n\n# ---- Phase 2: Runtime ----\nFROM ubuntu:jammy AS runtime\n\n# Minimale Abhängigkeiten für Swift-Runtime installieren\nRUN apt-get update && apt-get install -y \\\n    libicu70 \\\n    libcurl4 \\\n    libxml2 \\\n    && rm -rf /var/lib/apt/lists/*\n\nWORKDIR /app\n\n# Nur die Binärdatei aus der Build-Phase kopieren\nCOPY --from=build /app/.build/release/MySwiftApp .\n\n# Port, den Vapor standardmäßig abhört\nEXPOSE 8080\n\nCMD ["./MySwiftApp"]
\n\n

Wichtige Punkte:

\n
    \n
  • --static-swift-stdlib – statisches Linken der Standardbibliothek, um libswiftCore.so nicht in die Runtime mitzunehmen.
  • \n
  • Aufteilung von COPY – zuerst Package.swift, dann der Code. So nutzt Docker den Layer-Cache und baut Abhängigkeiten bei Änderungen am Quellcode nicht neu.
  • \n
  • Das Basis-Image ubuntu:jammy wiegt ~80 MB, das resultierende Image etwa 100-150 MB.
  • \n
\n\n

Schritt 3. Build und Start des Containers

\n\n

Image bauen:

\n\n
docker build -t my-swift-app .
\n\n

Starten:

\n\n
docker run -p 8080:8080 my-swift-app
\n\n

O

Blogs

Buchempfehlungen