2026年VPS自部署服务实录

本文记录了我在 VPS 上,从零开始构建一套集流量网关、AI 大脑、自动化流水线、可视化监控、个人品牌博客及企业级备份于一体的全栈系统的完整过程。

本教程注重架构规范、安全性与长期可维护性,直接提供经过验证的生产环境配置。

推荐硬件配置

虽然本架构高度模块化,但考虑到 AI 服务(Dify)与数据库的负载,建议配置如下:

  • CPU: 4 vCPU 及以上
  • 内存: 建议 16GB 起步(若仅运行 n8n 和博客,4GB 即可;运行 Dify 建议 16GB+)
  • 硬盘: 50GB SSD 及以上
  • 系统: Ubuntu 22.04 / Debian 11+

第一章:顶层架构设计规范

在部署任何服务之前,必须制定严格的系统规范,这是长期稳定运行的基石。

1.1 文件目录规范

拒绝将数据散落在 /home/root。所有 Docker 容器的配置 (docker-compose.yml) 与持久化数据 (volumes),统一存放于:/opt/docker_data/<服务名>

1.2 端口管理规范 (50000-60000)

为了安全隐蔽及避免冲突,宿主机对外暴露的管理端口严格限制在 50000 以上的高位端口段。

服务 端口 说明
Nginx Proxy Manager 58001 全站流量入口 (Ingress)
n8n (Pro) 58002 自动化工作流引擎
Dify 58003 LLM 应用开发平台 (AI 大脑)
Portainer 58004 容器可视化管理
Beszel 58006 轻量级服务器监控
Ghost 58008 个人品牌博客 / CMS

1.3 网络安全规范

  1. 统一网络: 创建一个名为 npm_network 的 Docker 网络,所有 Web 服务加入该网络,禁止直接暴露 HTTP 端口。
  2. SSL 强制: 全站启用 Cloudflare Origin CA (15年源服务器证书),配合 Cloudflare SSL "Full (Strict)" 模式。
# 创建统一网络
docker network create npm_network

第二章:流量守门员 - Nginx Proxy Manager

作为唯一的 Web 流量入口,负责 SSL 卸载、反向代理与访问控制。

2.1 部署配置

创建目录:/opt/docker_data/npm

文件:docker-compose.yml

version: '3.8'

services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    container_name: nginx_proxy_manager
    # 加入 Watchtower 白名单,允许自动更新
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    ports:
      # HTTP/HTTPS 入口 (保持标准端口)
      - '80:80'
      - '443:443'
      # 管理面板映射到高位端口
      - '58001:81'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    networks:
      - npm_network

networks:
  npm_network:
    external: true

2.2 启动与配置

docker compose up -d
  • 访问: http://IP:58001
  • 安全建议: 登录后,立即在 NPM 中为管理面板自身配置反向代理(如 admin.your-domain.com),指向 172.17.0.1:58001,并开启 SSL,通过域名访问管理后台。

第三章:可视化运维 - Portainer

当容器数量增多,命令行管理将变得困难。Portainer 提供图形化管理界面。

3.1 部署配置

创建目录:/opt/docker_data/portainer

文件:docker-compose.yml

version: '3.8'

services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    # 加入 Watchtower 白名单
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock # 核心:接管 Docker 守护进程
      - ./data:/data
    ports:
      # HTTPS 访问入口
      - 58004:9443
    networks:
      - npm_network

networks:
  npm_network:
    external: true

第四章:自动化中枢 - n8n

n8n 是强大的工作流自动化工具。生产环境建议放弃默认的 SQLite,使用 PostgreSQL 以支持高并发。

4.1 部署配置

创建目录:/opt/docker_data/n8n

文件:docker-compose.yml

version: '3.8'

services:
  db:
    image: postgres:16-alpine
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=更改为你的强密码
      - POSTGRES_DB=n8n
    volumes:
      - ./db_data:/var/lib/postgresql/data
    networks:
      - npm_network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -h localhost -U n8n -d n8n"]
      interval: 5s
      timeout: 5s
      retries: 5

  n8n:
    image: n8nio/n8n:latest
    restart: always
    container_name: n8n
    # 加入 Watchtower 白名单
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    ports:
      - "58002:5678"
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=db
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=更改为你的强密码
      - N8N_HOST=n8n.your-domain.com
      - WEBHOOK_URL=https://n8n.your-domain.com/
      - GENERIC_TIMEZONE=Asia/Shanghai
    volumes:
      - ./n8n_data:/home/node/.n8n
    networks:
      - npm_network
    depends_on:
      db:
        condition: service_healthy

networks:
  npm_network:
    external: true

第五章:AI 大脑 - Dify (私有化部署)

Dify 是一套复杂的微服务架构(包含 9+ 容器)。建议使用官方仓库代码进行部署,但需修改端口以符合规范。

5.1 部署步骤

  1. 修改配置:编辑 docker-compose.yaml
    • 找到 nginx 服务部分。
    • 修改端口映射:将 80:80 改为 58003:80
    • (可选) 将所有服务加入 npm_network,或者仅让 Dify 的 nginx 暴露端口并在 NPM 中通过 IP+端口转发。

启动:

docker compose up -d

克隆代码:

mkdir -p /opt/docker_data/dify
cd /opt/docker_data/dify
git clone https://github.com/langgenius/dify.git .
cd docker
cp .env.example .env

