Docker多容器编排实战:基于Ghost博客系统的完整部署方案

在当今云原生时代,Docker已成为应用部署的标准工具之一。而Docker Compose作为Docker官方的多容器编排工具,能够帮助我们轻松定义和运行复杂的多容器应用。本文将详细介绍如何使用Docker Compose部署一个完整的Ghost博客系统,包含Ghost应用、Nginx反向代理和MySQL数据库三个服务组件。

本次Docker实战基于🔗Docker入门教程,但是由于视频教程已经过时(早于2018年),一些配置需要修改,且ghost博客系统似乎已经不再免费,网络上有关ghost的内容也偏少,故颇费了一番功夫

项目架构设计

我们的Ghost博客系统采用典型的三层架构设计:

  1. 前端层:Nginx作为反向代理服务器,接收外部请求并转发给Ghost应用
  2. 应用层:Ghost博客系统本身,提供内容管理和发布功能
  3. 数据层:MySQL数据库持久化存储博客数据

目录结构解析

1
2
3
4
5
6
7
8
9
ghost/
├── ghost/
│ ├── config.production.json
│ └── Dockerfile
├── nginx/
│ ├── nginx.conf
│ └── Dockerfile
├── data/
└── docker-compose.yml
  • ghost/目录包含Ghost应用的相关配置和Dockerfile
  • nginx/目录包含Nginx的配置文件和Dockerfile
  • data/目录用于持久化MySQL数据
  • docker-compose.yml是核心的编排文件

深入解析Docker Compose配置

docker-compose.yml文件是整个项目的核心,它定义了三个服务及其相互关系:

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
version: '2'

networks:
ghost:

services:
ghost-app:
build: ghost
networks:
- ghost
depends_on:
- db
ports:
- "2368:2368"

nginx:
build: nginx
networks:
- ghost
depends_on:
- ghost-app
ports:
- "80:80"

db:
image: "mysql:5.7.15"
networks:
- ghost
environment:
MYSQL_ROOT_PASSWORD: mysqlroot
MYSQL_USER: ghost
MYSQL_PASSWORD: ghost
volumes:
- $PWD/data:/var/lib/mysql
ports:
- "3306:3306"

原教程中使用ghost用户访问mysql数据库报错权限不足,故改用root用户

网络配置

我们创建了一个名为ghost的自定义网络,所有服务都连接到这个网络。这样服务之间可以通过服务名相互访问(如Ghost可以通过db主机名访问MySQL服务),而无需关心IP地址变化。

服务依赖关系

  • ghost-app依赖于db服务,确保数据库先启动
  • nginx依赖于ghost-app服务,确保应用服务先启动

数据持久化

MySQL服务使用volumes将容器内的/var/lib/mysql目录映射到宿主机的./data目录,确保数据库数据不会因容器重启而丢失。

Ghost应用配置详解

Ghost的配置文件config.production.json包含了应用的核心配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"url": "http://localhost",
"server": {
"port": 2368,
"host": "0.0.0.0"
},
"database": {
"client": "mysql",
"connection": {
"host": "db",
"user": "root",
"password": "mysqlroot",
"database": "ghost",
"port": 3306,
"charset": "utf8"
},
"debug": false
},
// 其他配置...
}

关键点说明:

  • 数据库连接使用服务名db作为主机名,这是Docker网络提供的服务发现能力
  • 数据库凭据与docker-compose中定义的MySQL环境变量一致
  • 服务器监听0.0.0.0以便容器外部可以访问

./ghost/Dockerfile

1
2
3
4
5
6
FROM ghost:5.94.1
#COPY ./config.js /var/lib/ghost/content/config.js
#CMD ["cat", "config.production.json"]
COPY ./config.production.json /var/lib/ghost/config.production.json
EXPOSE 2368
#CMD ["npm", "start", "--production"]
  • 指定了使用官方 Ghost 镜像的 5.94.1 版本作为基础。官方镜像已经预配置了 Node.js 环境和 Ghost 运行所需的所有依赖
  • 将宿主机上的配置文件复制到容器内 Ghost 的默认配置目录
  • 声明容器运行时监听的端口, Ghost 默认使用 2368 端口:
  • 注释掉的 CMD [“npm”, “start”, “–production”],这是不必要的,因为新版本Ghost基础镜像已经包含了正确的启动命令

原教程中旧版本ghost使用config.js文件进行配置,且需要加上启动命令

Nginx反向代理配置

Nginx作为前端代理,将所有80端口的请求转发到Ghost应用的2368端口:

1
2
3
4
5
6
7
8
9
10
worker_processes 4;
events {worker_connections 1024;}
http {
server {
listen 80;
location / {
proxy_pass http://ghost-app:2368;
}
}
}

这里同样利用了Docker网络的服务发现能力,通过服务名ghost-app访问Ghost应用。

./nginx/Dockerfile

1
2
3
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
  • FROM nginx 使用了最新版的官方 Nginx 镜像,官方镜像已经包含了 Nginx 的最佳实践配置
  • 用自定义配置完全替换默认的 Nginx 配置, 目标路径 /etc/nginx/nginx.conf 是 Nginx 的主配置文件位置
  • EXPOSE 80 声明容器将监听 HTTP 默认端口, 对应 docker-compose.yml 中的端口映射, 实际访问会通过宿主机的 80 端口暴露服务

构建与部署流程

完整的构建和部署流程如下,在ghost项目目录下:

  1. 停止现有服务:docker-compose stop
  2. 强制删除容器:docker-compose rm -f
  3. 重新构建镜像:docker-compose build
  4. 启动服务:docker-compose up -d
  5. 查看日志:docker-compose logs

这套命令序列确保了每次部署都是全新的状态,避免了旧容器和镜像带来的潜在问题。

技术要点总结

  1. 服务发现:Docker网络自动提供DNS解析,容器间通过服务名通信
  2. 依赖管理depends_on确保服务按正确顺序启动
  3. 配置管理:各服务的配置通过Dockerfile和docker-compose.yml集中管理
  4. 数据持久化:通过volume实现MySQL数据的持久化存储
  5. 环境隔离:自定义网络隔离了服务间的通信

扩展思考

通过这个实战项目,我们不仅学会了Docker Compose的基本用法,更重要的是理解了如何设计一个可维护、可扩展的容器化应用架构。这种模式可以推广到其他类似的Web应用部署场景中。


Docker多容器编排实战:基于Ghost博客系统的完整部署方案
https://blog.cngo.xyz/posts/9739.html
作者
cngo
发布于
2025年4月16日
许可协议