我自己在VPS上跑了十几个自托管服务,最开始每次部署都从头来一遍,后来实在受不了这种重复,整理出了一套通用模板。现在新部署一个服务,从复制模板到跑起来基本不超过15分钟。下面把这套流程完整分享出来。
为什么Docker是VPS自托管的最优解
环境完全隔离,每个服务跑在自己的容器里,不同工具之间不会互相干扰。版本可控,指定镜像tag就能锁定版本,升级和回滚都有迹可循。迁移方便,整个栈目录加数据卷打包压缩,换服务器直接解压就能恢复。
配合Nginx Proxy Manager或Traefik,域名和HTTPS证书申请全部图形化操作,不需要手动改Nginx配置文件。
长期跑多个自托管服务,Docker Compose是目前性价比最高的方案,没什么能比得过。
第一步:安装Docker环境
Ubuntu/Debian系统,用官方源安装是最稳的方式:
# 清理旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc -y
# 添加官方源
sudo apt update && sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
验证安装成功:
docker --version
docker compose version
把当前用户加入docker组,避免每次都要sudo:
sudo usermod -aG docker $USER
newgrp docker
第二步:通用Docker Compose模板
我建议所有服务统一放在/opt/stacks/软件名/目录下,方便管理和备份。
docker-compose.yml(核心模板):
version: "3.8"
services:
main:
image: xxx/yyy:tag # 替换成目标软件的镜像
container_name: ${COMPOSE_PROJECT_NAME:-app}
restart: unless-stopped
ports:
- "${EXTERNAL_PORT:-8080}:80" # 左侧是宿主机端口,自己规划避免冲突
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Shanghai
# 根据软件要求添加额外环境变量
volumes:
- ./config:/config
- ./data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"] || exit 1
interval: 30s
timeout: 10s
retries: 3
networks:
default:
name: ${COMPOSE_PROJECT_NAME}_net
配套.env文件,把变量统一管理在这里,不要散落在compose文件里:
EXTERNAL_PORT=5683
TZ=Asia/Shanghai
PUID=1000
PGID=1000
这个模板我用了很久,绝大多数软件套进去改三四行就能跑,省掉了很多重复配置的时间。
第三步:标准化部署流程
每次部署新软件按这个顺序走,不容易出错:
# 1. 创建目录并进入
mkdir -p /opt/stacks/软件名 && cd /opt/stacks/软件名
# 2. 复制模板或下载官方compose文件,按需修改image、ports、volumes
# 3. 创建.env文件配置变量
# 4. 检查compose文件语法(这步很多人跳过,但能提前发现很多问题)
docker compose config
# 5. 启动服务
docker compose up -d
# 6. 查看启动日志确认正常
docker compose logs -f
# 7. 在云服务商控制台和UFW放行对应端口
第4步的docker compose config我强烈建议养成习惯,它会把模板变量都展开显示,语法错误和变量没替换的问题一眼就能看出来。
第四步:域名和SSL统一用Nginx Proxy Manager
手动配置Nginx和证书太繁琐,NPM(Nginx Proxy Manager)是目前最省心的方案,图形化界面一键申请Let's Encrypt证书。
部署NPM:
version: '3.8'
services:
npm:
image: jc21/nginx-proxy-manager:latest
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "81:81" # 管理面板,建议限制访问IP
environment:
DB_MYSQL_HOST: db
DB_MYSQL_USER: npm
DB_MYSQL_PASSWORD: 你的强密码
DB_MYSQL_NAME: npm
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
depends_on:
- db
db:
image: mysql:8.0
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 更强的根密码
MYSQL_DATABASE: npm
MYSQL_USER: npm
MYSQL_PASSWORD: 你的强密码
volumes:
- ./mysql:/var/lib/mysql
docker compose up -d
访问http://服务器IP:81,默认账号[email protected],密码changeme,登录后立刻改掉。
之后添加新服务只需要在NPM面板里加一条Proxy Host记录,填好域名和容器内部地址,勾选SSL自动申请,几秒钟搞定。
常用运维命令速查
# 更新镜像并重启(日常升级最常用)
docker compose pull && docker compose up -d
# 实时查看日志
docker compose logs -f
# 重启服务
docker compose restart
# 停止并删除容器(数据目录保留)
docker compose down
# 进入容器排查问题
docker compose exec main bash
# 备份整个服务栈
tar -czf backup-$(date +%F).tar.gz /opt/stacks/软件名/
常见问题排查
端口被占用:sudo lsof -i:端口号找出占用进程,杀掉或修改.env里的EXTERNAL_PORT。
权限报错:数据目录权限问题是最常见的坑,chown -R 1000:1000 ./data ./config通常能解决。
外网访问不了:按顺序检查——云服务商安全组是否放行、UFW防火墙规则、容器是否正常运行(docker compose ps)。
容器反复重启:docker compose logs看错误信息,九成是环境变量填错或数据库连接配置有问题。
2026年值得用Docker自托管的热门工具
用这套模板都能快速部署:
- 照片管理:Immich(Google Photos替代,功能最接近)
- 密码管理:Vaultwarden(Bitwarden轻量版,资源占用极低)
- 文件管理:Alist、Filebrowser
- 媒体服务:Jellyfin
- 网站监控:Uptime Kuma
- RSS阅读:FreshRSS
- 知识库:BookStack、Outline
- 书签管理:Linkding
这些工具都有活跃维护的官方Docker镜像,套上面的通用模板改几行就能跑。把这套流程跑熟了,VPS基本上就变成了你自己的私有云平台。