生产环境部署指南:用 Docker Compose 搭建高可用 Cockpit + MongoDB 集群

生产环境部署指南:用 Docker Compose 搭建高可用 Cockpit + MongoDB 集群

【免费下载链接】Cockpit Cockpit Core - Content Platform 【免费下载链接】Cockpit 项目地址: https://gitcode.com/gh_mirrors/cockp/Cockpit

Cockpit 是一款开源的 Headless CMS(无头内容管理系统),也被称为 Cockpit Core 内容平台,它通过 REST 与 GraphQL API 为网站、移动应用和物联网设备提供灵活的内容管理能力。本文将手把手教你使用 Docker Compose 搭建高可用 Cockpit + MongoDB 集群,从编写编排文件、配置数据库连接,到副本集高可用与数据备份恢复,一套完整的生产环境部署方案,帮助你快速上线一个稳定可靠的内容平台。

一、为什么生产环境推荐用 Docker Compose 部署 Cockpit?

Cockpit 官方提供了基于 PHP 8.3 + Apache 的 Docker 镜像,项目根目录的 Dockerfile 已经内置了 GD、Zip、PDO、MongoDB 驱动、Redis 扩展和 Apache mod_rewrite,省去了手动编译 PHP 扩展的繁琐过程。用 Docker Compose 编排 Cockpit + MongoDB,可以一次性解决三个生产环境难题:

难题Docker Compose 的解法
环境不一致镜像固化运行环境,本地与服务器行为一致
数据库依赖一条命令同时拉起应用与 MongoDB,depends_on 保证启动顺序
扩展与迁移通过环境变量注入配置,扩容节点无需改代码