注意: Dify 严禁使用自动更新工具更新,升级请使用 git pull 后重启容器。


第六章:监控系统 - Beszel

相比复杂的 Netdata,Beszel 更轻量且界面美观,适合单机或小规模集群监控。

6.1 部署配置 (Hub + Agent)

创建目录:/opt/docker_data/beszel

文件:docker-compose.yml

注意: 必须先启动 Hub 获取 Public Key,再填入 Agent 配置中。

version: '3.8'

services:
  # 1. 控制台 (Hub)
  beszel-hub:
    image: 'henrygd/beszel:latest'
    container_name: beszel-hub
    restart: unless-stopped
    # 加入 Watchtower 白名单
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    ports:
      - '58006:8090'
    volumes:
      - ./beszel_data:/beszel_data
    networks:
      - npm_network

  # 2. 采集器 (Agent)
  beszel-agent:
    image: 'henrygd/beszel-agent:latest'
    container_name: beszel-agent
    restart: unless-stopped
    # 关键:Agent 必须使用 host 模式才能准确读取宿主机资源
    network_mode: host
    # 加入 Watchtower 白名单
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    environment:
      # 使用字典格式以避免 SSH Key 格式错误
      PORT: 45876
      # ⚠️ 启动 Hub 后,去后台创建 System 获取 Key,并填入下方
      KEY: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI......"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /:/extra/filesystem:ro

networks:
  npm_network:
    external: true

第七章:内容管理系统 - Ghost

部署轻量级博客平台。为了便于迁移,数据库推荐使用 SQLite3。

7.1 环境配置 (.env)

创建目录:/opt/docker_data/ghost

文件:.env

# 前端访问域名
url=https://blog.your-domain.com
NODE_ENV=production

# 数据库 (SQLite3)
database__client=sqlite3
database__connection__filename=/var/lib/ghost/content/data/ghost.db

# 宿主机映射端口
HOST_PORT=58008

# 邮件配置 (SMTP)
mail__transport=SMTP
mail__options__host=smtp.example.com
mail__options__port=465
mail__options__secure=true
mail__options__auth__user=user@example.com
mail__options__auth__pass=password
mail__from=user@example.com

7.2 部署文件

文件:docker-compose.yml

version: '3.8'

services:
  ghost:
    image: ghost:latest
    container_name: ghost
    restart: unless-stopped
    # 加入 Watchtower 白名单
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    env_file:
      - .env
    ports:
      - "${HOST_PORT}:2368"
    volumes:
      - ./content:/var/lib/ghost/content
    networks:
      - npm_network

networks:
  npm_network:
    external: true

第八章:系统优化与维护

8.1 系统性能调优

# 1. 增加 4GB Swap (防止 OOM)
fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# 2. 开启 TCP BBR (网络加速)
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p

# 3. 限制 Docker 日志大小 (防止爆盘)
# 编辑 /etc/docker/daemon.json 添加:
# { "log-driver": "json-file", "log-opts": { "max-size": "20m", "max-file": "3" } }

8.2 镜像自动更新 (Watchtower)

采用 “白名单模式”,默认不更新任何容器,只更新带有 label-enable=true 标签的容器(如上文中的 NPM, n8n, Ghost, Beszel)。

部署 Watchtower:

docker run -d \
  --name watchtower \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower \
  --schedule "0 0 4 * * *" \
  --cleanup \
  --label-enable 
  • --label-enable: 关键参数,开启白名单模式,保护 Dify 等复杂应用不被自动升级损坏。

第九章:企业级容灾备份

采用 Rclone + Cloudflare R2 进行异地冷备。为了保证数据库的一致性,采用“闪断备份法”。

9.1 备份脚本

文件:/opt/rclone_backup.sh

#!/bin/bash
SOURCE_DIR="/opt/docker_data"
BACKUP_DIR="/opt/backup_staging"
REMOTE_PATH="remote:backup/vps_data" # 这里的 remote 需提前配置好
DATE=$(date +%Y%m%d_%H%M%S)
ARCHIVE_NAME="vps_data_$DATE.tar.gz"
LOG_FILE="/var/log/rclone_backup.log"

echo "[$(date)] 开始备份..." >> $LOG_FILE

# 1. 停止 Docker (同时停止 Socket 防止被意外唤醒)
systemctl stop docker.socket
systemctl stop docker.service

# 2. 打包数据
tar -zcf "$BACKUP_DIR/$ARCHIVE_NAME" -C /opt docker_data

# 3. 立即恢复服务 (业务中断约 1-2 分钟)
systemctl start docker.service

# 4. 上传并清理旧备份 (保留最近 25 天)
rclone copy "$BACKUP_DIR/$ARCHIVE_NAME" "$REMOTE_PATH"
rclone delete "$REMOTE_PATH" --min-age 25d

# 5. 清理本地
find "$BACKUP_DIR" -name "vps_data_*.tar.gz" -type f -mtime +1 -delete

echo "[$(date)] 备份完成。" >> $LOG_FILE

9.2 定时任务

设置每周日凌晨执行:

crontab -e
# 添加:
0 4 * * 0 /bin/bash /opt/rclone_backup.sh

结语

至此,一套基于 Gateway (NPM) + Brain (Dify) + Automation (n8n) + Monitor (Beszel) 的现代化数字基地构建完成。这套架构兼顾了高性能与易维护性,配合完善的备份策略。