使用 Docker 容器化 Swift 应用:开发者完整指南

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

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

开始课程

为什么 Swift 和 Docker 是服务器开发的理想组合

\n\n

如果您习惯认为 Swift 只用于 iOS 移动开发,那么是时候改变看法了。Swift 正自信地迈向服务器端:Vapor、Kitura、Perfect 等框架让您可以编写快速且安全的后端程序。但有一个问题:如何确保您的应用程序在开发者的 Mac 和生产环境的 Ubuntu 服务器上运行一致?

\n\n

答案就是——使用 Docker 容器化 Swift 应用。Docker 可以打包所有内容:可执行文件本身、系统库、Swift Package Manager (SPM) 依赖项——并且可以在任何地方运行。再也不会有“在我这能运行”和“在我这不行”的问题。

\n\n

在本文中,我们将介绍如何将 Swift 应用程序构建到 Docker 镜像中,优化其大小,配置多阶段构建,甚至为开发添加热重载功能。开始吧!

\n\n

步骤 1. 准备 Swift 应用程序

\n\n

作为示例,我们将使用一个基于 Vapor 的最小 Web 应用程序。如果您还没有项目,请创建一个:

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

将 Vapor 添加到 Package.swift:

\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

最简单的 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

检查项目是否可以在本地编译:swift build。如果一切正常,我们进入容器化步骤。

\n\n

步骤 2. 为 Swift 编写 Dockerfile

\n\n

良好 Swift 容器化的主要秘诀是——多阶段构建。第一阶段,我们编译可执行文件;第二阶段,只复制可执行文件和运行时依赖项。最终镜像大小会缩小 5-10 倍。

\n\n
# ---- 阶段 1:构建 ----\nFROM swift:5.9-jammy AS build\n\nWORKDIR /app\n\n# 复制 Package.swift 和 Package.resolved 以缓存依赖项\nCOPY Package.swift ./\nCOPY Package.resolved ./\n\n# 单独下载依赖项——这会被 Docker 缓存\nRUN swift package resolve\n\n# 复制源代码\nCOPY Sources ./Sources\n\n# 以 release 模式构建\nRUN swift build -c release --static-swift-stdlib\n\n# ---- 阶段 2:运行时 ----\nFROM ubuntu:jammy AS runtime\n\n# 安装 Swift 运行时所需的最小依赖项\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# 仅从构建阶段复制可执行文件\nCOPY --from=build /app/.build/release/MySwiftApp .\n\n# Vapor 默认监听的端口\nEXPOSE 8080\n\nCMD ["./MySwiftApp"]
\n\n

关键点:

\n
    \n
  • --static-swift-stdlib — 静态链接标准库,避免在运行时携带 libswiftCore.so。
  • \n
  • 分离 COPY 操作——先复制 Package.swift,再复制代码。这样 Docker 可以利用层缓存,在修改源代码时不会重新构建依赖项。
  • \n
  • 基础镜像 ubuntu:jammy 大小约为 80 MB,最终镜像大小约为 100-150 MB。
  • \n
\n\n

步骤 3. 构建并运行容器

\n\n

构建镜像:

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

运行:

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

O

博客

书籍推荐