Ghost 更新与迁移

内容追加

最近更新日期:2023-02-08

本次记录迁移至 DigitalOcean 的过程,IP 检查借助 geoiplookup,Prism.js 配置使用 k88hudson

Commands Memo

doctl, the DigitalOcean command-line tool, to connect to your Droplet with SSH.

doctl compute ssh 指令:通过提供的 ID 或名称使用 SSH 访问 Droplet。

doctl compute ssh ghostonubuntu2204-digitalocean --ssh-key-path /Users/.../..._id_rsa

ssh-add is a command for adding SSH private keys into the SSH authentication agent for implementing single sign-on with SSH.

将密钥文件路径作为参数提供给 ssh-add 后,即可使用 ssh user@ip 访问。

ssh-add ~/.ssh/..._id_rsa
ssh -v root@???

未将私钥添加给 ssh-agent 而直接用 ssh user@ip 访问会出现权限的异常。

debug1: Trying private key: /Users/.../id_dsa
debug1: No more authentication methods to try.
root@143.198.100.???: Permission denied (publickey).

使用 ~/.ssh/config 可简化每次重启就要 ssh-add ~/.ssh/?_rsa 的操作。

Mosh

由于最近迁移的服务器部署在 San Francisco,从国内通过 ssh 进行连接时,存在较大的延迟,故使用这款基于 UDP 的 Mosh。

SSH waits for the server's reply before showing you your own typing. That can make for a lousy user interface. Mosh is different: it gives an instant response to typing, deleting, and line editing.

VPS 可通过 sudo apt-get install mosh 安装,在开启服务时需要注意防火墙的状态和限制的端口,Ubuntu 可使用 ufw status 进行查看,或使用 lsof -i :60001 进行验证。Local 的 Mac 直接通过 brew install mosh 安装即可。

直接连接时会导致滚动页面的失效,且滚动的是历史命令。这是由于 Mosh 仅是相当于远程服务端的 screen snapshot 所造成的。

如果需要阻止 mosh 替代屏幕,那么应该加上 --no-init

mosh root@143.198.100.??? --no-init

Add Swap Space

内存负载过高会导致应用不定期的离线以及文件上传失败等问题,除开升级硬件配置以外,也可以通过交换文件的方式来向服务器添加额外的交换空间。

在内存不够的情况下,操作系统会先把内存中暂时不用的数据,存储到硬盘的交换空间,腾出内存来让别的程序运行。具体过程可参考 digitalocean 的 tutorials

Cloudflare DNS

登录状态在 Cloudflare 导航栏中点击 Websites 并选择需要 DNS 的域名,在 Quick Actions 中可以进一步地修改已经设置过的 DNS Settings。

需要注意 Cloudflare 自动完成的域名解析可能会添加不需要的配置:

  • 不需要用到的 CDN 服务:将 Proxy status 设置为 DNS only
  • 额外的域名解析:在 Actions 中的 Edit 里删除即可

快速上手

Node

最新 Ghost 版本需要 Node@14.x,应安装适用于 Ubuntu 的 二进制发行版

# Using Ubuntu 添加 Node.js ppa(Person Package achives) 安装 Node.js
# cURL is an abbreviation for Client URL Request Library which is used to transfer data from one place to another place. 
# -f (--fail) 表示在服务器错误时, 阻止一个返回表示错误原因的 html 页面
# -S (--show-error) 使curl在失败时显示错误消息 -s (--silent) 不显示进度表或错误信息的安静模式
# -L (--location) 如果服务器报告请求的页面已移动到其他位置,将使curl在新位置上重新执行请求
curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v
# v14.17.2

Ghost

Ghost@v3 需先通过 ghost update v3 获取到最新的 v3.x 版本,再运行 ghost update 升级到 v4。

更新期间出现目录所属权限的问题:使用 sudo chown /var/www/ghost 命令。

