Introduction : Pourquoi la conteneurisation Swift est un défi et un avantage
\nLa conteneurisation d'applications Swift pour iOS et macOS a longtemps été considérée comme l'affaire des passionnés. Contrairement à Go ou Node.js, Swift nécessite une compilation sur la plateforme cible, et les images Docker officielles sont longtemps restées une rareté. Cependant, avec la sortie de Swift 5.x et l'apparition d'images officielles swift:5.10 (et plus récentes), la situation a radicalement changé. Aujourd'hui, Docker permet non seulement d'exécuter des backends serveur sur Vapor, mais aussi d'automatiser la construction d'utilitaires CLI, de tester du code dans un environnement isolé et même de préparer des artefacts binaires pour le déploiement sur macOS.
Dans cet article, nous aborderons des techniques avancées : la construction multi-étapes (multi-stage build), la mise en cache agressive des dépendances, l'optimisation de la taille de l'image et l'intégration avec Swift Package Manager. Les exemples sont orientés vers des projets réels – d'un simple serveur HTTP à un microservice complexe.
\n\n1. Construction multi-étapes : séparer la compilation et l'exécution
\nL'erreur classique des débutants est d'utiliser une seule image pour la construction et l'exécution. En conséquence, l'image pèse >2 Go à cause du SDK, des outils et des sources. La bonne approche est en deux étapes : builder et runner.
\nExemple de Dockerfile pour une application Vapor
\n# Étape 1 : construction\nFROM swift:5.10 AS builder\nWORKDIR /app\nCOPY Package.swift Package.resolved ./\nRUN swift package resolve --cache-path .build/artifacts\nCOPY Sources Sources\nCOPY Tests Tests\nRUN swift build -c release --static-swift-stdlib\n\n# Étape 2 : exécution minimale\nFROM ubuntu:22.04\nRUN apt-get update && apt-get install -y libicu70 libxml2 ca-certificates && rm -rf /var/lib/apt/lists/*\nWORKDIR /app\nCOPY --from=builder /app/.build/release/Run .\nEXPOSE 8080\nCMD ["./Run"]\nPoints clés :
\n- \n
- Mise en cache des dépendances – copier
Package.swiftetPackage.resolvedavant de copier les sources. Docker met en cache la couche, et en cas de modification uniquement du code, seuls les binaires sont reconstruits. \n - Drapeau
--static-swift-stdlib– liaison statique de la bibliothèque standard Swift. Cela réduit les exigences d'exécution, mais augmente la taille du binaire d'environ 30 %. \n - Image minimale – utiliser Ubuntu avec les bibliothèques système nécessaires (
libicu,libxml2). L'image finale fait moins de 150 Mo contre 2 Go avec une construction en une seule étape. \n
2. Mise en cache agressive via BuildKit et agents SSH
\nLors du travail en CI/CD (GitHub Actions, GitLab CI), chaque exécution télécharge à nouveau les dépendances. Utilisez Docker BuildKit pour monter le cache de Swift PM.
\nDockerfile avec mise en cache BuildKit
\n# syntax=docker/dockerfile:1\nFROM swift:5.10 AS builder\nWORKDIR /app\nRUN --mount=type=cache,target=/app/.build/artifacts \\\n --mount=type=bind,source=Package.swift,target=Package.swift \\\n --mount=type=bind,source=Package.resolved,target=Package.resolved \\\n swift package resolve\nCOPY Sources Sources\nRUN --mount=type=cache,target=/app/.build/artifacts \\\n swift build -c release --static-swift-stdlib\nAvantages :
\n- \n
- Cache persistant – les artefacts de dépendances sont conservés entre les builds sur un même hôte. \n
- Agents SSH – si votre
Package.swiftfait référence à des dépôts privés, utilisez--mount=type=sshpour l'authentification sans stocker les clés dans l'image. \n
Pour les hôtes macOS (par exemple, MacStadium), ajoutez impérativement --platform linux/amd64, car Swift sur ARM (M1/M2) nécessite une émulation.
3. Travail avancé avec Swift Package Manager
\nSwift PM n'est pas seulement un gestionnaire de dépendances, mais aussi un outil puissant pour les tests et le linting dans un conteneur.
\nExécution de tests dans un conteneur avec prise en charge de la couverture de code
\nFROM swift:5.10 AS te