> ## Content Index
> Fetch the complete content index at: https://blog.20061124.xyz/llms.txt
> Use this file to discover other available public pages before exploring further.

# 把博客搬上自己的服务器：Docker + Ghost 部署记录
- URL: https://blog.20061124.xyz/docker-ghost-deploy/
- Published: 2026-09-30T02:00:00.000Z
- Updated: 2026-10-01T06:56:53.000Z
- Description: 用 Docker 在一台自己的服务器上跑 Ghost：容器怎么起、数据怎么挂、反向代理怎么配，以及几个容易忽略的细节。
- Author: Ray Jack
- Tags: 运维

用第三方平台写博客，最大的问题是：你不知道它哪天会改规则、涨价，或者干脆关掉。数据不在自己手里，样式也由别人说了算。所以我把博客搬到了一台自己的服务器上，用 Docker 跑 Ghost。

这篇记录一下整个过程，包括几个容易忽略的细节。

## 一、为什么是 Ghost + Docker

选 Ghost 的理由很简单：它是专门为写博客做的，后台干净，内容用编辑器写，主题是标准的 Handlebars 模板，想改前端随时可以改，不需要动后端。

选 Docker 的理由更简单：博客这种东西装一次可能几年不动，但服务器上还会跑别的东西。用容器隔离，升级 Ghost 的时候不用担心把系统里的 Node 版本搞乱。

## 二、起一个 Ghost 容器

Ghost 官方镜像直接可用，一条命令就能跑起来：

```
docker run -d \
  --name ghost \
  --restart always \
  -p 127.0.0.1:2368:2368 \
  -v /opt/ghost/content:/var/lib/ghost/content \
  -v /opt/ghost/config/config.production.json:/var/lib/ghost/config.production.json \
  -e NODE_ENV=production \
  ghost:6

```

这里有两个细节值得说：

- `-p 127.0.0.1:2368:2368` 里前面的 `127.0.0.1` 不要省。只写 `-p 2368:2368` 的话，Docker 会把它绑到 `0.0.0.0`，也就是对整个公网开放，并且绕过你的反向代理和 HTTPS。
- 数据一定要挂出来。`/var/lib/ghost/content` 里有文章图片、主题、上传的文件；`config.production.json` 里有数据库密码和邮件配置。这两样不挂载，容器一删就全没了。

## 三、反向代理和 HTTPS

Ghost 自己不管 HTTPS，前面要放一个反向代理。用 Nginx 或者 OpenResty 都行，核心就三件事：转发到 2368、把 `X-Forwarded-Proto` 设成 `https`、别把上传大小限制得太小。

```
location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    client_max_body_size 50m;
    proxy_pass http://127.0.0.1:2368;
}

```

`X-Forwarded-Proto` 这行漏掉的话，Ghost 会以为自己跑在 HTTP 上，登录后台时会出现重定向死循环，或者 Cookie 死活存不上。

## 四、数据库别用默认的

Ghost 默认用 SQLite，小站够用，但如果服务器上已经有 MySQL，直接复用更好，备份和迁移都方便。配置写在 `config.production.json` 的 `database` 段里：

```
{
  "database": {
    "client": "mysql",
    "connection": {
      "host": "127.0.0.1",
      "port": 3306,
      "user": "ghost",
      "password": "……",
      "database": "ghost"
    },
    "pool": {
      "min": 0,
      "max": 10,
      "idleTimeoutMillis": 60000
    }
  }
}

```

注意 `pool` 这一段。Ghost 默认的连接池配置不一定适合低流量的站，写清楚比较省事——具体原因可以看另一篇《MySQL 连接池的坑》。

## 五、备份

自己管服务器，备份就得自己负责。至少要备两样东西：

- **数据库**：用 `mysqldump` 导出一份 SQL
- **`/opt/ghost/content`**：图片、上传的文件和主题

特别是主题目录。用现成主题还好，自己改过的主题不备份，哪天手滑就白改了。改动之前先 `cp` 一份带时间戳的备份，成本几乎为零，救命的次数不少。

## 六、小结

整个流程其实不复杂：起容器、挂数据、配反代、接数据库。真正花时间的不是「怎么装」，而是「装完之后怎么让它稳定跑着不出事」——连接池、备份、证书续期，这些才是自己管服务器的日常。

换来的是：数据在自己手里，前端想怎么改就怎么改。