sudo systemctl is-active ghost_zairesinatra-com
✔ Checking system Node.js version - found v10.24.0、Ensuring user is not logged in as ghost user
✖ Checking if logged in user is directory owner
✖ Checking current folder permissions
✔ Checking folder permissions、Checking file permissions、Checking content folder ownership、Checking memory availability、Checking free space
One or more errors occurred.

1) Checking if logged in user is directory owner

Message: Your user does not own the directory /var/www/ghost and is also not a member of the owning group.
You must either log in with the user that owns the directory or add your user to the owning group.
Help: https://ghost.org/docs/install/ubuntu/#create-a-new-user

2) Checking current folder permissions

Message: The directory /var/www/ghost is not writable by your user. You must grant write access and try again.
Help: https://ghost.org/docs/install/ubuntu/#create-a-directory

Debug Information:
OS: Ubuntu, v18.04.4 LTS、Node Version: v10.24.0、Ghost Version: 3.41.9、Ghost-CLI Version: 1.17.3、Environment: production、Command: 'ghost update'

Try running ghost doctor to check your system for known issues.

更新前出现报错:ghost-cli@1.5.0 后 root 不允许运行 Ghost 相关的命令。

解决方式:将当前安装迁移到新的 Linux 用户

We discovered that you are using the DigitalOcean One-Click install. You need to create a user with regular account privileges and migrate your installation to this user.

增加一个新用户,并添加到 sudo 组。

$ adduser <user>
$ usermod -aG sudo <user>

创建新实例文件并移动到指定的位置 => 文件从属关系给予新用户。

$ mkdir -p /home/<user>/.ghost/
$ chown <user>:<user> /home/<user>/.ghost
$ mv /root/.ghost/config /home/<user>/.ghost/config
$ chown <user>:<user> /home/<user>/.ghost/config

切换到 Ghost 安装目录 /var/www/ghost 以更改所有权,并以新身份登录。

$ cd /var/www/ghost
$ find . -group root -user root -exec chown <user>:<user> {} \;
$ su - <user>

继续更新;启动后为非 https 状态,需配置 config.production.json 文件后重启。

$ ghost update v3
+ sudo systemctl is-active ghost_zairesinatra-com
✔ Checking system Node.js version - found v14.17.2
✔ Ensuring user is not logged in as ghost user
✔ Checking if logged in user is directory owner
✔ Checking current folder permissions
✔ Checking folder permissions
✔ Checking file permissions
✔ Checking content folder ownership
✔ Checking memory availability
✔ Checking free space
✔ Checking for available migrations
✔ Checking for latest Ghost version

# 3.42.5

This release contains a security patch.

* 🔒 Added a way to hide the secret settings once they are set - Thibaut Patel

---

View the changelogs for full details:
* Ghost - https://github.com/tryghost/ghost/compare/3.42.4...3.42.5
* Ghost-Admin - https://github.com/tryghost/admin/compare/3.42.4...3.42.5

✔ Fetched release notes
Version already installed.
ℹ Downloading and updating Ghost [skipped]
✔ Linking latest Ghost and recording versions
ℹ Removing old Ghost versions [skipped]
newghostzs@VM-4-10-ubuntu:/var/www/ghost$ ghost update
+ sudo systemctl is-active ghost_zairesinatra-com
✔ Checking system Node.js version - found v14.17.2
✔ Ensuring user is not logged in as ghost user
✔ Checking if logged in user is directory owner
✔ Checking current folder permissions
✔ Checking folder permissions
✔ Checking file permissions
✔ Checking content folder ownership
✔ Checking memory availability
✔ Checking free space
✔ Checking for available migrations
✔ Checking for latest Ghost version

# 4.10.1

* 🐛 Fixed GScan error when handling partials with undefined names - Thibaut Patel

---

View the changelogs for full details:
* Ghost - https://github.com/tryghost/ghost/compare/v4.10.0...v4.10.1
* Admin - https://github.com/tryghost/admin/compare/v4.10.0...v4.10.1

