Ubuntu 云服务器实践:安全部署文件存储、下载与代码托管
内容提要
本文介绍在 Ubuntu 云服务器上使用 Docker Compose 部署 OtterIO、Gitea 和 Traefik,搭建自管的对象存储、文件下载与代码托管服务,涵盖创建 deploy 用户、SSH 与 UFW 加固、固定镜像摘要、配置域名与证书、初始化数据目录、启动验证、备份恢复及升级流程。
延伸解读
安全加固的层次与边界
文章从账号、SSH、防火墙到容器权限做了多层加固:创建专用 deploy 用户并锁定密码、仅允许密钥登录、UFW 限制来源 IP、容器以非 root 运行并移除 capabilities。但需注意,Docker 发布端口可能绕过 UFW 常规规则,因此还需结合云防火墙和将后台端口绑定到 127.0.0.1。这些措施降低暴露面,但并非绝对隔离,管理员仍可通过 sudo 取得 root 权限。
镜像固定与版本选择
文章强调使用固定版本标签和完整镜像摘要,而非 latest 或仅主版本标签。OtterIO 选用 RELEASE.2026-10-07T14-09-17Z,Gitea 使用 28.1.0-rootless,Traefik 选择仍受支持的 v3 正式版。固定摘要能确保镜像内容不变,但文章也指出,摘要和发布清单不能代替签名验证或可复现构建证明。升级前应保留旧摘要并阅读兼容说明。
数据持久化与备份要点
所有服务数据统一放在 /data 挂载点,OtterIO、Gitea 和 Traefik 证书分别使用子目录。若只有系统盘,可通过绑定挂载将 /srv/file-code-stack-data 映射到 /data,但文章提醒这并不增加独立磁盘的故障隔离。初始化脚本会检查 /data 是否为挂载点,未挂载时停止写入。备份恢复和升级流程需在服务稳定后按维护窗口执行。
证书申请与访问控制
Traefik 支持 ACME HTTP-01 和 DNS-01(Cloudflare、AliDNS)。HTTP-01 要求域名直接解析到服务器且公网 80 可访问;DNS-01 则通过 API 创建临时 TXT 记录,适合已接入 CDN 的场景。文章建议为 DNS 服务商创建独立凭据并限制权限,凭据文件权限设为 20003:20003、0400。S3 和 Git 入口默认受来源 IP 限制,预签名链接不会绕过该限制。
Q&A
如何在 Ubuntu 云服务器上部署 OtterIO、Gitea 和 Traefik?
使用 Docker Compose 部署,配置放在 /app/file-code-stack,数据放在 /data。先创建 deploy 用户并加固 SSH 和 UFW,然后固定镜像摘要,配置域名和证书,初始化数据目录,最后启动服务。
为什么建议使用固定镜像摘要而不是 latest 标签?
固定镜像摘要可以确保每次部署使用完全相同的镜像内容,避免因 latest 标签更新导致意外变更,提高部署的可重复性和安全性。
如何为 OtterIO 和 Gitea 配置 HTTPS 证书?
通过 Traefik 自动管理证书,支持 ACME HTTP-01 或 DNS-01 验证。在 .env 中设置 TLS_MODE 为 http、cloudflare 或 alidns,并配置相应的凭据文件。
部署后如何验证文件下载服务是否正常工作?
使用 curl 测试下载链接,检查响应头、Range 请求返回 206 Partial Content,以及 ETag 条件请求返回 304 Not Modified。确保文件可访问且写请求被拒绝。
如何备份和恢复 OtterIO 的数据?
使用 restic 等工具备份 /data/otterio 目录,恢复时停止容器,将备份数据还原到原目录,再启动容器。确保备份包含对象数据和元数据。
升级 OtterIO 或 Gitea 时需要注意什么?
升级前备份数据,拉取新版本镜像并核对摘要,更新 .env 中的镜像引用,重新生成配置并预检查,然后重启服务。升级后验证功能正常。