结论先行:出海独立开发者自建基础设施,没必要反复在网上搜罗碎片化的配置文件。本篇交付 5 套验证过的生产级 Docker Compose 实战模板:WordPress LNMP 博客栈、Ghost 内容营销平台、Nextcloud 私有团队网盘、Vaultwarden 密码安全库与 Plausible 隐私友好型网站统计。每份配置均固化了命名持久卷、日志限额轮转与内部网络隔离,只需复制 YAML 并补充 .env 变量,5 分钟即可在 VPS 上拉起整套私有云应用。
0、写在前面
在《Docker Compose 模板库实战(上)》中,我们建立了标准化编排规范与基础底层模板。
这一篇直接聚焦海外独立开发的高频实战场景:
- 内容营销与 SEO:自建英文博客(WordPress / Ghost);
- 资产与数据隔离:团队云盘(Nextcloud)与全平台团队密码同步库(Vaultwarden);
- 流量与转化追踪:轻量、无 Cookie 干扰、符合 GDPR 规范的网站统计(Plausible)。
网络上流传的许多单机部署脚本往往存在缺少持久卷命名、直接暴露数据库端口或未配健康探针等安全隐患。本文整理的 5 套模板均经过长期生产验证,开箱即用。
1、期望目标
阅读并实操本文后,你将达成以下目标:
- [ ] 掌握 5 款高频出海开源服务的生产级 Compose 配置与环境变量隔离;
- [ ] 掌握 WordPress、Ghost、Nextcloud、Vaultwarden 与 Plausible 的反向代理适配要点;
- [ ] 理解各大服务的硬件资源基线,在一台 2 核 4G VPS 上合理编排部署;
- [ ] 掌握各应用持久化数据卷(Volume)的备份与版本升级操作。
2、应用资源消耗与架构选型总览
| 自建应用服务 |
核心技术栈 |
内存底噪 |
磁盘基准 |
反代核心要求 |
最佳使用场景 |
| WordPress |
PHP-FPM + MySQL 8.0 |
约 350MB - 500MB |
1GB+ |
支持大文件上传 client_max_body_size |
内容 SEO、外贸电商与多语言博客 |
| Ghost |
Node.js + MySQL 8.0 |
约 250MB - 400MB |
500MB+ |
纯 HTTPS 强制跳转 |
现代英文技术博客、Newsletter 订阅 |
| Nextcloud |
PHP + PostgreSQL + Redis |
约 450MB - 800MB |
取决于网盘容量 |
调整 upload_max_filesize 与 HSTS |
跨国团队文件同步、个人备份网盘 |
| Vaultwarden |
Rust + SQLite |
约 25MB - 50MB |
极低 (< 100MB) |
强制开启 HTTPS 与 WebSocket 路由 |
跨设备密码库、团队敏感密钥保管 |
| Plausible |
Elixir + ClickHouse + PG |
约 400MB - 700MB |
2GB+ (OLAP 存储) |
针对 /js/script.js 开启 CDN 缓存 |
极简网站统计,替代 Google Analytics |
3、5 个开箱即用生产级实战模板
模板 1:WordPress + MySQL 8.0(生产级经典建站栈)
本模板配置了 MySQL 健康就绪探测与 WordPress 自动连接参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| services: db: image: mysql:8.0.36 container_name: wp-db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE:-wordpress} MYSQL_USER: ${MYSQL_USER:-wpuser} MYSQL_PASSWORD: ${MYSQL_PASSWORD} volumes: - db_data:/var/lib/mysql networks: - wp-net healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] interval: 5s timeout: 5s retries: 5 start_period: 15s
wordpress: image: wordpress:6.5-php8.2-apache container_name: wp-app restart: unless-stopped ports: - "127.0.0.1:${WP_PORT:-8080}:80" environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_NAME: ${MYSQL_DATABASE:-wordpress} WORDPRESS_DB_USER: ${MYSQL_USER:-wpuser} WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD} volumes: - wp_data:/var/www/html depends_on: db: condition: service_healthy networks: - wp-net
volumes: db_data: wp_data:
networks: wp-net: driver: bridge
|
模板 2:Ghost 5.x 现代博客与 Newsletter 平台
Ghost 是一款极其流畅的现代发布系统,对 SEO 极为友好:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| services: ghost: image: ghost:5-alpine container_name: ghost-app restart: unless-stopped ports: - "127.0.0.1:2368:2368" environment: url: https://${GHOST_DOMAIN:-blog.example.com} database__client: mysql database__connection__host: ghost-db database__connection__user: ${GHOST_DB_USER:-ghost} database__connection__password: ${GHOST_DB_PASSWORD} database__connection__database: ${GHOST_DB_NAME:-ghost_prod} volumes: - ghost_content:/var/lib/ghost/content depends_on: ghost-db: condition: service_healthy networks: - ghost-net
ghost-db: image: mysql:8.0.36 container_name: ghost-db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${GHOST_ROOT_PASSWORD} MYSQL_DATABASE: ${GHOST_DB_NAME:-ghost_prod} MYSQL_USER: ${GHOST_DB_USER:-ghost} MYSQL_PASSWORD: ${GHOST_DB_PASSWORD} volumes: - ghost_mysql:/var/lib/mysql networks: - ghost-net healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${GHOST_ROOT_PASSWORD}"] interval: 5s timeout: 5s retries: 5 start_period: 15s
volumes: ghost_content: ghost_mysql:
networks: ghost-net: driver: bridge
|
模板 3:Nextcloud 私有团队网盘(PostgreSQL + Redis 缓存驱动)
专为跨国协作与自建网盘设计,带 Redis 锁支持,彻底消除文件冲突:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| services: db: image: postgres:16-alpine container_name: nc-postgres restart: unless-stopped environment: POSTGRES_DB: nextcloud POSTGRES_USER: nc_user POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - nc_db:/var/lib/postgresql/data networks: - nc-net healthcheck: test: ["CMD-SHELL", "pg_isready -U nc_user -d nextcloud"] interval: 5s timeout: 5s retries: 5
redis: image: redis:7-alpine container_name: nc-redis restart: unless-stopped networks: - nc-net
app: image: nextcloud:apache container_name: nc-app restart: unless-stopped ports: - "127.0.0.1:8082:80" environment: POSTGRES_HOST: db POSTGRES_DB: nextcloud POSTGRES_USER: nc_user POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} REDIS_HOST: redis volumes: - nc_data:/var/www/html depends_on: db: condition: service_healthy redis: condition: service_started networks: - nc-net
volumes: nc_db: nc_data:
networks: nc-net: driver: bridge
|
模板 4:Vaultwarden 全平台密码同步服务器
Bitwarden 官方服务器使用 C# 开发且较为沉重,而 Vaultwarden 采用 Rust 重写,内存底噪不足 40MB,支持 Bitwarden 全平台客户端插件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| services: vaultwarden: image: vaultwarden/server:latest container_name: vaultwarden restart: unless-stopped ports: - "127.0.0.1:8083:80" - "127.0.0.1:3012:3012" environment: WEBSOCKET_ENABLED: "true" SIGNUPS_ALLOWED: "false" ADMIN_TOKEN: ${ADMIN_TOKEN} volumes: - vw_data:/data networks: - vw-net
volumes: vw_data:
networks: vw-net: driver: bridge
|
注意:Bitwarden 客户端的加密标准要求通信必须走 HTTPS。反向代理时必须配置 SSL,并将 /notifications/hub 路径代理至 3012 端口以保证实时同步。
模板 5:Plausible Analytics 轻量网站统计分析
全面替代臃肿且侵犯用户隐私的 Google Analytics,单页面脚本小于 1KB:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| services: plausible_db: image: postgres:16-alpine container_name: plausible-db restart: unless-stopped environment: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_USER: plausible POSTGRES_DB: plausible_db volumes: - db_data:/var/lib/postgresql/data networks: - plausible-net
plausible_events_db: image: clickhouse/clickhouse-server:24.3-alpine container_name: plausible-clickhouse restart: unless-stopped volumes: - event_data:/var/lib/clickhouse networks: - plausible-net
plausible: image: plausible/analytics:v2.1 container_name: plausible-app restart: unless-stopped command: sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run" ports: - "127.0.0.1:8084:8000" environment: BASE_URL: https://${PLAUSIBLE_DOMAIN} SECRET_KEY_BASE: ${SECRET_KEY_BASE} DATABASE_URL: postgresql://plausible:${DB_PASSWORD}@plausible_db:5432/plausible_db CLICKHOUSE_DATABASE_URL: http://plausible_events_db:8123/plausible_events_db depends_on: - plausible_db - plausible_events_db networks: - plausible-net
volumes: db_data: event_data:
networks: plausible-net: driver: bridge
|
4、统一运维与日常数据卷备份
所有应用均采用命名数据卷(如 db_data、wp_data、vw_data)。在宿主机编写一个通用的备份脚本即可实现一键归档:
1 2 3 4 5
| docker run --rm \ -v vw_data:/source:ro \ -v $(pwd)/backups:/backup \ alpine tar -czvf /backup/vaultwarden_$(date +%Y%m%d).tar.gz -C /source .
|
5、生产避坑清单
避坑 1:Vaultwarden 缺少 HTTPS 导致无法登录
- 根因:WebCrypto 安全 API 规范强制要求在非
localhost 环境下必须由 HTTPS 交付。若通过 HTTP 直连,浏览器扩展与 App 会禁止发送密码密钥。
- 解法:前置必须配置 Nginx / Caddy 反向代理并签发有效 SSL 证书。
避坑 2:Nextcloud 上传大文件报 413 Request Entity Too Large
- 根因:Nginx 反向代理默认限制客户端请求体体积为 1MB。
- 解法:在宿主机反代配置中追加
client_max_body_size 10G;。
6、FAQ
Q1:一台 2 核 4G 的 VPS 能同时跑这 5 个服务吗?
可以平稳运行。WordPress (400MB) + Ghost (300MB) + Nextcloud (500MB) + Vaultwarden (40MB) + Plausible (600MB) 的常驻总内存约在 2GB 左右,搭配 4GB Swap 虚拟内存,在低并发场景下性能非常充裕。
Q2:如何安全更新这些应用的镜像?
进入对应目录执行:
1 2
| docker compose pull docker compose up -d
|
Docker 会自动拉取新镜像并热重载容器,数据卷中的业务数据不受任何改动。