✔ Fetched release notes
✔ Downloading and updating Ghost to v4.10.1


Checking theme compatibility for Ghost 4.10.1

✔ Your theme is compatible.

You can also check theme compatibility at https://gscan.ghost.org

Please review the full list of breaking changes at https://ghost.org/docs/changes/

? Are you sure you want to proceed with migrating to Ghost 4.10.1? Yes
✔ Updating to a major version
✔ Linking latest Ghost and recording versions
✔ Removing old Ghost versions

Nginx

考虑到直接输入根域名重定向到 www 的页面,在 ghost 自带生成的 nginx ssl 配置外,额外自行写一个 nginx 重定向的 conf 配置。

# sites-available 中的 zs.com-ssl.conf
server {
	#监听 80 和 443端口
        listen 80;
        listen 443 ssl http2;
        #域名
        server_name	zs.com;
        # 放置的项目路径
        root /var/www/html;
        # 显示首页
        index index.html;
        # 配置ssl证书的位置-放置位置
        # 也可通过 ghost config url https://xxx.com 与 ghost setup nginx ssl 完成
        # ghost 初次设置了url后可通过 ghost setup ssl 直接生成 ssl nginx 配置
        ssl_certificate	/etc/nginx/ssl/zs.com_nginx/zs.com_bundle.crt;
        ssl_certificate_key	/etc/nginx/ssl/zs.com_nginx/zs.com.key;
        #开启强制http跳转https
        if ($server_port = 80){
       	rewrite ^(/.*)$ https://$host$1 permanent;
       	}
	location / {
		return 301 https://www.zs.com$request_uri;
	}
}
# 建立软连接
$ ln -s /etc/nginx/sites-available/zs.com-ssl.conf /etc/nginx/sites-enabled/zs.com-ssl.conf
# 测试配置文件
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# 重启服务
$ sudo nginx -s reload

Let's Encrypt

收到官方邮件的提醒,表示在一定时间后 LetsEncrypt 的证书将要到期,这里值得注意的是,通过 Ghost 集成的 LetsEncrypt 证书只有 90 天的有效期,意味着需要一个季度手动更新一次。

Your certificate (or certificates) for the names listed below will expire in 17 days (on 20 Jul 19 07:56 +0000). Please make sure to renew your certificate before then, or visitors to your web site will encounter errors.
We recommend renewing certificates automatically when they have a third of their total lifetime left. For Let's Encrypt's current 90-day certificates, that means renewing 30 days before expiration. See https://letsencrypt.org/docs/integration-guide/ for details.

  • Renew Ghost Let's Encrypt SSL
# Renew certificate
ghost setup ssl-renew
# Switch to root user
sudo su
# Upgrade acme.sh inside letsencrypt
"/etc/letsencrypt"/acme.sh --upgrade --home "/etc/letsencrypt"
# Renew SSL through acme.sh
"/etc/letsencrypt"/acme.sh --cron --home "/etc/letsencrypt" --debug --log
# 执行到这一步若出现 Add '--force' to force to renew. 的提示表示当前还是处于有效期, 需要进行强行更新
"/etc/letsencrypt"/acme.sh --cron --home "/etc/letsencrypt" --debug --log --force
# 查看当前证书信息
/etc/letsencrypt/acme.sh --home "/etc/letsencrypt" --list
  • check expiry date of SSL cert for ghost blog => clickme

Chrome 中点开 view site information 并选择 connection is secure,在 certificate is valid 中查看。

版本迭代

由于 Ghost 或 Node 版本的更新会导致部分内容存在不兼容的情况,此章节记录对于这种改动处理时需要注意的方面。

Ghost Init

.post-template .gh-head,
.page-template .gh-head {
  background: #000000 !important;
}
.site-footer {
  background: #000000 !important;
}
.post-card-tags {
  color: var(--color-secondary-text) !important;
}
.gh-portal-triggerbtn-container.with-label::before {
  display: none !important;
}
/* 需提前,否则闪烁 */
.footer-cta,
a.gh-head-button {
  display: none;
}

