使用 Docker 自托管 Ghost 实例的 7 个有用技巧

是一个 开源CMS平台 它轻巧,快速,专注于建立会员网站。

你总是可以 选择 Ghost 的托管主机 本身。 但由于它是开源软件,您也可以自由地将其托管在自己的服务器上并自行管理。

借助 Linode 和 DigitalOcean 等云服务,只需单击几下即可部署安装了 Ghost 的新 Linux 服务器。

虽然在云服务器上部署 Ghost 是一项相对容易的任务,但管理 Ghost 可能并不总是那么容易。

几个月来,我们一直在管理我们的 Ghost 实例来托管 Linux 手册。 这段经历教会了我们一些你在 Ghost 官方文档中可能找不到的东西。

在本文中,我将讨论在生产服务器上部署 Ghost 驱动的博客之前要考虑的一些关键因素。

请记住,本文是关于 Ghost 的 Docker 映像,由开发人员社区构建和管理。

在 DevOps 社区中,我们一直努力的目标是获得 close 尽可能走向一个叫做 无操作. 但在实际意义上,它永远是一个 悖论.

在这里,我们正试图实现与 NoOps 相同的目标,但在必要时采用混合前景和人工干预。

因此,事不宜迟,让我列出并描述确保一个稳定且维护最少的 Ghost 实例的基本要素。

1.正确设置您的邮件配置

你会 F通过您的 Ghost 实例向您的成员和订阅者发送各种电子邮件:

  • 交易电子邮件:用于会员登录、注册确认等。
  • 批量电子邮件:用于通过 Ghost 发送电子邮件通讯

如果您不想通过 Ghost 传递时事通讯,您可以使用任何 SMTP 服务。 否则,您必须使用 邮筒.

交易电子邮件的 SMTP 设置

理论上,您的 Ghost 实例应该能够使用直邮服务,这要归功于 节点邮件程序.

但是,这可能会导致某些注册失败并显示“请 Enter 有效的电子邮件地址”错误消息。

这就是为什么您必须设置 SMTP 设置 邮筒 或者 亚马逊 SES. 你也可以试试其他 电子邮件中继服务发送网格 或者 邮件黑猩猩.

通过 Mailgun 配置的典型 SMTP 设置如下所示(通过 绑定安装 文件 config.production.json):

  "mail": {
    "transport": "SMTP",
    "options": {
        "service": "Mailgun",
        "host": "smtp.eu.mailgun.org",
        "port": 465,
        "secureConnection": true,
        "auth": {
            "user": "replace-me-with-a-mailgun-configured-email-address",
            "pass": "replace-me-with-the-relevant-mailgun-apikey"
        }
    }
  },

注意 SMTP 端口号. 有时电子邮件会因为端口号而失败。 在我们的案例中,一些电子邮件在端口 587 上失败并开始使用端口 465。

请从 Mailgun 检查此文档 这里 有关验证您的域和更新发送电子邮件所需的必要 DNS 记录的完整信息。

通常,您必须在域名面板的 DNS 记录设置中更新从 Mailgun 获得的 MX、CNAME 和 TXT 记录。 在 Linode 上,它们看起来像:

Mailgun MX 记录
Mailgun TXT 记录Mailgun TXT 记录

用于发送时事通讯的批量电子邮件

为了 批量发送时事通讯 对您的成员来说,Mailgun 是唯一可用于在您的 Ghost 配置中实现它的可用服务。 批量电子邮件服务是 很不一样 来自传统的 SMTP 服务。

要在 Ghost 上为您的会员正确配置批量电子邮件,首先您必须确保启用会员资格。 这是一个明显的要求。

幽灵设置 > 实验室 > 成员

现在向下滚动到电子邮件部分并展开“电子邮件通讯设置”。

Enter Mailgun 配置的域名和 API 密钥。 Mailgun 区域将是“欧盟”或“美国”。 请选择合适的一种。

如果您从上面的 SMTP 设置中回忆 example,地区名,“EU”可以用主机名来感知,即 smtp.eu.mailgun.org.

这里 有关 Mailgun 配置的域名和 API 密钥的更多信息。 要选择域名,请检查 这里.

2. 数据库选择 MySQL 或 MariaDB 而不是 SQLite

如果您的 Ghost 博客计划用于生产用途,我建议不要使用 SQLite Ghost 容器中默认提供的数据库。

使用推荐的原因 数据库 作为 MySQL 或者 玛丽亚数据库 当您拥有大量成员并且想要从 Ghost 本身向他们发送电子邮件时事通讯时,这一点非常重要。

我们以艰难的方式学会了它。 最初,我们使用 MailerLite 来创建和发送时事通讯。 然后我们决定利用 Ghost 的内置通讯功能。

到目前为止,我们有大约 1,100 名成员。 这造成了一个问题,因为 SQLite 无法一次处理这么多查询。 新创建的帖子发送失败。 日志显示此错误:

Processed job threw an unhandled error
"The email service was unable to send an email batch."

Error ID:
    24bf8000-4f50-11eb-adf5-73dcc562a630

Error Code: 
    SQLITE_ERROR

不是这样。 它甚至拒绝输出1100名成员。 下载将无法开始。 我们以 JSON 格式下载了整个备份,并从那里提取了成员信息。

要解决此问题,请从 SQLite 迁移到 MySQL 或 MariaDB,这将成为不必要的开销,并导致迁移期间可能出现不必要的停机时间,甚至可能是无限期的停机时间。 因此,作为预防措施,最好先将 Ghost 与 MySQL 或 MariaDB 一起部署。

以下是一个 example Docker Compose 上 Ghost 的典型 MariaDB 数据库服务配置:

    db:
        image: mariadb:10.5.3
        volumes:
            - ghostdb:/var/lib/mysql
        restart: on-failure
        environment:
            MYSQL_RANDOM_ROOT_PASSWORD: 1
            MYSQL_USER: rename-me
            MYSQL_PASSWORD: replace-me
            MYSQL_DATABASE: rename-me

3.启用日志轮换

日志轮换是在所需时间段后自动重置日志文件的过程。 这有助于避免创建大量日志文件堆积并不必要地侵入您的服务器磁盘空间。 通常,如果您在 Ghost 配置中不包含以下代码段,则会导致日志文件累积到 15-20 GB 之间的巨大大小!:

  "logging": {
    "path": "content/logs/",
    "level": "info",
    "rotation": {
      "enabled": true,
      "count": 15,
      "period": "1d"
  },

有关登录 Ghost 的详细概述,您可以访问其相关 文档页面.

3.使用反向代理

在部署 Ghost 之前,从一开始就使用反向代理总是一个额外的优势。 它使您在短期和长期管理 Web 应用程序变得更加容易。

4.无停机更新Ghost

如果您使用反向代理,在不停机的情况下更新您的 Ghost 实例将是一件容易的事。

这是我推荐的。 设置 Docker Notify,以便您收到有关 Ghost 实例的新 Docker 映像的通知(使用最新版本的 Ghost)。

然后您可以按照本教程更新您的 Docker 容器。

幸运的是,执行更新时完全没有停机时间。 如果您已经登录到 admin 面板(比如在撰写文章时),您不会注意到任何异常。

但是,如果您没有登录,直到您在更新后删除旧容器, admin 如果您尝试重新登录,面板将继续尝试加载自身。

但在生产意义上,Ghost 博客本身将继续在前端可用,即使在您执行升级时也是如此。

6.始终设置重启策略

由于您使用的是 Ghost Docker 容器,因此重新启动策略始终非常重要,并且必须在您的配置中指定。 这可确保您的 Ghost 容器在您的物理服务器因任何维护事件而重新启动时始终自行重新启动。

如果您的通用 Docker 配置有 实时恢复 启用,建议使用 on-failure 重启政策。 为了更好地了解重启策略,请查看 官方文档 有关此类政策的完整参考。

通常,您在 Docker Compose 文件的服务中设置这样的重启策略:

restart: on-failure

7. 使用外部 Docker 卷

如果您使用在部署 Ghost 之前手动创建的卷,则可以在将来需要时更轻松地迁移您的内容(在同一服务器或其他服务器中)。 它使您可以更好地控制您的数据,因为是您创建和指定供 Ghost 容器使用的卷。 否则,您需要将其留给 Docker Compose 在本地创建。

要为 Ghost 容器创建外部 Docker 卷,请使用以下命令:

docker volume create ghost

在哪里 ghost 是您的外部 Docker Ghost 卷的名称。

由于我已经提到选择 MySQL 或 MariaDB 数据库以确保在成千上万的用户中获得更好的性能,因此还必须以相同的方式创建其卷:

docker volume create ghostdb

在哪里 ghostdb 是您的外部 Docker Ghost 数据库卷的名称。

要指示 Docker Compose 使用您刚刚在上面创建的这些特定卷,Docker Compose 文件中的卷部分必须如下所示:

volumes:
  ghost:
    external: true
  ghostdb:
    external: true

请注意我如何指定这些 Docker 卷本质上是外部的。

额外提示:安排定期备份

服务器备份

如果您正在使用 锂节点, 数字海洋 或任何其他类似的云服务器提供商,强烈建议您在创建服务器以部署 Ghost 时始终启用备份。

为了 example,当您在 Linode 上创建具有 1 GB RAM(称为 nanode)的服务器时,您会发现一个要求启用备份的复选框。 每当您部署生产服务器时,我总是建议您在开始实际启动服务器以进行首次启动之前启用它。

此外,您可以基于 crontab 在服务器上部署脚本,以手动为 Ghost 拍摄外部 Docker 卷的快照。

从技术上讲,体积数据如前面的指针 7 中所述,特别是 ghostghostdb当地居住在 /var/lib/docker/volumes/ghost/_data/var/lib/docker/volumes/ghostdb/_data 分别。 为了有效地归档它们,您可以使用 tar 定期备份这两个目录。

既然你现在会知道这些 tar 存档后将随时可用,您还可以在本地系统上部署另一个脚本(假设每天在您家/办公室的特定时间实时运行)以 ssh 进入 Ghost 服务器并获取这些存档。 这样一来,无论您是否可以访问 Internet,您都可以随时获得 Ghost 博客的本地更新副本。

或者,您也可以使用数据库命令使用逻辑备份方法备份 MySQL 数据库 mysql转储. 在 MariaDB 上该命令被称为 mariadb-dump 这不过是相同的符号链接 mysqldump 命令。

可以找到物理备份和逻辑备份之间的出色比较 这里.

驯服幽灵

这是一些不同方法的汇编,可在您部署 Ghost 实例后最大限度地减少和防止任何潜在的维护问题发生。 希望每当您在 Ghost 上启动或使用自己的博客时它对您有用。

我们将继续我们的 Ghost 之旅,如果我们在部署时遇到任何其他可以通过不同配置避免的问题,我们将更新本文。

如果您对上述讨论的建议有任何建议或有任何新建议,请在下面的对话部分与我们分享。 我们很高兴阅读并了解您的更多信息。