从零到部署:Swifton框架极速Web开发实战指南
引言:Swift开发者的Web框架困境与解决方案
你是否曾为Swift语言缺乏像Ruby on Rails或Django那样成熟的Web开发框架而苦恼?作为一门以安全和性能著称的语言,Swift在服务端开发领域一直未能形成生态优势。Swifton框架的出现正是为了解决这一痛点——它将Ruby on Rails的开发理念引入Swift世界,提供了一套完整的MVC架构、自动化路由和模板系统,让Swift开发者也能体验"约定优于配置"的高效开发模式。本文将带你全面掌握Swifton框架,从环境搭建到生产部署,构建一个功能完备的Web应用。
读完本文你将获得:
- 快速搭建Swifton开发环境的完整步骤
- 掌握MVC架构在Swifton中的实现方式
- 学会路由配置、控制器设计和视图渲染的核心技巧
- 实现数据持久化与JSON API开发
- 部署Swifton应用到Linux服务器的最佳实践
Swifton框架概述:Rails风格的Swift Web开发体验
项目定位与核心特性
Swifton是一个受Ruby on Rails启发的Swift Web框架,支持Linux和macOS双平台运行。其核心设计目标是提供"开箱即用"的Web开发体验,主要特性包括:
| 特性 | 说明 | 优势 |
|---|---|---|
| conventions-over-configuration | 遵循Rails式约定优于配置原则 | 减少80%的样板代码 |
| 完整MVC架构 | 分离模型、视图、控制器职责 | 代码组织更清晰 |
| 资源路由自动生成 | 一行代码生成RESTful路由集合 | 路由配置效率提升60% |
| Stencil模板引擎 | Mustache风格的HTML模板系统 | 前端设计与后端逻辑解耦 |
| 跨平台支持 | 同时运行于Linux和macOS | 开发与部署环境一致性 |
| S4协议兼容 | 支持所有S4标准的HTTP服务器 | 部署选项灵活多样 |
⚠️ 注意:根据项目README最新说明,由于Swift语言当前的静态特性限制,Swifton项目已暂停活跃开发。本文内容基于最新可用版本,适合学习Swift Web开发思想及框架设计原理。
技术架构与依赖生态
Swifton的技术栈构建在多个优秀的Swift开源项目之上,其Package.swift定义的核心依赖包括:
let package = Package(
name: "Swifton",
dependencies: [
.Package(url: "https://github.com/necolt/Stencil.git", versions: Version(0,5,6)..<Version(1,0,0)),
.Package(url: "https://github.com/Zewo/String.git", majorVersion: 0, minor: 7),
.Package(url: "https://github.com/open-swift/S4.git", majorVersion: 0, minor: 6),
.Package(url: "https://github.com/Zewo/Router.git", majorVersion: 0, minor: 6)
]
)
核心组件架构如下:
环境搭建:从零配置Swifton开发环境
系统要求与前置条件
Swifton开发环境需要满足以下条件:
- Swift 3.0+开发工具链(推荐使用swiftenv管理版本)
- macOS 10.11+或Linux(Ubuntu 14.04+/CentOS 7+)
- git版本控制工具
- 基础编译工具(Linux需要安装build-essential)
快速安装步骤
macOS环境配置
# 1. 安装swiftenv版本管理器
brew install swiftenv
# 2. 配置环境变量(~/.bash_profile或~/.zshrc)
echo 'if which swiftenv > /dev/null; then eval "$(swiftenv init -)"; fi' >> ~/.bash_profile
source ~/.bash_profile
# 3. 安装指定版本Swift
swiftenv install 3.1.1
swiftenv global 3.1.1
# 4. 验证安装
swift --version # 应显示Swift 3.1.1版本信息
# 5. 克隆项目仓库
git clone https://gitcode.com/gh_mirrors/sw/Swifton
cd Swifton
Linux环境配置(Ubuntu)
# 1. 安装依赖包
sudo apt-get update
sudo apt-get install -y clang libicu-dev git libcurl4-openssl-dev libssl-dev uuid-dev
# 2. 安装swiftenv
git clone https://github.com/kylef/swiftenv.git ~/.swiftenv
echo 'export SWIFTENV_ROOT="$HOME/.swiftenv"' >> ~/.bashrc
echo 'export PATH="$SWIFTENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(swiftenv init -)"' >> ~/.bashrc
source ~/.bashrc
# 3. 安装Swift
swiftenv install 3.1.1
swiftenv global 3.1.1
# 4. 克隆项目
git clone https://gitcode.com/gh_mirrors/sw/Swifton
cd Swifton
项目构建与验证
# 构建项目
swift build
# 运行测试(若测试失败可清理测试缓存)
swift test
# 如遇测试崩溃可尝试: rm -r Packages/*/Tests
核心功能详解:构建RESTful Web应用
路由系统:RESTful资源的自动映射
Swifton的路由系统借鉴了Rails的资源路由理念,能够通过一行代码生成完整的RESTful路由集合。
资源路由定义
// main.swift中定义路由
let router = Router.create { route in
route.resources("todos", controller: TodosController())
}
上述代码等效于手动定义以下7个路由:
| HTTP方法 | 路径 | 控制器动作 | 说明 |
|---|---|---|---|
| GET | /todos | index | 列表展示 |
| GET | /todos/new | new | 创建表单 |
| POST | /todos | create | 提交创建 |
| GET | /todos/{id} | show | 详情展示 |
| GET | /todos/{id}/edit | edit | 编辑表单 |
| PATCH | /todos/{id} | update | 更新资源 |
| DELETE | /todos/{id} | destroy | 删除资源 |
自定义路由配置
除资源路由外,Swifton也支持灵活的自定义路由:
// 基本路由定义
router.get("/", HomeController()["index"])
router.post("/login", SessionsController()["create"])
router.get("/about", PagesController()["about"])
// 带参数的路由
router.get("/users/{username}", UsersController()["show"])
router.get("/posts/{year}/{month}", PostsController()["archive"])
// 路由组
router.group("/admin") { admin in
admin.get("/dashboard", AdminController()["dashboard"])
admin.get("/users", AdminController()["users"])
}
路由分发流程
控制器:请求处理的核心中枢
控制器是Swifton应用的业务逻辑核心,负责处理请求、协调模型与视图。
控制器基础结构
import Swifton
class TodosController: ApplicationController {
// 共享变量
var todo: Todo?
override func controller() {
super.controller()
// 前置过滤器配置
beforeAction("setTodo", only: ["show", "edit", "update", "destroy"])
// 定义动作
action("index") { request in
let todos = ["todos": Todo.allAttributes()]
return render("Todos/Index", todos)
}
action("show") { request in
return render("Todos/Show", self.todo)
}
// 其他动作...
}
// 过滤器实现
filter("setTodo") { request in
guard let t = Todo.find(request.params["id"]) else {
return self.redirectTo("/todos")
}
self.todo = t as? Todo
return self.next // 继续执行后续过滤器或动作
}
}
控制器过滤器机制
Swifton支持前置(beforeAction)和后置(afterAction)过滤器,用于在动作执行前后处理通用逻辑:
class ApplicationController: Controller {
override func controller() {
// 对所有动作生效的前置过滤器
beforeAction("authenticateUser")
// 仅对指定动作生效的后置过滤器
afterAction("logAction", only: ["create", "update", "destroy"])
}
filter("authenticateUser") { request in
guard let _ = request.session["user_id"] else {
return redirectTo("/login")
}
return self.next
}
filter("logAction") { request in
let logEntry = "\(request.method) \(request.path) - \(Date())"
print(logEntry)
return self.next
}
}
多格式响应处理
Swifton控制器支持基于Accept请求头的多格式响应:
action("show") { request in
return respondTo(request, [
"html": {
// HTML响应 - 渲染模板
render("Todos/Show", self.todo)
},
"json": {
// JSON响应 - 返回数据
renderJSON(self.todo)
},
"xml": {
// XML响应 - 自定义处理
Response(status: .ok, body: self.todo?.toXML())
}
])
}
模型系统:数据持久化与业务逻辑
Swifton本身是ORM无关的框架,官方提供了简单的内存模型实现,同时支持多种ORM解决方案。
内存模型使用(MemoryModel)
import Swifton
// 定义模型
class Todo: MemoryModel {
// 自动继承id、created_at、updated_at字段
// 自定义属性访问器
var title: String {
get { return self["title"] as! String }
set { self["title"] = newValue }
}
var completed: Bool {
get { return self["completed"] as? Bool ?? false }
set { self["completed"] = newValue }
}
// 自定义方法
func markAsCompleted() {
self.completed = true
self.save()
}
}
// 模型操作示例
func demonstrateTodoOperations() {
// 创建记录
let todo = Todo.create([
"title": "学习Swifton",
"completed": false
])
// 查询记录
let allTodos = Todo.all()
let firstTodo = Todo.first()
let todo3 = Todo.find(3)
let pendingTodos = Todo.filter { $0["completed"] as! Bool == false }
// 更新记录
if let todo = Todo.find(1) {
todo.update(["title": "掌握Swifton控制器"])
// 或直接修改属性
todo.title = "掌握Swifton模型"
todo.save()
}
// 删除记录
if let todo = Todo.find(2) {
Todo.destroy(todo)
}
}
第三方ORM集成
对于生产环境,建议使用更成熟的ORM解决方案:
- Fluent (SQLite/MySQL/PostgreSQL)
import Fluent
class Todo: Model {
let storage = Storage()
var title: String
var completed: Bool
init(title: String, completed: Bool = false) {
self.title = title
self.completed = completed
}
// Fluent协议实现...
}
- PostgreSQL适配器
import PostgreSQL
class Todo {
let id: Int?
let title: String
let completed: Bool
init(id: Int? = nil, title: String, completed: Bool = false) {
self.id = id
self.title = title
self.completed = completed
}
// PostgreSQL查询方法...
}
视图系统:Stencil模板引擎
Swifton使用Stencil模板引擎渲染HTML视图,支持模板继承、条件判断、循环等功能。
模板基本语法
<!-- Views/Layouts/Main.html.stencil -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Swifton应用{% endblock %}</title>
<link rel="stylesheet" href="/css/application.css">
</head>
<body>
<header>
<h1>{% block header %}我的应用{% endblock %}</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
{% block footer %}© 2023 Swifton应用{% endblock %}
</footer>
</body>
</html>
视图继承与片段
<!-- Views/Todos/Index.html.stencil -->
{% extends "Layouts/Main.html.stencil" %}
{% block title %}待办事项列表{% endblock %}
{% block content %}
<h2>待办事项</h2>
<a href="/todos/new">添加新事项</a>
<table>
<thead>
<tr>
<th>标题</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for todo in todos %}
<tr>
<td>{{ todo.title }}</td>
<td>{{ todo.completed ? "已完成" : "未完成" }}</td>
<td>
<a href="/todos/{{ todo.id }}">查看</a>
<a href="/todos/{{ todo.id }}/edit">编辑</a>
<form action="/todos/{{ todo.id }}" method="post" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<button type="submit">删除</button>
</form>
</td>
</tr>
{% empty %}
<tr>
<td colspan="3">暂无待办事项</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
模板变量与过滤器
Stencil模板支持丰富的变量类型和过滤器:
<!-- 变量访问 -->
{{ user.name }}
{{ post.content|truncatechars:100 }}
{{ date|date:"Y-m-d" }}
<!-- 条件判断 -->
{% if user.isAdmin %}
<a href="/admin">管理面板</a>
{% endif %}
<!-- 循环 -->
{% for item in items %}
<li>{{ forloop.index }}. {{ item.name }}</li>
{% endfor %}
<!-- 包含其他模板 -->
{% include "Shared/Navigation.html.stencil" %}
<!-- 宏定义 -->
{% macro user_card(user) %}
<div class="user-card">
<h3>{{ user.name }}</h3>
<p>{{ user.bio }}</p>
</div>
{% endmacro %}
{% for user in users %}
{{ user_card(user) }}
{% endfor %}
中间件:请求处理的管道机制
中间件允许在请求到达控制器之前或响应发送给客户端之前处理HTTP请求/响应。
中间件实现
import Swifton
import S4
// 日志中间件
class LoggingMiddleware: Middleware {
func respond(to request: Request, chainingTo next: Responder) throws -> Response {
// 请求处理前
let startTime = Date()
// 调用下一个中间件或路由
let response = try next.respond(to: request)
// 请求处理后
let duration = Date().timeIntervalSince(startTime) * 1000
print("\(request.method) \(request.uri.path) - \(response.status.code) (\(duration)ms)")
return response
}
}
// 错误处理中间件
class ErrorHandlingMiddleware: Middleware {
func respond(to request: Request, chainingTo next: Responder) throws -> Response {
do {
return try next.respond(to: request)
} catch {
let errorPage = """
<html>
<head><title>Error</title></head>
<body>
<h1>500 Internal Server Error</h1>
<p>\(error.localizedDescription)</p>
</body>
</html>
"""
return Response(status: .internalServerError, body: errorPage)
}
}
}
中间件配置
// main.swift中配置中间件链
let app = ErrorHandlingMiddleware().chain(
LoggingMiddleware().chain(
CookiesMiddleware().chain(
ParametersMiddleware().chain(router)
)
)
)
// 启动服务器
serve { request in
app.respond(to: request)
}
常用内置中间件
Swifton提供了几个常用中间件:
- CookiesMiddleware - 处理Cookie
- ParametersMiddleware - 解析请求参数
- SessionMiddleware - 会话管理
- StaticMiddleware - 静态文件服务
实战案例:构建Todo应用
项目结构设计
SwiftonTodo/
├── Package.swift
├── Sources/
│ ├── TodoApp/
│ │ ├── main.swift
│ │ ├── Controllers/
│ │ │ ├── ApplicationController.swift
│ │ │ └── TodosController.swift
│ │ ├── Models/
│ │ │ └── Todo.swift
│ │ └── Views/
│ │ ├── Layouts/
│ │ │ └── Main.html.stencil
│ │ └── Todos/
│ │ ├── Index.html.stencil
│ │ ├── Show.html.stencil
│ │ ├── New.html.stencil
│ │ └── Edit.html.stencil
├── Public/
│ ├── css/
│ │ └── application.css
│ └── js/
│ └── application.js
└── Tests/
└── TodoAppTests/
└── TodoTests.swift
1. 创建项目与依赖配置
Package.swift
import PackageDescription
let package = Package(
name: "TodoApp",
dependencies: [
.Package(url: "https://gitcode.com/gh_mirrors/sw/Swifton.git",
versions: Version(0,1,0)..<Version(1,0,0))
]
)
2. 实现数据模型
Sources/TodoApp/Models/Todo.swift
import Swifton
class Todo: MemoryModel {
var title: String {
get { return self["title"] as! String }
set { self["title"] = newValue }
}
var completed: Bool {
get { return self["completed"] as? Bool ?? false }
set { self["completed"] = newValue }
}
static func allAttributes() -> [[String: Any]] {
return all().map { $0.attributes }
}
}
3. 实现控制器
Sources/TodoApp/Controllers/ApplicationController.swift
import Swifton
class ApplicationController: Controller {
override func controller() {
super.controller()
// 应用级别的过滤器和配置
}
}
Sources/TodoApp/Controllers/TodosController.swift
import Swifton
class TodosController: ApplicationController {
var todo: Todo?
override func controller() {
super.controller()
beforeAction("setTodo", only: ["show", "edit", "update", "destroy"])
action("index") { request in
let todos = ["todos": Todo.allAttributes()]
return render("Todos/Index", todos)
}
action("new") { request in
return render("Todos/New")
}
action("create") { request in
guard let title = request.params["title"] as? String, !title.isEmpty else {
return redirectTo("/todos/new", flash: [
"error": "标题不能为空"
])
}
Todo.create([
"title": title,
"completed": request.params["completed"] as? Bool ?? false
])
return redirectTo("/todos", flash: [
"notice": "待办事项创建成功"
])
}
action("show") { request in
guard let todo = self.todo else {
return redirectTo("/todos", flash: [
"error": "待办事项不存在"
])
}
return render("Todos/Show", todo.attributes)
}
action("edit") { request in
guard let todo = self.todo else {
return redirectTo("/todos", flash: [
"error": "待办事项不存在"
])
}
return render("Todos/Edit", todo.attributes)
}
action("update") { request in
guard let todo = self.todo else {
return redirectTo("/todos", flash: [
"error": "待办事项不存在"
])
}
guard let title = request.params["title"] as? String, !title.isEmpty else {
return redirectTo("/todos/\(todo.id!)/edit", flash: [
"error": "标题不能为空"
])
}
todo.update([
"title": title,
"completed": request.params["completed"] as? Bool ?? false
])
return redirectTo("/todos/\(todo.id!)", flash: [
"notice": "待办事项更新成功"
])
}
action("destroy") { request in
guard let todo = self.todo else {
return redirectTo("/todos", flash: [
"error": "待办事项不存在"
])
}
Todo.destroy(todo)
return redirectTo("/todos", flash: [
"notice": "待办事项已删除"
])
}
}
filter("setTodo") { request in
guard let id = request.params["id"],
let todo = Todo.find(id) as? Todo else {
return self.redirectTo("/todos", flash: [
"error": "待办事项不存在"
])
}
self.todo = todo
return self.next
}
}
4. 创建视图模板
Sources/TodoApp/Views/Layouts/Main.html.stencil
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Todo App{% endblock %}</title>
<link rel="stylesheet" href="/css/application.css">
</head>
<body>
<header>
<h1>Todo App</h1>
<nav>
<a href="/todos">待办事项</a>
</nav>
</header>
<main>
{% if flash.notice %}
<div class="flash notice">{{ flash.notice }}</div>
{% endif %}
{% if flash.error %}
<div class="flash error">{{ flash.error }}</div>
{% endif %}
{% block content %}{% endblock %}
</main>
<footer>
<p>Powered by Swifton</p>
</footer>
</body>
</html>
Sources/TodoApp/Views/Todos/Index.html.stencil
{% extends "Layouts/Main.html.stencil" %}
{% block title %}待办事项列表{% endblock %}
{% block content %}
<div class="page-header">
<h2>待办事项</h2>
<a href="/todos/new" class="btn">添加新事项</a>
</div>
<table class="todos-table">
<thead>
<tr>
<th>标题</th>
<th>状态</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for todo in todos %}
<tr>
<td>{{ todo.title }}</td>
<td>{{ todo.completed ? "✓ 已完成" : "○ 未完成" }}</td>
<td>{{ todo.created_at|date:"yyyy-MM-dd HH:mm" }}</td>
<td class="actions">
<a href="/todos/{{ todo.id }}" class="btn btn-small">查看</a>
<a href="/todos/{{ todo.id }}/edit" class="btn btn-small">编辑</a>
<form action="/todos/{{ todo.id }}" method="post" class="inline-form">
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="btn btn-small btn-danger">删除</button>
</form>
</td>
</tr>
{% empty %}
<tr>
<td colspan="4" class="empty-state">暂无待办事项,点击"添加新事项"创建</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
Sources/TodoApp/Views/Todos/New.html.stencil
{% extends "Layouts/Main.html.stencil" %}
{% block title %}创建新待办事项{% endblock %}
{% block content %}
<div class="page-header">
<h2>创建新待办事项</h2>
<a href="/todos">返回列表</a>
</div>
<form action="/todos" method="post" class="todo-form">
<div class="form-group">
<label for="title">标题</label>
<input type="text" id="title" name="title" required>
</div>
<div class="form-group">
<label>
<input type="checkbox" name="completed" value="true">
标记为已完成
</label>
</div>
<div class="form-actions">
<button type="submit" class="btn">创建</button>
<a href="/todos" class="btn btn-secondary">取消</a>
</div>
</form>
{% endblock %}
5. 配置主程序入口
Sources/TodoApp/main.swift
import Swifton
import S4Venice
// 配置视图和静态文件目录
SwiftonConfig.viewsDirectory = "./Sources/TodoApp/Views"
SwiftonConfig.publicDirectory = "./Public"
// 定义路由
let router = Router.create { route in
route.get("/", TodosController()["index"])
route.resources("todos", controller: TodosController())
}
// 配置中间件
let app = CookiesMiddleware().chain(
ParametersMiddleware().chain(router)
)
// 启动服务器
print("Server starting on http://0.0.0.0:8000")
serve(HTTPHost(ipv4: .any, port: 8000)) { request in
return app.respond(to: request)
}
6. 添加静态样式
Public/css/application.css
/* 基础样式 */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
/* 布局组件 */
header {
padding: 20px 0;
border-bottom: 1px solid #eee;
margin-bottom: 30px;
}
header h1 {
margin-bottom: 10px;
}
nav a {
margin-right: 15px;
}
footer {
margin-top: 50px;
padding-top: 20px;
border-top: 1px solid #eee;
color: #777;
text-align: center;
}
main {
min-height: 400px;
}
.page-header {
margin-bottom: 30px;
}
.page-header h2 {
margin-bottom: 15px;
}
/* 表单样式 */
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
input[type="text"],
textarea,
select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
/* 按钮样式 */
.btn {
display: inline-block;
padding: 10px 15px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
text-decoration: none;
font-size: 14px;
}
.btn-secondary {
background-color: #6c757d;
}
.btn-danger {
background-color: #dc3545;
}
.btn-small {
padding: 5px 10px;
font-size: 12px;
}
/* 表格样式 */
.todos-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
}
.todos-table th,
.todos-table td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.todos-table th {
background-color: #f8f9fa;
font-weight: bold;
}
.todos-table .empty-state {
text-align: center;
padding: 40px;
color: #666;
}
/* 提示消息 */
.flash {
padding: 15px;
margin-bottom: 20px;
border-radius: 4px;
}
.flash.notice {
background-color: #d4edda;
color: #155724;
}
.flash.error {
background-color: #f8d7da;
color: #721c24;
}
/* 辅助样式 */
.inline-form {
display: inline;
}
.form-actions {
margin-top: 20px;
}
.empty-state {
text-align: center;
padding: 40px;
color: #666;
}
7. 构建并运行应用
# 构建项目
swift build
# 运行应用
.build/debug/TodoApp
访问 http://0.0.0.0:8000 即可使用Todo应用。
部署与扩展:从开发到生产环境
构建发布版本
# 构建优化版本
swift build --configuration release
# 查看构建产物
ls -lh .build/release/TodoApp
Linux服务器部署
基本部署流程
# 在服务器上安装依赖
sudo apt-get install -y libicu-dev libcurl4-openssl-dev
# 传输构建产物
scp .build/release/TodoApp user@server:/opt/todoapp/
# 在服务器上创建必要目录
ssh user@server "mkdir -p /opt/todoapp/{Views,Public}"
# 传输视图和静态文件
scp -r Sources/TodoApp/Views user@server:/opt/todoapp/
scp -r Public user@server:/opt/todoapp/
# 启动应用
ssh user@server "cd /opt/todoapp && ./TodoApp"
使用Systemd管理服务
创建服务文件 /etc/systemd/system/todoapp.service:
[Unit]
Description=Todo App
After=network.target
[Service]
User=www-data
WorkingDirectory=/opt/todoapp
ExecStart=/opt/todoapp/TodoApp
Restart=always
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[Install]
WantedBy=multi-user.target
管理服务:
# 启用并启动服务
sudo systemctl enable todoapp
sudo systemctl start todoapp
# 查看状态
sudo systemctl status todoapp
# 查看日志
journalctl -u todoapp -f
Docker容器化部署
创建Dockerfile
FROM swift:3.1.1
WORKDIR /app
# 复制项目文件
COPY . .
# 构建应用
RUN swift build --configuration release
# 暴露端口
EXPOSE 8000
# 启动命令
CMD [".build/release/TodoApp"]
构建并运行容器
# 构建镜像
docker build -t todoapp .
# 运行容器
docker run -d -p 8000:8000 --name todoapp todoapp
# 查看日志
docker logs -f todoapp
性能优化建议
- 启用编译器优化
swift build --configuration release -Xswiftc -O
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