Update Node

$ npm install -g ghost-cli@latest
added 491 packages, and audited 492 packages in 24s
41 packages are looking for funding
  run `npm fund` for details
6 vulnerabilities (5 moderate, 1 high)
To address all issues (including breaking changes), run:
  npm audit fix --force
Run `npm audit` for details.

npm audit 命令将项目中配置的依赖项的描述提交到默认注册表,并要求报告已知漏洞。如果发现任何漏洞,将计算影响和适当的补救措施。如果没有发现漏洞,该命令将以 0 退出代码退出;若某些漏洞无法自动修复,则需要人工干预或审查。

$ npm audit fix --force
npm WARN using --force Recommended protections disabled.
npm ERR! code ENOLOCK
npm ERR! audit This command requires an existing lockfile.
npm ERR! audit Try creating one first with: npm i --package-lock-only
npm ERR! audit Original error: loadVirtual requires existing shrinkwrap file
npm ERR! A complete log of this run can be found in: /Users/xieziyi/.npm/_logs/2022-07-27T05_03_02_392-debug-0.log

执行指导修复的代码 npm i --package-lock-only,没有 package.json 文件。

$ npm i --package-lock-only
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /Users/xieziyi/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/Users/xieziyi/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/xieziyi/.npm/_logs/2022-07-27T05_03_19_779Z-debug-0.log

在当前目录进行 npm 初始化创建 package.json 文件。

$ cd /Users/xieziyi
$ npm init -y
Wrote to /Users/xieziyi/package-json:{...}
$ npm install -g ghost-cli@latest
changed 491 packages, and audited 492 packages in 3s
41 packages are looking for funding
  run `npm fund` for details
6 vulnerabilities (5 moderate, 1 high)
To address all issues (including breaking changes), run: npm audit fix --force
Run `npm audit` for details.
$ npm fund
xieziyi@1.0.0
$ npm audit fix --force
npm WARN using --force Recommended protections disabled.
up to date, audited 1 package in 89ms
found 0 vulnerabilities

Update Ghost

ghost update 会取代旧版本服务,对于旧版文件的更改将失效,需要在新 version 中再次进行配置。

  • 2022-08-21 更新 => v5.10.1

Disqus 在 Ghost v5.10.1 中不再有 65-69 行的评论代码块提示。可在 Ghost 新增特性 comments 代码块下追加 Disqus 代码。

