Ubuntu 22.04 安装 Static Web Server 指南
Ubuntu 22.04 从零安装 Static Web Server(SWS)v2.44.1 完整指南:官方 tar.gz 二进制主方案(SHA256 校验、systemd 托管、防火墙)与 cargo 编译备用方案,含真实排障实录与卸载清理。
Ubuntu 22.04 安装 Static Web Server 指南
目标:在 Ubuntu 22.04 服务器上从零安装 Static Web Server(SWS)v2.44.1 并以 systemd 托管为常驻服务。本文含两个安装方案——官方 tar.gz 二进制安装(主方案)与 cargo 编译安装(备用方案),每条命令与回显均在 Ubuntu 22.04 LTS(x86_64)实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04 LTS(x86_64,内核 5.15+ 均适用)
- 软件版本:Static Web Server v2.44.1(官方最新稳定版,发布于 2026-10-11;版本查询日期 2026-10-20,查询渠道 GitHub Releases/releases.atom)
- 安装目标路径:二进制
/usr/local/bin/static-web-server,站点根目录/var/www/html,配置文件/etc/static-web-server/static-web-server.toml - 服务托管:systemd(unit 名
static-web-server.service),监听端口 8780(SWS 默认端口为 80,本文统一改用 8780 演示) - 版本查询命令(随时确认官方最新稳定版):
curl -s https://github.com/static-web-server/static-web-server/releases.atom | grep -oE '<title>[^<]+</title>' | head -5
实测回显(查询日期 2026-10-20,v3.0.0-beta.x 为测试版不选,最新稳定版为 v2.44.1):
<title>Release notes from static-web-server</title>
<title>v3.0.0-beta.2</title>
<title>v2.44.1</title>
<title>v2.44.0</title>
<title>v3.0.0-beta.1</title>
二、前置条件
- 系统与权限:一台 Ubuntu 22.04 服务器,具备 root 或 sudo 权限;本机可访问外网(GitHub 下载慢时可用代理,见 3.2 节说明)。
- 基础工具:
wget/curl(下载)、tar(解压)、sha256sum(校验)。Ubuntu 22.04 最小安装可能缺 wget/curl,先补齐:
apt-get update && apt-get install -y curl wget
实测回显(节选末尾):
Running hooks in /etc/ca-certificates/update.d...
done.
- 服务运行用户:systemd 托管将以
www-data运行服务,Ubuntu 22.04 默认自带该用户,确认命令与实测回显:
getent passwd www-data
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
⚠️ 若该命令无输出(个别精简系统),执行
useradd -r -s /usr/sbin/nologin www-data创建后再继续。
三、版本选型说明
SWS 官方不提供 deb/rpm 包,以 tar.gz 二进制压缩包为唯一官方预编译发行形态,每个版本同时发布 SHA256 校验文件。选型时需要确定三件事:
- 版本号:选最新稳定版 v2.44.1(beta 版
v3.0.0-beta.x仅供尝鲜,不要用于生产); - 构建目标(triple):决定下载哪个压缩包,对照表如下;
| 目标 triple | 适用环境 | 说明 |
|---|---|---|
x86_64-unknown-linux-musl | 常规 x86_64 服务器 | 静态链接,零依赖,首选 |
x86_64-unknown-linux-gnu | x86_64 且依赖 glibc 动态链接的场景 | 老旧 glibc 发行版需核对版本 |
x86_64-unknown-linux-gnu-fips | 需要符合 FIPS 140-3 的合规环境 | FIPS 加密模块变体 |
aarch64-unknown-linux-musl | ARM64 服务器(如国产化 ARM 主机) | 静态链接 |
关键差异:musl 版把 libc 静态编进二进制,拷贝到任何 Linux 都能跑;gnu 版体积略小但依赖目标机 glibc。无特殊合规要求一律选 musl。可用 uname -m 确认机器架构(输出 x86_64 或 aarch64)。
- 校验文件:
static-web-server-v2.44.1-SHA256SUM包含全部资产校验值,下载后必须比对(见 4.2)。
四、方案 A:官方 tar.gz 二进制安装(主方案)
4.1 方案说明
从 GitHub Releases 直接下载与平台匹配的静态编译二进制,解压安装到 /usr/local/bin,手写 systemd unit 托管为常驻服务。全程约 1 分钟,不依赖包管理器,升级=替换一个文件。这是 SWS 官方文档的标准安装路径,也是本文实测的主方案。
4.2 下载与 SHA256 校验
在 /tmp 完成下载与校验(版本号 2.44.1 可按 3.1 节查询命令结果替换):
cd /tmp
wget -q https://github.com/static-web-server/static-web-server/releases/download/v2.44.1/static-web-server-v2.44.1-x86_64-unknown-linux-musl.tar.gz
wget -q https://github.com/static-web-server/static-web-server/releases/download/v2.44.1/static-web-server-v2.44.1-SHA256SUM
sha256sum static-web-server-v2.44.1-x86_64-unknown-linux-musl.tar.gz
grep x86_64-unknown-linux-musl.tar.gz static-web-server-v2.44.1-SHA256SUM | head -2
实测回显(第 1 行是本地计算值,第 2 行是官方 SHA256SUM 文件中的值,二者一致即校验通过):
8f94abd9bc9c6d11240301d7271b95f9ec05b1b3e8509087c86ca8fd0b56fb4e static-web-server-v2.44.1-x86_64-unknown-linux-musl.tar.gz
8f94abd9bc9c6d11240301d7271b95f9ec05b1b3e8509087c86ca8fd0b56fb4e static-web-server-v2.44.1-x86_64-unknown-linux-musl.tar.gz
⚠️ 下载慢或超时:GitHub 直连受限的环境可走代理下载,
wget单次代理写法wget -x http://192.168.1.62:7897 <URL>,或会话级export http_proxy=http://192.168.1.62:7897 https_proxy=http://192.168.1.62:7897后再执行 wget。
4.3 解压安装二进制
cd /tmp
tar -xzf static-web-server-v2.44.1-x86_64-unknown-linux-musl.tar.gz
ls -la static-web-server-v2.44.1-x86_64-unknown-linux-musl/
cp static-web-server-v2.44.1-x86_64-unknown-linux-musl/static-web-server /usr/local/bin/
static-web-server --version
实测回显:
-rw-r--r-- 1 1001 1001 10847 Oct 7 20:22 LICENSE-APACHE
-rw-r--r-- 1 1001 1001 1112 Oct 7 20:22 LICENSE-MIT
-rw-r--r-- 1 1001 1001 8563 Oct 7 20:22 README.md
-rwxr-xr-x 1 1001 1001 8260032 Oct 7 20:22 static-web-server
Version: 2.44.1
Built: 2026-10-07 21:53:43 +02:00
Git commit: c5cbe67e91da91ccad838163cf9a034bf221a447
Build target: x86_64-unknown-linux-musl
Rust version: rustc 1.99.0 (b940084d7 2026-09-28)
License: MIT OR Apache-2.0
Homepage: https://static-web-server.net
Author: Jose Quintana <https://joseluisq.net>
压缩包内含二进制与 Apache/MIT 双许可文本;--version 能正确输出版本信息即安装成功。二进制体积约 7.9MB(8,260,032 字节)。
4.4 创建站点目录与演示页面
mkdir -p /var/www/html
cat > /var/www/html/index.html <<'EOF'
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="utf-8"><title>SWS Demo Site</title></head>
<body><h1>Hello Static Web Server</h1><p>It works!</p></body>
</html>
EOF
chown -R www-data:www-data /var/www/html
ls -la /var/www/html/
实测回显:
total 12
drwxr-xr-x 2 www-data www-data 4096 Oct 20 16:31 .
drwxr-xr-x 4 root root 4096 Oct 20 16:19 ..
-rw-r--r-- 1 www-data www-data 170 Oct 20 16:15 index.html
/var/www/html 是 SWS 生产配置的标准站点根目录(与 Ubuntu Nginx/Apache 惯例一致),演示页面 170 字节。
4.5 编写配置文件
SWS 的配置文件为 TOML 格式,官方约定路径为 /etc/static-web-server/。先创建一份最小可用配置(完整参数逐项解释见本专栏《Static Web Server 2.44.1 配置参数详解》):
mkdir -p /etc/static-web-server
cat > /etc/static-web-server/static-web-server.toml <<'EOF'
[general]
host = "0.0.0.0"
port = 8780
root = "/var/www/html"
log-level = "info"
page404 = "/var/www/html/404.html"
page50x = "/var/www/html/50x.html"
health = true
compression = true
cache-control-headers = true
directory-listing = false
redirect-trailing-slash = true
ignore-hidden-files = true
[advanced]
EOF
echo "404 page content" > /var/www/html/404.html
echo "50x maintenance" > /var/www/html/50x.html
配置块关键项说明(其余保持默认):
| 键 | 值与作用 | 默认值 |
|---|---|---|
host | 监听地址,0.0.0.0 表示所有 IPv4 网卡 | ::(IPv6 全地址) |
port | 监听端口,默认 80 需 root,演示改 8780 | 80 |
root | 站点根目录 | ./public |
log-level | 日志级别 error/warn/info/debug/trace,info 可看到请求日志 | error |
page404/page50x | 自定义错误页,相对路径时相对 root 解析 | 通用内置页 |
health | 开启 /health 探活端点 | false |
⚠️ TOML 是强类型配置:
index-files等少数键只接受字符串(如"index.html, index.htm"),写成数组会启动报错,实测案例见 8.1。
4.6 systemd 托管
创建环境变量文件与 unit 文件两份配置。环境变量文件沿用官方 systemd/etc_default_static-web-server 的形态(SWS 支持 SERVER_* 环境变量作为配置来源,与 TOML 键一一对应):
cat > /etc/default/static-web-server <<'EOF'
SERVER_ROOT=/var/www/html
SERVER_CONFIG_FILE=/etc/static-web-server/static-web-server.toml
SERVER_LOG_LEVEL=info
EOF
cat > /etc/systemd/system/static-web-server.service <<'EOF'
[Unit]
Description=Static Web Server
Documentation=https://static-web-server.net
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=www-data
Group=www-data
EnvironmentFile=/etc/default/static-web-server
ExecStart=/usr/local/bin/static-web-server
Restart=always
RestartSec=5
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
chmod 640 /etc/default/static-web-server
单元文件逐项说明:User/Group=www-data 让服务降权运行;EnvironmentFile 注入 SERVER_* 环境变量(指定配置文件路径);Restart=always + RestartSec=5 实现崩溃后 5 秒自动拉起;StandardError=journal 把日志写入 journald(journalctl -u static-web-server 查看)。
⚠️ SWS 默认日志级别为
error,即控制台几乎无输出,这是正常现象;本文配置已通过环境变量文件调为info。
启用并启动服务(每条命令针对单个单元):
systemctl daemon-reload
systemctl enable static-web-server
systemctl start static-web-server
systemctl is-active static-web-server
systemctl status static-web-server --no-pager -l | head -6
实测回显:
Created symlink /etc/systemd/system/multi-user.target.wants/static-web-server.service → /etc/systemd/system/static-web-server.service.
active
● static-web-server.service - Static Web Server
Loaded: loaded (/etc/systemd/system/static-web-server.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2026-10-20 16:18:32 UTC; 2s ago
Docs: https://static-web-server.net
Main PID: 3024 (static-web-serv)
Tasks: 13 (limit: 94371)
active (running) 与 enabled(开机自启)双确认。ps 里进程名显示为截断的 static-web-serv(Linux 进程名 15 字符上限),属正常现象。
4.7 验证服务
curl -sI http://127.0.0.1:8780/
实测回显:
HTTP/1.1 200 OK
content-length: 170
content-type: text/html; charset=utf-8
accept-ranges: bytes
last-modified: Tue, 20 Oct 2026 16:15:29 GMT
vary: accept-encoding
cache-control: max-age=86400
date: Tue, 20 Oct 2026 16:15:43 GMT
HTTP/1.1 200 OK 说明站点已在 8780 端口正常服务,且 SWS 内置的 Cache-Control 头已自动附加。再看运行日志:
journalctl -u static-web-server --no-pager -n 5
实测回显(每行前缀 Oct 20 16:31:10 主机名 static-web-server[PID]: 因机器而异,以下为本文实测值):
Oct 20 16:31:10 e12700ecf57f static-web-server[4432]: 2026-10-20T16:31:10.123208237Z INFO Server::start_server{addr_str="0.0.0.0:8780" threads=12}: static_web_server::server: close time.busy=0.00ns time.idle=709ns
Oct 20 16:31:10 e12700ecf57f static-web-server[4432]: 2026-10-20T16:31:10.123222702Z INFO static_web_server::server: http1 server is listening on http://0.0.0.0:8780
Oct 20 16:31:10 e12700ecf57f static-web-server[4432]: 2026-10-20T16:31:10.123225315Z INFO static_web_server::server: press ctrl+c to shut down the server
http1 server is listening on http://0.0.0.0:8780 确认服务已按配置监听 8780 端口。threads=12 为 worker 线程数(=CPU 核数 × threads-multiplier),随目标机核数变化。再验证探活端点(4.5 配置已开启 health = true):
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8780/health
实测回显:
200
4.8 开放防火墙端口
远程访问需放行端口(本地 ufw 防火墙;云服务器还需在厂商安全组放行):
ufw allow 8780/tcp
ufw status
实测回显:
Rules updated
Rules updated (v6)
Status: inactive
Rules updated 表示规则已写入;Status: inactive 表示本机 ufw 当前未启用(规则在 enable 后生效),如果你的服务器 ufw status 显示 active,8780 端口即刻放行。外网浏览器访问 http://<服务器IP>:8780/ 应看到演示页面。
五、方案 B:cargo 编译安装(备用方案)
5.1 方案说明
通过 Rust 包管理器 cargo 从 crates.io 源码编译安装,适合需要自定义编译特性、或无法直接下载官方二进制的环境。缺点是依赖 Rust 工具链且编译耗时(约 3–10 分钟,视机器而定)。
5.2 安装 Rust 工具链
SWS 2.44.1 要求 rustc ≥ 1.88.0。Ubuntu 22.04 apt 源的 cargo 版本过旧,直接用会编译失败——这是实测踩到的第一个坑:
apt-get install -y cargo
cargo --version
cargo install static-web-server --version 2.44.1
实测回显(apt 装的 cargo 为 1.75.0,编译被拒):
cargo 1.75.0
error: cannot install package `static-web-server 2.44.1`, it requires rustc 1.88.0 or newer, while the currently active rustc version is 1.75.0
`static-web-server 2.32.2` supports rustc 1.74.0
解决方案:用官方 rustup 安装最新 stable 工具链(安装脚本来自 rustup.rs,仅当前用户生效,装到 ~/.cargo/ 与 ~/.rustup/):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /root/rustup-init.sh
TMPDIR=/root sh /root/rustup-init.sh -y --default-toolchain stable --profile minimal
source "$HOME/.cargo/env"
rustc --version
实测回显(工具链安装完成后的关键日志与版本确认):
info: default host tuple is x86_64-unknown-linux-gnu
info: syncing channel updates for stable-x86_64-unknown-linux-gnu
info: latest update on 2026-10-15 for version 1.99.1 (58cf8f9c3 2026-10-13)
info: downloading 3 components
rustc 1.99.1 (58cf8f9c3 2026-10-13)
⚠️ 如果
/tmp挂载了 noexec(容器镜像与安全加固服务器常见),rustup 会因无法执行临时目录里的安装器而失败,实测报错:error: Cannot execute /tmp/tmp.GnKCSzMIOs/rustup-init (likely because of mounting /tmp as noexec). error: Please copy the file to a location where you can execute binaries and run ./rustup-init.上例命令中的
TMPDIR=/root就是解法:把脚本与临时目录都挪到可执行位置(/root或家目录)。
5.3 cargo 编译安装
cargo install static-web-server --version 2.44.1
实测回显(节选,依赖下载与编译行有数百行,本文实测共编译 221 个 crate,约 4 分钟):
Downloaded static-web-server v2.44.1
Installing static-web-server v2.44.1
Updating crates.io index
Compiling proc-macro2 v1.0.107
...
Compiling shadow-rs v2.0.0
Compiling static-web-server v2.44.1
Installing /root/.cargo/bin/static-web-server
Installed package `static-web-server v2.44.1` (executable `static-web-server`)
完成后把二进制复制到系统路径并验证(编译版 Build target 为 x86_64-unknown-linux-gnu,Built/Git commit 字段为空,与官方发布二进制的差异属正常现象):
cp ~/.cargo/bin/static-web-server /usr/local/bin/
static-web-server --version
实测回显:
Version: 2.44.1
Built:
Git commit:
Build target: x86_64-unknown-linux-gnu
Rust version: rustc 1.99.1 (58cf8f9c3 2026-10-13)
⚠️ 编译产物默认仅对当前用户可用,务必按上例复制到
/usr/local/bin/再做 systemd 托管,否则www-data用户无权执行家目录下的文件。后续 4.4–4.8 步骤与本方案完全一致。
5.4 验证
与 4.3 相同:static-web-server --version 正确输出 Version: 2.44.1 即安装成功。编译版与官方二进制的差异仅两点:Build target 为 x86_64-unknown-linux-gnu(依赖目标机 glibc)、Built/Git commit 为空(源码编译未注入构建元数据),均为正常现象。
六、方案对比选择建议
| 维度 | 方案 A:官方 tar.gz 二进制 | 方案 B:cargo 编译安装 |
|---|---|---|
| 耗时 | 约 1 分钟 | 约 3–10 分钟(含工具链) |
| 依赖 | 仅 wget/tar | Rust 工具链(≥1.88.0)+ crates.io 网络 |
| 版本一致性 | 与官方发布完全一致(SHA256 可校验) | 随编译环境变化(Build target 为 gnu) |
| 升级方式 | 下载新版替换一个文件 | 重新编译 |
| 适用场景 | 所有常规场景(默认选它) | 需自定义 feature 编译、无法直连 Releases |
选择建议:一律优先方案 A;只有当需要修改源码/启用非默认编译特性,或所在网络只能访问 crates.io 时才用方案 B。两方案可以共存,编译版装入 /usr/local/bin/ 前注意备份原官方二进制以便回退。
七、配置说明
所有方案共用的配置与安全项:
- 配置文件位置:
/etc/static-web-server/static-web-server.toml,由/etc/default/static-web-server中的SERVER_CONFIG_FILE指向;SWS 默认还会在工作目录找sws.toml,生产环境建议总是显式指定绝对路径。 - 配置修改后必须重启服务(SWS 不支持配置热加载):
systemctl restart static-web-server。 - 多版本管理:SWS 是单二进制,把不同版本分别放
/opt/sws-2.44.1/、/opt/sws-2.43.0/等目录,改 unit 的ExecStart路径即可切换;升级时保留旧版二进制即为随时可用的回滚方案。 - 降级:用旧版 tar.gz 覆盖
/usr/local/bin/static-web-server后systemctl restart static-web-server,配置文件向后兼容。 - 最小权限:服务以
www-data运行,站点目录属主与读写权限只需覆盖到该用户;TLS 私钥权限设置见 8.2 的排障实录。 - 开机自启:4.6 节
systemctl enable static-web-server已设置;取消自启用systemctl disable static-web-server。
八、常见问题(FAQ)
Q1:启动报错 invalid type: sequence, expected a string in general.index-files?
TOML 配置中 index-files 是字符串类型(逗号分隔),不能写成数组。实测报错回显:
Caused by:
0: error during toml configuration file deserialization
1: invalid type: sequence, expected a string
in `general.index-files`
改为 index-files = "index.html, index.htm" 后重启即可。排查思路:启动即失败的配置错误都会打出 error during toml configuration file deserialization 与具体键名,按报错键修正类型。
Q2:启用 TLS 后服务起不来,日志报 Permission denied (os error 13)?
服务以 www-data 运行,而 openssl 生成的私钥默认权限 600 属主 root:root,服务用户读不到。实测日志回显:
error reading file ("/etc/static-web-server/local.key"): Permission denied (os error 13)
static-web-server.service: Main process exited, code=exited, status=1/FAILURE
解决:把证书与私钥属主改为 root:www-data 并收紧权限后重启:
chown root:www-data /etc/static-web-server/local.key /etc/static-web-server/local.crt
chmod 640 /etc/static-web-server/local.key /etc/static-web-server/local.crt
systemctl restart static-web-server
Q3:启动报错 failed to bind to 0.0.0.0:8780 address / Address in use (os error 98)?
端口被占用:常见原因是前一个 SWS 实例还在跑(手工启动与 systemd 各一份)。先用 ps aux | grep static-web-server 找到旧进程并 kill <PID>,再 systemctl start static-web-server。注意用 pkill -x static-web-server 杀不掉——Linux 进程名截断为 15 字符 static-web-serv,精确匹配全名会失配(实测踩坑);按 PID 杀最可靠。
Q4:systemd 启动成功但 curl 连不上?
依次检查:systemctl is-active static-web-server 是否 active;journalctl -u static-web-server -n 20 有无 Address already in use 或配置反序列化报错;配置里 host 是否被改成了 127.0.0.1(远程将无法访问);防火墙是否放行(见 4.8)。
Q5:日志里出现 basic authentication: bcrypt is limited to 72 bytes per password 警告?
BCrypt 算法只取口令前 72 字节。SWS 的 Basic 认证口令要求使用 BCrypt 散列(htpasswd -bnBC 10 "" 'your-password' | tr -d ':\n' 生成),警告提示不要用超长或非 ASCII 口令原文,改用 72 字节以内的 ASCII 口令重新生成散列。
Q6:/metrics 访问返回 401?
开启 Basic 认证后 /metrics 同样受保护(启动日志会警告 metrics endpoint /metrics is unauthenticated; restrict access via reverse proxy or network policy 提醒在未开认证时注意暴露面)。带凭据访问 curl -u admin:<password> http://127.0.0.1:8780/metrics 即返回 Prometheus 文本格式指标。
九、卸载与清理
完整卸载 SWS 的步骤(按安装内容逐项回退):
systemctl stop static-web-server
systemctl disable static-web-server
rm /etc/systemd/system/static-web-server.service
systemctl daemon-reload
rm /etc/default/static-web-server
rm -rf /etc/static-web-server
rm /usr/local/bin/static-web-server
rm -rf /var/www/html
以上命令依次完成:停止服务 → 取消开机自启 → 移除 unit 文件并重载 systemd → 移除环境变量文件、配置目录、二进制与站点目录。卸载后确认无残留进程:ps aux | grep static-web-server | grep -v grep 应无输出。
十、参考链接
- 官方安装文档:https://static-web-server.net/download-install/
- 版本发布页:https://github.com/static-web-server/static-web-server/releases
- v2.44.1 发布页(本文实测版本):https://github.com/static-web-server/static-web-server/releases/tag/v2.44.1
- 官方 systemd 示例(含 socket activation 与沙箱加固模板):https://github.com/static-web-server/static-web-server/tree/master/systemd
- 站内延伸阅读:《Static Web Server 介绍与选型指南》、《Static Web Server 2.44.1 配置参数详解》、《Static Web Server 2.44.1 常用 CLI 命令详解》