Cockpit 默认使用 SQLite(mongolite://)存储数据,适合开发调试;生产环境建议切换到真正的 MongoDB,以获得更好的并发性能、索引能力和副本集高可用支持。这一点在 bootstrap.php 的默认配置中可以看到,你只需在 config/config.php 中覆盖 database.server 即可无缝切换。

二、整体架构:高可用 Cockpit + MongoDB 集群长什么样?

推荐的生产架构分为三层:

  • 接入层:Nginx 反向代理,负责 HTTPS 终结、静态资源缓存与流量转发;
  • 应用层:1 个或多个 Cockpit 容器(官方镜像 cockpithq/cockpit:core-latest),无状态应用,可横向扩容;
  • 数据层:MongoDB 副本集(Replica Set),一主多从,实现数据冗余与自动故障转移。

Cockpit 通过 lib/MongoHybrid/Client.php 统一抽象了 MongoDB 与 SQLite 两种驱动,连接串以 mongodb://mongodb+srv:// 开头时走真实 MongoDB,应用层无需改动任何业务代码。

三、快速搭建步骤:编写 docker-compose.yml

3.1 第一步:获取代码并准备目录

生产环境建议拉取官方发布版本而非源码仓库,如果你需要基于源码二次开发,可以克隆:

git clone https://gitcode.com/gh_mirrors/cockp/Cockpit

创建项目目录结构,storage 目录必须可写(安装引导程序 install/index.php 会检查 storage/datastorage/cachestorage/uploads 等目录的写入权限):

/opt/cockpit/
├── docker-compose.yml
├── config/
│   └── config.php
└── storage/          # 挂载数据卷

3.2 第二步:编写 docker-compose.yml

这是全文核心,一份可直接上生产的高可用编排文件:

version: '3.8'

services:
  mongo:
    image: mongo:8
    container_name: cockpit-mongo
    restart: unless-stopped
    command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
    volumes:
      - mongo_data:/data/db
      - mongo_config:/data/configdb
    healthcheck:
      test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - cockpit-net

  mongo-init:
    image: mongo:8
    container_name: cockpit-mongo-init
    depends_on:
      mongo:
        condition: service_healthy
    command: >
      mongosh --host mongo:27017 --eval
      "try { rs.initiate({_id:'rs0', members:[{_id:0, host:'mongo:27017'}]}) } catch(e) { print(e) }"
    networks:
      - cockpit-net

  cockpit:
    image: cockpithq/cockpit:core-latest
    container_name: cockpit-app
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"        # 只暴露到本机,由 Nginx 转发
    environment:
      - COCKPIT_DATABASE_SERVER=mongodb://mongo:27017/?replicaSet=rs0
      - COCKPIT_DATABASE_NAME=cockpit
      - COCKPIT_SEC_KEY=${COCKPIT_SEC_KEY}   # 从 .env 读取,绝不写死在文件里
    volumes:
      - ./config:/var/www/html/config
      - cockpit_storage:/var/www/html/storage
    depends_on:
      mongo:
        condition: service_healthy
    networks:
      - cockpit-net

volumes:
  mongo_data:
  mongo_config:
  cockpit_storage:

networks:
  cockpit-net:
    driver: bridge

说明:mongo-init 是一个一次性容器,负责把 MongoDB 初始化为副本集 rs0,这是实现故障自动切换的关键一步。Cockpit 只暴露到 127.0.0.1,对外统一由反向代理接管。

3.3 第三步:配置 config.php 与安全密钥

Cockpit 会优先加载 config/config.php(挂载到容器内 /var/www/html/config)。创建如下配置:

<?php
// config/config.php
return [
    'database' => [
        'server'   => getenv('COCKPIT_DATABASE_SERVER') ?: 'mongodb://mongo:27017',
        'database' => getenv('COCKPIT_DATABASE_NAME') ?: 'cockpit',
    ],
    'sec-key' => getenv('COCKPIT_SEC_KEY') ?: 'please-change-me',
];

安全提醒(必须做):Cockpit 默认的 sec-key 是写死在 bootstrap.php 里的公开值,生产环境务必通过环境变量覆盖,否则存在会话伪造风险。同时在同目录创建 .env 文件:

COCKPIT_SEC_KEY=$(openssl rand -hex 32)

3.4 第四步:启动并完成安装

docker compose up -d
docker compose ps        # 确认三个容器都 healthy

浏览器访问 http://服务器IP/install,跟随 install/index.php 的引导完成初始化,设置管理员账号即可。安装完成后,REST 与 GraphQL API 就可以通过 /api/* 对外提供服务了。

四、高可用关键点:副本集、持久化与备份恢复

4.1 MongoDB 副本集实现自动故障转移

生产环境单体 MongoDB 一旦宕机,整个内容平台随之不可用。通过 --replSet rs0 将 MongoDB 初始化为副本集后,主节点故障时从节点会自动选举出新主节点,Cockpit 连接串中的 ?replicaSet=rs0 让驱动自动感知角色变化,实现高可用无缝切换。

4.2 数据持久化与备份策略

  • 应用数据cockpit_storage 卷持久化上传的图片、文件与缓存;
  • 数据库mongo_data 卷持久化全部内容数据;
  • 备份方案:生产环境建议每日执行 mongodump 并同步到异地存储:
docker exec cockpit-mongo mongodump --archive=/tmp/cockpit-backup.gz --gzip
docker cp cockpit-mongo:/tmp/cockpit-backup.gz /backup/cockpit-$(date +%F).gz

恢复时使用 mongorestore --gzip --archive=/backup/cockpit-xxx.gz 即可。

4.3 多副本扩容建议

当流量增长时,可以把 MongoDB 扩展为"一主两从"副本集,并把 Cockpit 应用容器扩到 2~3 个实例,前面用 Nginx 做负载均衡。由于 Cockpit 应用本身无状态,扩容只需 docker compose up -d --scale cockpit=2,再在 Nginx 中配置 upstream 即可。

五、反向代理与 HTTPS:快速上线前必做的一步

Cockpit 容器默认监听 80 端口(Apache),我们把它映射到本机 8080,再由 Nginx 对外提供 HTTPS。参考配置:

server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

X-Forwarded-Proto 头一定要带上,否则 HTTPS 场景下 API 返回的 URL 可能错误地使用 http 协议。

六、上线检查清单与常见问题排查

上线前逐项检查:

  • sec-key 已通过环境变量替换为随机值
  • ✅ MongoDB 副本集 rs.status() 状态为正常(PRIMARY/SECONDARY)
  • storage 目录可写,安装引导检查项全部通过
  • ✅ HTTPS 已启用,API 仅通过反向代理对外暴露
  • ✅ 已配置每日数据库备份与恢复演练

常见问题速查:

现象原因与解决办法
安装页提示目录不可写检查 ./configcockpit_storage 挂载权限,容器内 www-data 用户 UID 为 1000
连接 MongoDB 失败确认 depends_on 的 healthcheck 生效,MongoDB 容器已初始化副本集
重启后数据丢失确认使用了命名卷而非匿名卷,且 docker compose down 而非 -v
更换数据库后老数据消失Cockpit 默认 SQLite 数据在 storage/data,切换 MongoDB 前先导出旧内容

七、总结

通过 Docker Compose 搭建高可用 Cockpit + MongoDB 集群并不复杂:官方镜像解决了 PHP 运行环境问题,config/config.php 一处配置即可从 SQLite 平滑切换到 MongoDB 副本集,再配合 Nginx 反向代理与定时备份,就能得到一个开箱即用、可横向扩展的企业级内容平台。希望这份生产环境部署指南能帮你一次上线成功,让内容团队专注创作,让开发团队专注业务。🚀

【免费下载链接】Cockpit Cockpit Core - Content Platform 【免费下载链接】Cockpit 项目地址: https://gitcode.com/gh_mirrors/cockp/Cockpit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值