{{#if comments}}
    <section class="article-comments gh-canvas">
        {{comments}}
    </section>
{{/if}}
<section class="article-comments gh-canvas">
    <div id="disqus_thread"></div>
    <script>
        var disqus_config = function () {
            this.page.url = "{{url absolute="true"}}";
            this.page.identifier = "ghost-{{comment_id}}"
        };
        (function() {
        var d = document, s = d.createElement('script');
        s.src = 'https://zsxzy.disqus.com/embed.js';
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
        })();
    </script>
</section>

Ghost & Github Pages

虽然 GitHub Pages 上 Jekyll 与 Ghost 项目仍然在稳定运行,但因为有科学上网的限制,可能会存在访问上的痛点。考虑到往后的迁移,故记录备份与配置的过程。

命令 ghost start|stop 须在该安装 Ghost 的文件夹目录下执行,否则会出现 Working directory is not a recognisable Ghost installation. 的错误。

将 Local Ghost 生成静态页面步骤如下:

  • shellScript 保存在本地 Ghost 网站的根目录中,用于将 Local Ghost 编译成静态页面
  • 修改该文件中 # Define urls and https 部分
# Define urls and https
from_url=https://zairesinatra.github.io/ # change this if your local ghost url is different
to_url=yourdomain.com # change it to your real domain name (no add https)
to_https=true # set true to enable HTTPS (e.g. GitHub Pages)
  • 键入 chmod +x gui.sh 增加 shellScript 权限
  • 运行脚本,生成静态文件目录
 ./gui.sh or source gui.sh or sh gui.sh

Bugs 解决

Internal Server Error

通过 FTP 将所有图片复制到 VPS 下的 /var/www/ghost/content/images 目录。在准备上传文章的配图时,提示上传失败,原因说是内部服务器的错误。

当无法保存图片时,通常可以考虑一下问题是否出在了文件夹的权限方面。众所周知,应该使用特定的用户来访问和修改博客的内容。

sudo chown -R <ghostuser>:<ghostuser> ./content

就在本人认为问题已经得到解决的时候,又出现了如下的异常:

$ ghost start
+ sudo systemctl is-active ghost_www-zairesinatra-com
✔ Checking system Node.js version - found v16.14.2
✔ Ensuring user is not logged in as ghost user
✔ Checking if logged in user is directory owner
✔ Checking current folder permissions
+ sudo systemctl is-active ghost_www-zairesinatra-com
✔ Validating config
✔ Checking folder permissions
✔ Checking file permissions
✔ Checking memory availability
✔ Checking binary dependencies
✔ Checking systemd unit file
✔ Checking systemd node version - found v16.14.2
✖ Starting Ghost: www-zairesinatra-com
A SystemError occurred.

Message: Systemd process manager has not been set up or is corrupted.
Help: Run ghost setup linux-user systemd and try again.

Debug Information:
    OS: Ubuntu, v18.04.4 LTS
    Node Version: v16.14.2
    Ghost Version: 4.44.0
    Ghost-CLI Version: 1.19.3
    Environment: production
    Command: 'ghost start'

Try running ghost doctor to check your system for known issues.

You can always refer to https://ghost.org/docs/ghost-cli/ for troubleshooting.

欲通过 ghost setup 重设配置,但出现了跳过部分配置的情况。

$ ghost setup linux-user systemd
Systemd service has already been set up. Skipping Systemd setup
ℹ Setting up Systemd [skipped]

官方文档表示某些输出可能不会存在日志文件中,可尝试 ghost run 命令。

$ ghost run
INFO Ghost is running in production...
...
Sharp wasn't installed

在 Github Issues 上查到与 Sharp 相关的问题 => 点此

这是更换了文件夹内容后出现的状况,且开始并未表示 Sharp 存在问题,根据此处的理解,尝试重新进行设置,可成功的完成修复。

"Directory was linked using NFS so ghost-cli couldn't change its permissions or owner, therefore it kind of silently failed where it did."

$ id -u ghost
$ stat /var/www/<ghost-blog>
$ ghost setup # or ghost setup systemd

Cascading problems caused by version compatibility

Ghost cannot be installed normally in some specific Node version environments, so nvm is usually used to install multiple Node versions.

Since there are no precompiled NodeJS binaries for versions prior to 15.x for Apple's new M1 chip (arm64 architecture). I encountered some problems when using nvm: when using nvm install v14.15.4 to install Node, the compilation was successful, but the installation failed.

# 为下载预编译的 x64 二进制文件 => 将 shell 的体系结构从 arm64 更改为 x86
$ arch -x86_64 zsh
# 输出机器的体系结构 => 结果有 i386、i486、mips、alpha
$ arch
i386
# 使用 nvm 安装节点
$ nvm install v14.17.1
# 检查架构是否正确
node -p process.arch
x86

多提一句,体系结构的粘性是从 Rosetta 在 PowerPC 到 Intel 过渡中的工作方式的一种变化,在 macOS Big Sur 中,如果可以最大程度地提高兼容性,子进程将更喜欢父进程的架构。因此,例如启动 x86_64 sh 将导致来自该 shell 的 python 调用也是 x86_64。

kex_exchange_identification

在使用 doctl compute ssh... 访问 Droplet 时出现 port 22 直接关闭的情况。

$ doctl compute ssh ghostonubuntu2204-digitalocean --ssh-key-path ~/.ssh/digitalocean_id_rsa
kex_exchange_identification: Connection closed by remote host
Connection closed by ??? port 22
Error: exit status 255

使用 ssh -v user@ip Verbose Mode 进行 debug 如下。

$ ssh -v root@???
OpenSSH_9.0p1, LibreSSL 3.3.6
debug1: Reading configuration data ~/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
...
debug1: Local version string SSH-2.0-OpenSSH_9.0
kex_exchange_identification: Connection closed by remote host
Connection closed by ??? port 22

Ubuntu 22.04 中出现 "Connection refused by port 22" 的常见原因:

  • 没有安装 OpenSSH 的包
  • SSH 服务未激活
  • 错误的端口连接
  • 防火墙的规则阻止了连接请求
  • 开启了全局模式的代理
  • 文件 /etc/ssh/sshd_config 中 MaxStartups 和 MaxSessions 的限制
# Check the OpenSSH installation
$ sudo apt list --installed | grep openssh-server
# If the OpenSSH package is not installed
$ sudo apt install openssh-server -y
# View the status of the SSH server
$ sudo systemctl status ssh
# To activate the service,
$ sudo systemctl start ssh
# Check sshd port
$ sudo netstat -ltnp | grep sshd
# Specify port for ssh connection
$ ssh -p [port_number] [username]@[ip_address]

SSH is a popular and effective way to connect to remote Linux machines in the command line. The ssh daemon (sshd) reads the configuration file located in /etc/ssh/sshd_config.

The MaxStartups setting specifies the maximum number of concurrent unauthenticated connections to the SSH daemon. Additional connections are dropped until authentication succeeds or the LoginGraceTime expires for a connection.

MaxStartups 中的 start:rate:full 表示当连接数达到 start 时,就会开始有 rate 的概率拒绝连接;当连接数达到 full 时,后续的连接将被全部拒绝。

The MaxSessiosn setting defines the maximum number of open sessions per connection.

要禁用 shell 的多路复用时,可以将其值设置为 1。将 MaxSessiosn 设置为 0 时会禁用所有的会话,包括 login、shell 和 subsystem。

SSH acceleration and optimization

A 记录解析域名到 IP 地址,而 PTR 记录解析 IP 地址到域名。

A PTR (pointer) record maps an IP address to the domain name. It's often called a "reverse DNS entry" because it converts an IP address to a name.

服务器会先根据 Client IP 进行 DNS PTR 反向查询 Domain 或 Hostname,然后根据查询出的客户端域名或主机名进行 DNS 正向 A 记录查询,并验证是否与原始 IP 地址一致,以此来防止客户端的欺骗。

由于常规使用的都是没有 PTR 记录的动态 IP,所以这种验证并没有太大的作用。

GSSAPI 全称是 Generic Security Services API,在这里主要是作为一种 OpenSSH Authentication 的方式。

OpenSSH Authentication Methods:

  • Password authentication: Client will ask you to enter a password, will encrypt it and use it to authenticate itself to a server.
  • Public key authentication: Each client uses a key pair to authenticate itself to a server. Server should find the key in the list of allowed keys.
  • Host based authentication: This method is similar to public key authentication, but client should not only use correct key, but also must connect from correct host.
  • Keyboard authentication: Server will use client to present zero or more prompts to client PC operator and request answers from operator.
  • Challenge Response Authentication: Used to configure keyboard authentication. You should use specific backend send the challenges and check the responses.
  • GSSAPI Authentication: GSSAPI is a IETF standard for strong encrypted authentication. OpenSSH uses GSSAPI and kerberos 5 code to authenticate clients.

密码或者公钥的认证并不会阻止系统执行 GSSAPI Authentication 的过程,那么连接时就难免在此处消耗一定的时间,造成 SSH 登录慢的体验。

综上,可将 UseDNSGSSAPIAuthentication 设置 no,并重启 ssh 服务。

The service command is a wrapper script that allows system administrators to start, stop, and check the status of services without worrying too much about the actual init system being used. Prior to systemd's introduction, it was a wrapper for /etc/init.d scripts and Upstart's initctl command, and now it is a wrapper for these two and systemctl as well. - askubuntu

The Secure Shell Daemon application (SSH daemon or sshd) is the daemon program for ssh. This program is an alternative to rlogin and rsh and provides encrypted communications between two untrusted hosts over an insecure network. The sshd is the daemon that listens for connections from clients on port 22.

# /etc/ssh/sshd_config
UseDNS no
GSSAPIAuthentication no
service sshd restart
systemctl restart sshd.service
# shorthand
sed -i -e 's/UseDNS yes/UseDNS no/g' -e 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/g' /etc/ssh/sshd_config && systemctl restart sshd.service

因服务器部署在海外地区,除开上述的配置外,还可以采取代理服务器的方法进行远程连接。OpenSSH ProxyJump 和 ProxyCommand 指令可以让 SSH 通过 Jump Host 连接到 Remote Server。Jump Host 也称作 Jump Server 或 Bastion Host。

A Bastion Host or a Jump Server is an intermediary device that an SSH client connects to first before accessing the target remote Linux system. An SSH Jump server acts as a gateway to your IT resources, thus reducing the attack surface.

# Dynamic jump host list
ssh -J username1@host1:port,username2@host2:port username3@host3:port
# Static jump host list
# ~/.ssh/config
Host vps1
  HostName vps1.example.org
  User ...
  PreferredAuthentications password
Host ultimateVps
  HostName ultimateVps.example.org
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/..._id_rsa
  ProxyJump vps1

通常情况下,国内与海外服务器的网络路由可能会因为一个结点的拥堵而导致网络质量的降级。在长距离的跨国网络中,众多路由节点都会存在有拥堵的风险,那么此时可以考虑在合适的位置添加一个额外的路由节点来改变原本的路由,绕过某些可能会造成拥堵的节点,那么就可以缩短链路的距离,改善网络的质量。

scp -vrCo 'ProxyJump root@vps1' root@ultimateVps:/.../... /Users/...

路径后缀错误所导致的图显失败

因默认自动编译生成的是动态网站,而实际需编译成静态网站时,应当修改默认文件中的相关配置。将所有的 .hbs 文件中的格式选型代码进行指定删减。

{{#if feature_image}}
  <figure class="article-image">
    {{!-- This is a responsive image, it loads different sizes depending on device
    https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
    <img
      srcset="{{img_url feature_image size="xl"}} 2000w"
      sizes="(min-width: 1400px) 1400px, 92vw"
      src="{{img_url feature_image size="xl"}}"
      alt="{{title}}"
    />
  </figure>
{{/if}}

更新所致的数据假性丢失

根目录中存在一个叫 config.development.json 的配置文件,这个文件决定了启动的端口号以及所使用的数据库等内容。

Ghost 默认使用 sqlite3 数据库(我记得以前使用的是 MySQL?),那么数据消失的问题就应该查看环境中对数据库的配置是否出现了异常。

config.development.json 中 sqlite3 被指定为了 ghost-dev,故进行改正。

"database": {
  "client": "sqlite3",
  "connection": {
    "filename": "/Users/.../zs-ghost/content/data/ghost-local.db"
  }
}

若需要将 sqlite3 迁移到 MySQL,可参考如下配置。troubleshooting

"database": {
  "client": "mysql",
  "connection": {
    "host": "127.0.0.1",
    "user": "???",
    "password": "???",
    "database": "ghost-dev",
    "charset": "utf8"
  }
},

注意此处 host 不能设置为 localhost,否则会出现启动异常。

Ghost was able to start, but errored during boot with: connect ECONNREFUSED ::1:3306

结束

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!