介绍:为什么 Swift 开发者需要 Docker?
许多 Swift 开发者(尤其是在 iOS 和 macOS 领域)习惯了 Xcode、模拟器和手动管理依赖。然而,随着服务器端 Swift(例如 Vapor 框架)的流行以及测试和部署自动化的需求,容器化已成为一项必备技能。
Docker 允许您将 Swift 应用程序及其所有依赖项打包到一个隔离的容器中。这确保了代码在本地机器、CI/CD 服务器和生产环境中运行一致。在本文中,我们将探讨如何为 Swift 项目创建 Docker 镜像、优化其大小并在容器中运行它。
1. Swift 的 Docker 基础:Dockerfile 和多阶段构建
容器化 Swift 应用程序的标准方法是使用 多阶段构建。这允许将编译阶段(需要庞大的 Swift 工具)与运行阶段(只需要编译好的二进制文件)分开。
考虑一个典型的 Swift 项目,例如基于 Vapor 的服务器。在项目根目录下创建一个 Dockerfile 文件:
# 第一阶段:构建FROM swift:5.9-focal AS build
WORKDIR /app
# 复制 Package.swift 和 Package.resolved 文件以缓存依赖COPY Package.swift Package.resolved ./RUN swift package resolve
# 复制源代码COPY . .
# 以 release 模式构建RUN swift build -c release --static-swift-stdlib
# 第二阶段:用于运行的最小镜像FROM ubuntu:focal
WORKDIR /app
# 从第一阶段复制构建好的二进制文件COPY --from=build /app/.build/release/Run .
# 开放端口(默认 Vapor 使用 8080)EXPOSE 8080
# 运行应用程序CMD ["./Run"]重要事项:
--static-swift-stdlib— 静态链接 Swift 标准库可减少运行时的依赖。- 在复制源代码之前先复制
Package.swift— 这是一种用于缓存 Docker 依赖层的技巧。 - 基础镜像
ubuntu:focal— 轻量级,但包含所有必要的系统库。
2. 构建和运行容器
现在 Dockerfile 已准备就绪,让我们构建镜像并运行容器:
# 构建镜像docker build -t my-swift-app .
# 在后台运行容器并映射端口docker run -d -p 8080:8080 --name swift-container my-swift-app
# 检查日志docker logs swift-container
# 测试(如果应用程序是 HTTP 服务器)curl http://localhost:8080/如果您使用 Swift Package Manager 而不是 Vapor,二进制文件的名称可能不同。在这种情况下,请修改 COPY --from=build 和 CMD 中的路径。您可以通过以下命令找到确切的二进制文件名称:
swift build -c release --show-bin-path2.1. 使用 .dockerignore
为了避免将不必要的文件(例如 .git、build/)复制到构建上下文中,请创建一个 .dockerignore 文件:
.git.gitignore.build/*.xcodeproj*.xcworkspace.DS_StoreREADME.md3. 用于 Swift 应用程序的 Docker Compose
如果您的项目使用数据库(PostgreSQL、Redis)或多个微服务,使用 docker-compose.yml 会很方便。以下是 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 port