Docker 与 Swift:从零到一的应用程序容器化

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么 Docker 和 Swift 是现代开发的理想组合

iOS 和 macOS 开发领域长期以来一直与 Xcode 和本地构建紧密相关。然而,随着服务器端 Swift(尤其是 Vapor 框架)的出现以及微服务架构的日益流行,容器化已不仅仅是一种趋势,而是一种必要。对于 Swift 开发者来说,Docker 不仅关乎环境隔离,还关乎构建的一致性、CI/CD 的简便性以及在任何服务器上的轻松部署。

在本文中,我们将介绍使用 Docker 和 Swift 的完整工作流程:从为 macOS/Linux 编写简单的 Dockerfile,到部署一个完整的基于 Vapor 的 Web 应用程序。您将学习如何避免常见错误,并使您的容器变得轻量且安全。



主体部分:Swift 容器化分步指南



1. 基础:Swift 应用程序的 Dockerfile(macOS 与 Linux)

首先需要理解:Swift 是一种跨平台语言,但 Docker 传统上运行在 Linux 容器上。对于 macOS 开发,您可以使用带有 Linux 构建版 Swift 的镜像(例如 swift:5.9-focal),或者,如果 macOS 环境至关重要,则可以使用虚拟化技术(Docker Desktop for Mac)。然而,对于服务器端应用程序(Vapor、Kitura),Linux 镜像是标准选择。

服务器端 Swift 应用程序(Vapor)的基础 Dockerfile:

# 使用官方 Swift 镜像FROM swift:5.9-focal AS build

# 设置工作目录WORKDIR /app

# 复制 Package.swift 和 Package.resolved 文件以缓存依赖COPY Package.swift Package.resolved ./RUN swift package resolve

# 复制源代码COPY Sources ./SourcesRUN swift build -c release

# 最终镜像(最小化)FROM ubuntu:focalWORKDIR /appCOPY --from=build /app/.build/release /appEXPOSE 8080CMD ["./Run"]

这种方法使用了多阶段构建:第一阶段编译应用程序,第二阶段创建一个仅包含二进制文件和必要库的最小化镜像。最终镜像大小约为 60-80 MB,而不是 2 GB。



2. 镜像优化:缓存与依赖

Swift 是一种编译型语言,每次构建可能需要几分钟。为了加速这一过程,请利用 Docker 的层缓存。关键技巧:首先复制 Package.swift 和 Package.resolved,然后执行 swift package resolve,最后再复制源代码。这确保了依赖项仅在 Package.swift 发生变化时才重新构建,而不是在每次代码更改时都重新构建。

另一个优化是使用 .dockerignore:

.git.gitignore.build*.xcworkspace*.xcodeprojDerivedDataPackagesREADME.mdTests

这可以防止不必要的文件(测试文件、git 文件、Xcode 项目文件)进入构建上下文,从而加快上下文传输速度并减小镜像大小。



3. Docker Compose:将 Swift 与数据库和缓存连接起来

实际应用程序很少孤立运行。对于典型的 Vapor 后端,您将需要 PostgreSQL(或 Fluent)、用于缓存的 Redis,可能还需要 Nginx。docker-compose.yml 允许您通过一条命令启动所有服务。

包含 PostgreSQL 和 Redis 的 Swift 应用程序的 docker-compose.yml 示例:

version: '3.8'services:  app:    build: .    ports:      - "8080:8080"    environment:      - DATABASE_HOST=db      - DATABASE_PORT=5432      - REDIS_HOST=redis      - REDIS_PORT=6379    depends_on:      - db      - redis    restart: unless-stopped

db: image: postgres:15-alpine environment: POSTGRES_DB: myapp POSTGRES_USER: user POSTGRES_PASSWORD: password volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432"

redis: image:

博客

书籍推荐