Introduction : pourquoi un développeur Swift a-t-il besoin de Docker ?
De nombreux développeurs Swift (en particulier dans le monde iOS et macOS) sont habitués à Xcode, aux simulateurs et à la gestion manuelle des dépendances. Cependant, avec la popularité croissante du Swift côté serveur (par exemple, le framework Vapor) et la nécessité d'automatiser les tests et le déploiement, la conteneurisation devient une compétence obligatoire.
Docker permet d'empaqueter votre application Swift avec toutes ses dépendances dans un conteneur isolé. Cela garantit que le code fonctionnera de la même manière sur la machine locale, sur le serveur CI/CD et en production. Dans cet article, nous allons voir comment créer une image Docker pour un projet Swift, optimiser sa taille et l'exécuter dans un conteneur.
1. Les bases de Docker pour Swift : Dockerfile et construction multi-étapes
L'approche standard pour la conteneurisation d'applications Swift est l'utilisation de la construction multi-étapes. Cela permet de séparer l'étape de compilation (où les outils Swift lourds sont nécessaires) et l'étape d'exécution (où seul le binaire compilé est suffisant).
Considérons un projet Swift typique, par exemple un serveur Vapor. Créons un fichier Dockerfile à la racine du projet :
# Première étape : constructionFROM swift:5.9-focal AS build
WORKDIR /app
# Copie des fichiers Package.swift et Package.resolved pour la mise en cache des dépendancesCOPY Package.swift Package.resolved ./RUN swift package resolve
# Copie du code sourceCOPY . .
# Construction en mode releaseRUN swift build -c release --static-swift-stdlib
# Deuxième étape : image minimale pour l'exécutionFROM ubuntu:focal
WORKDIR /app
# Copie du binaire compilé depuis la première étapeCOPY --from=build /app/.build/release/Run .
# Ouverture du port (par défaut, Vapor utilise le 8080)EXPOSE 8080
# Lancement de l'applicationCMD ["./Run"]Points importants :
--static-swift-stdlib— la liaison statique de la bibliothèque standard Swift réduit les dépendances au moment de l'exécution.- La copie de
Package.swiftavant les sources est une astuce pour mettre en cache la couche des dépendances Docker. - L'image de base
ubuntu:focalest légère mais contient toutes les bibliothèques système nécessaires.
2. Construction et exécution du conteneur
Maintenant que le Dockerfile est prêt, construisons l'image et lançons le conteneur :
# Construction de l'imagedocker build -t my-swift-app .
# Lancement du conteneur en arrière-plan avec redirection de portdocker run -d -p 8080:8080 --name swift-container my-swift-app
# Vérification des logsdocker logs swift-container
# Test (si l'application est un serveur HTTP)curl http://localhost:8080/Si vous utilisez Swift Package Manager sans Vapor, le binaire peut avoir un nom différent. Dans ce cas, modifiez le chemin dans COPY --from=build et CMD. Vous pouvez connaître le nom exact du binaire avec la commande :
swift build -c release --show-bin-path2.1. Travailler avec .dockerignore
Pour éviter de copier des fichiers inutiles dans le contexte de construction (par exemple, .git, build/), créez un fichier .dockerignore :
.git.gitignore.build/*.xcodeproj*.xcworkspace.DS_StoreREADME.md3. Docker Compose pour les applications Swift
Si votre projet utilise une base de données (PostgreSQL, Redis) ou plusieurs microservices, il est pratique d'utiliser docker-compose.yml. Exemple pour 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: