如何在 Debian 12 上使用 Nginx 部署 Ghost 博客
在此页面上
- 先决条件
- 步骤 1 - 配置 UFW 防火墙
- 第 2 步 - 安装 Nginx
- 第 3 步 - 安装 Node.js
- 第 4 步 - 使用 Docker 安装 MySQL
第 5 步 - 安装 Ghost
- 安装 Ghost-CLI
- 准备Ghost目录
- 安装幽灵
Ghost 是一个开源博客平台,可帮助您创建具有专业外观的博客。它于 2013 年推出,作为 WordPress 的替代品。它是用 JavaScript 编写的,由 Node.js 库提供支持。
在本教程中,我们将探讨如何在 Debian 12 驱动的服务器上使用 Nginx 和 MySQL 安装 Ghost CMS。我们将使用 Let's Encrypt SSL 证书来保护我们的安装。
先决条件
运行 Debian 12 且 RAM 至少为 2GB 的服务器。
具有 sudo 权限的非 root 用户。
完全合格的域名 (FQDN),例如指向您的服务器的 example.com
。
确保一切都已更新。
$ sudo apt update
$ sudo apt upgrade
您的系统需要的软件包很少。
$ sudo apt install wget curl nano ufw software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release debian-archive-keyring unzip -y
其中一些软件包可能已经安装在您的系统上。
步骤 1 - 配置 UFW 防火墙
第一步是配置防火墙。 Debian 默认带有 ufw(简单防火墙)。
检查防火墙是否正在运行。
$ sudo ufw status
您应该得到以下输出。
Status: inactive
允许 SSH 端口,以便防火墙在启用它时不会中断当前连接。
$ sudo ufw allow OpenSSH
还允许 HTTP 和 HTTPS 端口。
$ sudo ufw allow http
$ sudo ufw allow https
启用防火墙
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
再次检查防火墙的状态。
$ sudo ufw status
您应该看到类似的输出。
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80/tcp ALLOW Anywhere
443 ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
第 2 步 - 安装 Nginx
Debian 12 附带旧版本的 Nginx。要安装最新版本,您需要下载官方 Nginx 存储库。
导入 Nginx 的签名密钥。
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
添加 Nginx 稳定版本的存储库。
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg arch=amd64] \
http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
更新系统存储库。
$ sudo apt update
安装 Nginx。
$ sudo apt install nginx
验证安装。在 Debian 上运行该命令需要 sudo
。
$ sudo nginx -v
nginx version: nginx/1.24.0
启动 Nginx 服务器。
$ sudo systemctl start nginx
第 3 步 - 安装 Node.js
Ghost 安装程序需要 Nodejs 才能工作。第一步是导入 Nodesource GPG 密钥。
$ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg
接下来,创建 Nodesource 存储库文件。我们将安装 Node 18x,这是 Ghost 推荐的当前 LTS(长期支持)版本。
$ NODE_MAJOR=18
$ echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
更新系统存储库列表。
$ sudo apt update
安装节点。
$ sudo apt install nodejs -y
确认节点安装。
$ node --version
v18.18.2
第 4 步 - 使用 Docker 安装 MySQL
Debian 不再附带 MySQL。相反,它随 MariaDB 一起提供。 Ghost仅支持MySQL。您可以调整 Ghost 以与 MariaDB 一起使用,但不建议这样做。由于在编写本教程时 MySQL 的官方存储库尚未针对 Debian 12 进行更新,因此我们将使用 Docker 安装它。
导入 Docker GPG 密钥。
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
创建 Docker 存储库文件。
$ echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
更新系统存储库列表。
$ sudo apt update
安装 Docker 和 Docker Compose。
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
默认情况下,Docker 需要 root 权限。如果您想避免每次运行 docker
命令时都使用 sudo
,请将您的用户名添加到 docker
组中。
$ sudo usermod -aG docker $(whoami)
您需要注销服务器并以同一用户身份重新登录才能启用此更改或使用以下命令。
$ su - ${USER}
确认您的用户已添加到 Docker 组。
$ groups
navjot wheel docker
现在 Docker 已安装,我们需要为 MySQL 创建一个 Docker compose 文件。为 MySQL docker 创建一个目录。
$ mkdir ~/mysql
创建并打开 docker-compose.yml 文件进行编辑。
$ nano docker-compose.yml
将以下代码粘贴到其中。
services:
database:
image: container-registry.oracle.com/mysql/community-server:latest
container_name: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_USER: ghost
MYSQL_PASSWORD: ghostpassword
MYSQL_DATABASE: ghostdb
ports:
- "3306:3306"
volumes:
- ./mysql:/var/lib/mysql
按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
在这里,我们设置了 Ghost 数据库的 root 密码和 MySQL 凭据。这些将在容器运行时创建。
启动 MySQL 容器。
$ docker compose up -d
检查 Docker 容器的状态。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec42fb205f1e container-registry.oracle.com/mysql/community-server:latest "/entrypoint.sh mysq…" 4 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060-33061/tcp mysql
Ghost可以使用端口3306连接到MySQL容器并对其执行操作。
第 5 步 - 安装 Ghost
我们也可以使用 Docker 安装 Ghost,这可以简化事情,但我们不会在这里这样做。
Ghost 安装将包含三个组件 - Ghost-CLI 命令行工具,用于安装和管理 Ghost 博客和博客包本身的更新。
安装 Ghost-CLI
运行以下命令安装Ghost-CLI工具。
$ sudo npm install ghost-cli@latest -g
准备Ghost目录
创建 Ghost 根目录。
$ sudo mkdir -p /var/www/html/ghost
将目录的所有权设置为当前用户。
$ sudo chown $USER:$USER /var/www/html/ghost
设置正确的目录权限。
$ sudo chmod 755 /var/www/html/ghost
切换到Ghost目录。
$ cd /var/www/html/ghost
安装幽灵
安装 Ghost 是一个单一命令过程。
$ ghost install
在安装过程中,CLI 工具会询问几个问题来配置博客。
- 博客 URL:输入完整的博客 URL 以及 https 协议。 (
https://example.com
) - MySQL 主机名:按 Enter 键使用
localhost
的默认值,因为我们的 Ghost 安装和 MySQL 位于同一服务器上。 - MySQL 用户名:输入
ghost
作为您的 MySQL 用户名。 - MySQL密码:输入之前在docker文件中创建的root密码。
- Ghost 数据库名称:输入 docker 文件中配置的数据库 (
ghostdb
) 的名称。 - Sudo 密码:它会要求您输入 sudo 密码来执行管理任务。
- 设置 Nginx? 通常,Ghost-CLI 会检测您的 Nginx 安装并自动为您的博客进行配置。但这仅适用于使用操作系统包安装的 Nginx。由于我们使用 Nginx 的存储库安装它,Ghost 无法检测到它并会自动跳过它。
- 设置 SSL?:由于它跳过了 Nginx 配置,因此 CLI 工具也将跳过设置 SSL。
- 设置systemd?:Ghost会询问您是否要为Ghost设置系统服务。按Y继续。
- 启动 Ghost?:按 Y 开始 Ghost 安装。但是,它不会工作,因为 Nginx 和 SSL 尚未配置。
第 6 步 - 安装 SSL
在继续之前,我们需要安装 Certbot 工具并为我们的域安装 SSL 证书。
要安装 Certbot,我们将使用 Snapd 软件包安装程序。 Snapd 始终携带最新稳定版本的 Certbot。不过 Debian 并未安装 Snapd。首先安装它。
$ sudo apt install snapd
确保您的 snapd 版本是最新的。
$ sudo snap install core
$ sudo snap refresh core
安装证书机器人。
$ sudo snap install --classic certbot
使用以下命令确保可以通过创建到 /usr/bin
目录的符号链接来运行 Certbot 命令。
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
验证安装。
$ certbot --version
certbot 2.7.1
生成 SSL 证书。
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email -d example.com
上述命令会将证书下载到服务器上的 /etc/letsencrypt/live/example.com
目录中。
生成 Diffie-Hellman 组证书。
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
检查 Certbot 续订调度程序服务。
$ sudo systemctl list-timers
您会发现 snap.certbot.renew.service
是计划运行的服务之一。
NEXT LEFT LAST PASSED UNIT ACTIVATES
Tue 2023-10-17 00:00:00 UTC 14h left Mon 2023-10-16 00:00:18 UTC 9h ago dpkg-db-backup.timer dpkg-db-backup.service
Mon 2023-10-16 19:12:00 UTC 9h left Mon 2023-10-16 07:27:11 UTC 2h 17min ago snap.certbot.renew.timer snap.certbot.renew.service
Mon 2023-10-16 20:49:14 UTC 11h left Mon 2023-10-16 07:48:12 UTC 1h 56min ago apt-daily.timer apt-daily.service
对该过程进行一次演练,以检查 SSL 续订是否正常工作。
$ sudo certbot renew --dry-run
如果没有看到任何错误,则一切都已准备就绪。您的证书将自动更新。
第 7 步 - 配置 Nginx
创建并打开文件 /etc/nginx/conf.d/ghost.conf
进行编辑。
$ sudo nano /etc/nginx/conf.d/ghost.conf
将以下代码粘贴到 ghost.conf
文件中。将 example.com
的所有实例替换为您的域名。
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
access_log /var/log/nginx/ghost.access.log;
error_log /var/log/nginx/ghost.error.log;
client_max_body_size 20m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] 8.8.8.8 8.8.4.4 [2001:4860:4860::8888] [2001:4860:4860::8844] valid=60s;
resolver_timeout 2s;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:2368;
}
}
上述配置会将所有 HTTP 请求重定向到 HTTPS,并将作为 Ghost 服务的代理通过您的域提供服务。
按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
打开文件 /etc/nginx/nginx.conf
进行编辑。
$ sudo nano /etc/nginx/nginx.conf
在 include /etc/nginx/conf.d/*.conf;
行之前添加以下行。
server_names_hash_bucket_size 64;
按 Ctrl + X 并在出现提示时输入 Y 来保存文件。
验证您的 Nginx 配置。
$ sudo nginx -t
如果您没有看到任何错误,则表示您可以开始了。重新启动 Nginx 服务器以应用配置。
$ sudo systemctl restart nginx
第 9 步 - 运行网站
现在,您可以通过在网络浏览器中打开 https://example.com
来验证您的安装。您将看到以下页面,表明安装成功。
第 10 步 - 完成设置
要完成 Ghost 博客的设置,请在浏览器中访问 https://example.com/ghost
。博客域末尾的额外 /ghost
会将您重定向到 Ghost 的管理面板,或者在本例中为您首次访问后的设置。
在这里,您需要创建管理员帐户并选择博客标题。
输入您的详细信息,然后点击创建帐户并开始发布按钮继续。
接下来,您将进入以下屏幕,您可以在其中看到一些选项,例如撰写第一篇文章、自定义您的网站和导入会员。
我们将选择Explore Ghost admin进行探索并直接进入仪表板。设置结束后,您将看到 Ghost 的管理面板。
如果您想切换到深色模式,可以通过单击设置页面底部设置齿轮按钮旁边的切换开关来实现。
您将看到默认帖子。您可以取消发布或删除它并开始发布。
第 11 步 - 配置邮件程序
Ghost 不仅充当博客平台,还充当时事通讯管理器。对于日常操作,您可以使用任何事务性邮件服务与 Ghost 一起发送邮件。但如果您想通过 Ghost 发送新闻通讯,唯一支持的官方批量邮件程序是 Mailgun。您也可以使用不同的时事通讯服务,但为此,您需要使用 Ghost 的 Zapier 集成功能。
让我们首先为事务性电子邮件配置 SMTP 服务。为此,打开文件 /var/www/html/ghost/config.development.json
文件进行编辑。
$ nano /var/www/html/ghost/config.production.json
找到以下几行。
"mail": {
"transport": "Direct"
},
将它们替换为以下代码。
"mail": {
"from": "'HowtoForge Support' [email ",
"transport": "SMTP",
"options": {
"host": "YOUR-SES-SERVER-NAME",
"port": 465,
"service": "SES",
"auth": {
"user": "YOUR-SES-SMTP-ACCESS-KEY-ID",
"pass": "YOUR-SES-SMTP-SECRET-ACCESS-KEY"
}
}
},
在这里,我们使用 Amazon SES 邮件服务,因为它价格实惠且不需要月费。
按 Ctrl + X 并在出现提示时输入 Y 来保存文件。完成后,重新启动 Ghost 应用程序以使更改生效。
$ ghost restart
要配置新闻通讯设置,请访问设置>>电子邮件新闻通讯部分。
单击Mailgun 配置链接展开。
填写您的 Mailgun 区域、域和 API 密钥。
单击右上角的保存按钮保存设置。
要测试新闻通讯的发送,请创建一个新的测试帖子,点击“发布”,然后选择仅通过电子邮件选项。如果您也想发布该帖子,请选择发布并通过电子邮件选项。
单击继续,最终审核按钮继续。下一页将再次要求最终确认。
单击立即发送电子邮件按钮发送新闻通讯。邮件发送后,您将收到以下消息。
检查您的电子邮件中是否有该帖子。
第 12 步 - 更新 Ghost
Ghost 更新有两种类型 - 次要更新和主要更新。
首先,如果您想运行次要更新,请进行完整备份。它创建所有帖子、成员、主题、图像、文件和重定向文件的备份。
$ cd /var/www/html/ghost
$ ghost backup
运行 update 命令来执行次要更新。
$ ghost update
要执行主要更新,您应该遵循 Ghost 上的官方详细更新指南。根据您当前使用的版本以及您想要更新到的主要版本,步骤会有所不同。
结论
关于如何使用 Nginx 在 Debian 12 服务器上设置 Ghost CMS 的教程到此结束。如果您有任何问题或任何反馈,请在下面的评论中分享。