这是将 Strapi 项目部署到 DigitalOcean Droplet 的分步指南。或者,如果数据库相关要求和预算更适合您的使用案例,您也可以选择部署到 DigitalOcean 的平台即服务 (PaaS),即 App Platform。
本指南介绍如何在 DigitalOcean Droplet 上托管数据库。另一种选择是使用 DigitalOcean 托管数据库 将数据库作为服务在外部托管。
- 您已创建 带有本地 PostgreSQL 数据库的 Strapi 项目。
- 您已阅读 常规部署配置 部分。
- 您已创建 DigitalOcean 帐户。您可以使用 此推荐链接。
创建 Strapi 项目时,请勿使用 --quickstart
标志,因为快速启动安装使用 SQLite,而这对于远程托管来说并非理想选择。
创建“Droplet”
DigitalOcean 称虚拟专用服务器为 Droplet。创建一个新的 Droplet 来托管您的 Strapi 项目:
- 登录您的 DigitalOcean 帐户。
- 选择右上角附近的 Create 下拉菜单,然后选择 Droplets。
- 选择离用户位置最近的“区域”和“数据中心”。
- 从“OS”选项卡中选择 Ubuntu 22.04 (LTS) x64 作为镜像。
- 根据您的需求选择合适的 droplet 大小和定价计划。Strapi 需要 至少 2GB 的 RAM 来构建和部署管理界面。
- 选择 SSH 密钥。
- 在您计算机上的终端实例中,运行以下命令:
pbcopy < ~/.ssh/id_rsa.pub
。该命令将开发计算机上现有的 SSH 公钥复制到剪贴板。 - 返回 DigitalOcean 网站,将您的公钥 SSH 密钥粘贴到“新 SSH 密钥”字段中。命名此 SSH 密钥并单击“保存”**。
- (可选)根据需要选择其他选项,例如 IPv6。
- (可选)选择 主机名 或保留原样。
- 单击右下角的 创建 Droplet 按钮。
DigitalOcean 将创建您的 Droplet 并通过加载栏指示进度。完成后,继续设置生产服务器并安装 Node.js。
有关创建和使用 SSH 密钥的其他说明,请参阅 DigitalOcean 官方文档。
设置生产服务器并安装 Node.js
以下步骤将帮助您设置生产服务器和非 root 用户来管理服务器。
设置生产服务器
按照 DigitalOcean 官方文档使用 Ubuntu 22.04 进行初始 服务器设置。
安装和配置 Node.js 和 npm
现在服务器已设置完毕,使用个人软件包存档 (PPA) 安装 Node,如 官方 DigitalOcean 文档 中所述。
安装 Node(默认情况下也会安装 npm
)后,您将手动更改 npm
的默认目录。以下步骤基于官方 Node 文档中的 如何解决访问权限:
- 创建一个
.npm-global
目录,并通过运行以下命令为node_modules
设置此目录的路径:
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
- 运行以下命令创建(或修改)一个
~/.profile
文件:
sudo nano ~/.profile
- 将以下行粘贴到打开的
~/.profile
文件的前两行中:
# 设置 PATH,以便全局节点模块安装时不会出现权限问题
export PATH=~/.npm-global/bin:$PATH
然后按Ctrl+X
退出,y
保存,Enter
接受。
4. 通过运行以下命令更新系统变量:
source ~/.profile
您现在可以在服务器上安装和配置 Git 版本控制了。
在您的服务器上安装和配置 Git 版本控制
在初始开发期间和之后维护和更新 Strapi 应用程序的一种方便方法是使用 Git。为了使用 Git,您需要在您的 Droplet 上安装它。
Droplet 应该默认安装 Git。通过运行以下命令检查 Git 是否已安装:
git --version
如果终端返回 git version
后跟某个版本号(例如,git version 2.x.x
),则表示 Git 已安装,您可以继续 为您的项目安装数据库。
如果未安装 Git:
- 按照 DigitalOcean 文档 如何在 Ubuntu 22.04 上安装 Git 安装 Git。
- 按照 DigitalOcean 文档 中所述设置用户名和电子邮件,配置 Git。
为您的项目安装数据库
按照 DigitalOcean 文档 中的“第 4 步 - 创建新数据库”步骤,在 Ubuntu 22.04 上安装 PostgreSQL。完成后,将安装 PostgreSQL 并创建用户和数据库。
要使用 Strapi 连接到 PostgreSQL 数据库,数据库:
- 需要有密码,
- 或通过将空字符串(“'''”)声明为密码来明确说明没有密码。
要使用 Strapi 连接到 PostgreSQL 数据库:
- (可选) 如果您已从
postgres@
用户切换,请运行以下命令:
sudo -u postgres psql
[sudo] password for your-name: # 出现此身份验证提示
psql (14.8 (Ubuntu 14.8-0ubuntu0.22.04.1)) # 输入密码后的 shell 响应
输入“help”获取帮助。
- 运行以下命令更改您创建的用户并添加密码,将
your-name
和'your-password'
替换为您自己的值:
psql
# 在下面输入 SQL 命令(包括引号和分号)。
postgres=# ALTER USER your-name PASSWORD 'your-password';
ALTER ROLE # SQL 命令后的 shell 响应
# 然后使用 \q 命令退出,因为我们不想更改角色。
postgres=# \q
exit
- (可选) 如果您在首次设置 Strapi 时选择
PostgreSQL
作为初始数据库选择,则pg
包会自动安装在本地。如果您的 Strapi 项目使用 SQLite,请安装pg
依赖包。在您的开发机器上,在 Strapi 项目文件夹中运行以下命令:
npm install pg --save
记下数据库名称、用户名和密码以供日后使用。
为本地开发配置
- 您必须在本地安装并设置
git
。 - 应该为您之前创建的 Strapi 项目初始化 Git。
- 将
config/database.js
的内容替换为以下内容:
module.exports = ({ env }) => ({
connection: {
client: 'postgres',
connection: {
host: env('DATABASE_HOST', '127.0.0.1'),
port: env.int('DATABASE_PORT', 5432),
database: env('DATABASE_NAME', 'strapidb'),
user: env('DATABASE_USERNAME', ''),
password: env('DATABASE_PASSWORD', ''),
ssl: env.bool('DATABASE_SSL', false) && {
rejectUnauthorized: env.bool('DATABASE_SSL_SELF', false),
},
},
debug: false,
},
})
- Push these changes to Github by running the following commands:
git add .
git commit -m "Configured production/database.json"
git push
从 GitHub 部署
现在,您将通过从 GitHub 克隆 Strapi 项目来将其部署到您的 Droplet。
- 从您的终端,以非 root 用户身份登录到您的 Droplet,运行以下命令,将“your-handle”和“your-project”替换为您的 GitHub 用户名和项目名称:
cd ~
git clone https://github.com/your-handle/your-project.git
- (可选)如果使用基于密码的身份验证而不是 SSH 密钥:
- 尝试克隆时,系统将提示您输入“your-handle”和密码。这实际上是一个 个人访问令牌 (PAT),因为密码已被 弃用。
- 为了解决稍后使用 webhook 时出现的 问题,请运行以下命令,将
your-handle
、your-pat
和your-project
替换为适当的值:
cd ~/your-project
git remote add origin https://your-handle:your-pat@github.com/your-handle/your-project.git
# 如果响应为“fatal: remote origin already exist.”,则运行:
git remote set-url origin https://your-handle:your-pat@github.com/your-handle/your-project.git
- 导航到项目的文件夹,即 Strapi 的根文件夹,并通过运行以下命令安装项目的 npm 包,将
your-project
替换为通过 GitHub 上的项目名称:
cd your-project
npm install
- 通过运行以下命令构建 Strapi 的管理面板:
NODE_ENV=production npm run build
- 由于 Strapi 默认使用端口 1337,您必须通过运行以下命令配置您的
ufw
防火墙以允许访问此端口以进行测试和安装:
cd ~
sudo ufw allow 1337/tcp
sudo ufw enable
按 y
回答 命令可能会破坏现有的 ssh 连接。继续操作 (y|n)?
消息。
您的 Strapi 项目现已安装在您的 DigitalOcean Droplet 上。在创建第一个用户之前,您必须安装并配置 Nginx 和 pm2、配置 ecosystem.config.js` 文件和环境变量 以及 设置 webhook。
安装和配置 Nginx 网络服务器
- 按照 DigitalOcean 官方文档 上的指南安装和配置 Nginx,并牢记以下特殊性:
- 您可以为 Strapi 项目添加域名或使用子域名。
- “步骤 5 - 设置服务器块”中对
your_domain
的引用应包含 TLD,(例如example.com
)。 - “步骤 5 - 设置服务器块”中的位置字段(指定为
try_files $uri $uri/ =404;
)必须替换为以下内容:
proxy_pass http://localhost:1337;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header 连接 'upgrade';
proxy_set_header 主机 $host;
proxy_cache_bypass $http_upgrade;
- Nginx 有一个名为
client_max_body_size
的 配置设置,它将阻止大于指定大小的文件上传。由于其默认值只有 1MB,因此需要进行调整。请注意,strapi 中间件已经负责解析最大 200MB 的文件大小的请求。
...
http {
...
client_max_body_size 200m; # 或 0 禁用
...
}
...
- 通过运行以下命令关闭对外部流量的端口:
cd ~
sudo ufw denied 1337
安装和配置 pm2
pm2 允许您保持 Strapi 项目处于活动状态并在不停机的情况下重新加载它。
确保您以非 root 用户身份登录并通过运行以下命令全局安装 pm2:
npm install pm2@latest -g
配置 ecosystem.config.js
和 .env
文件
ecosystem.config.js
管理 Strapi 连接到数据库所需的数据库连接变量。ecosystem.config.js
也被 pm2
用于在 Strapi 文件系统本身的文件发生任何更改时重新启动项目,例如当 GitHub 收到更新时。您可以在 官方 pm2 文档 中阅读有关 ecosystem.config.js
文件的更多信息。
- 使用以下命令创建
ecosystem.config.js
文件并打开它。我们将使用nano
编辑器:
cd ~
pm2 init
sudo nano ecosystem.config.js
- 将文件中的样板内容替换为以下内容:
module.exports = {
apps: [
{
name: 'strapi-app',
cwd: '/home/your-name/your-project', // 必须有绝对路径
script: 'npm',
args: 'start',
env: {
NODE_ENV: 'production',
},
},
],
}
- 转到
your-project
文件夹以创建并打开.env
文件:
cd ~/your-project
sudo nano .env
- 将 Strapi 应用程序的本地
.env
文件的内容复制到当前打开的文件中nano
。将数据库名称和凭据替换为在数据库设置期间指定的名称和凭据。
HOST=0.0.0.0
PORT=1337
APP_KEYS=your-app-keys # 自动生成
API_TOKEN_SALT=your-api-token-salt # 自动生成
ADMIN_JWT_SECRET=your-admin-jwt-secret # 自动生成
TRANSFER_TOKEN_SALT=your-transfer-token-salt # 自动生成
# 数据库
DATABASE_CLIENT=postgres
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5432
DATABASE_NAME=your-database-name # 在数据库设置期间指定
DATABASE_USERNAME=your-database-username # 在数据库设置期间指定
DATABASE_PASSWORD=your-database-password # 在数据库设置期间指定
DATABASE_SSL=false
JWT_SECRET=your-jwt-secret #自动生成
- 运行以下命令启动
pm2
:
cd ~
pm2 start Ecosystem.config.js
pm2
现已设置为使用 ecosystem.config.js
来管理更改后重新启动应用程序。这是推荐的最佳做法。
配置 .env
以在系统启动时启动 Strapi
以下步骤根据 DigitalOcean PM2 设置文档 修改而来:
- 生成启动脚本,通过运行以下命令启动 PM2:
$ cd ~
$ pm2 startup systemd
# Shell 输出
[PM2] 找到初始化系统:systemd
[PM2] 要设置启动脚本,请复制/粘贴以下命令:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u your-name --hp /home/your-name
- 复制上面生成的命令并粘贴到终端:
$ sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u your-name --hp /home/your-name
# Shell 输出
[PM2] 找到初始化系统:systemd
平台 systemd
# ...
[PM2] [v] 命令已成功执行。
+---------------------------------------+
[PM2] 重启时冻结进程列表:
$ pm2 save
[PM2] 删除初始化脚本:
$ pm2 unstartup systemd
- 保存新的 PM2 进程列表和环境:
pm2 save
# Shell 输出
[PM2] 保存当前进程列表...
[PM2] 已成功保存在 /home/your-name/.pm2/dump.pm2 中
您可以使用 sudo reboot
命令测试上述脚本是否在系统重启时有效。再次以非 root 用户身份登录并运行“pm2 list”和“systemctl status pm2-your-name”以验证一切正常。您还可以使用“pm2 logs strapi-app --lines 20”检查日志。
Strapi 生产服务器现在应该可以在 Nginx 设置期间 指定 的域中使用。登录屏幕可在同一域的“/admin”端点上使用。
在 DigitalOcean/GitHub 上设置 webhook
如果您的项目是在 GitHub 上设置的,则必须使用 webhook 在那里配置您的 Strapi 项目存储库。
有关 webhook 的更多信息,请参阅 GitHub 文档 和 DigitalOcean 文档。
- 转到 GitHub 上的“your-project”并按照 DigitalOcean 文章中的 步骤 1 设置 webhook。记下“your-webhook-secret”中输入的内容,以备后用。
- 在您的服务器上创建一个 webhook 脚本。以下命令创建一个名为“webhook.js”的新文件,该文件将包含 2 个变量:
cd ~
mkdir NodeWebhooks
cd NodeWebhooks
sudo nano webhook.js
- 在打开的“nano”编辑器中,粘贴以下脚本,确保更新文件顶部的“secret”和“repo”变量的值。然后保存并退出。js
var secret = 'your-webhook-secret' // created in GitHub earlier var repo = '~/your-project' const http = require('node:http') const crypto = require('node:crypto') const exec = require('node:child_process').exec const PM2_CMD = 'cd ~ && pm2 startOrRestart ecosystem.config.js' http .createServer((req, res) => { req.on('data', (chunk) => { const sig = `sha1=${ crypto .createHmac('sha1', secret) .update(chunk.toString()) .digest('hex')}` if (req.headers['x-hub-signature'] === sig) { exec(`cd ${repo} && git pull && NODE_ENV=production npm run build && ${PM2_CMD}`, (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`) return } console.log(`stdout: ${stdout}`) console.log(`stderr: ${stderr}`) }) } }) res.end() }) .listen(8080)
上面的脚本声明了一个名为PM2_CMD
的变量,该变量在从 GitHub 拉取后用于更新您的项目。脚本首先更改为主目录,然后将变量PM2_CMD
作为pm2 restart strapi
运行。
- 通过运行以下脚本允许端口与端口 8080 的外部 Web 流量进行通信:
sudo ufw allow 8080/tcp
sudo ufw enable
按 y
接受 Command may break already ssh connections. Proceed with operation (y|n)?
消息。
之前,您设置了 pm2
,以便在 Droplet 重新启动或启动时启动 your-project
的服务。现在,您将对 webhook.js
脚本执行相同操作。
- 将 webhook 安装为
systemd
服务。首先运行echo $PATH
,然后复制输出以供下一步使用。
echo $PATH
# Shell 输出
/home/your-name/.npm-global/bin:/home/your-name/bin:/home/your-name/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
- 创建
webhook.service
文件:
sudo nano /etc/systemd/system/webhook.service
- 将以下配置详细信息粘贴到打开的
nano
编辑器中。确保将两个位置的your-name
替换为您的用户名。然后,将上面输出到 shell 的路径粘贴到your-path
的位置,然后保存并退出:
[Unit]
Description=Github webhook
After=network.target
[Service]
Environment=PATH=your-path
Type=simple
User=your-name
ExecStart=/usr/bin/node /home/your-name/NodeWebhooks/webhook.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
- 启用并启动新服务,使其在系统启动时启动:
sudo systemctl enable webhook.service
sudo systemctl start webhook
- 检查 webhook 的状态:
sudo systemctl status webhook
- (可选)按照 DigitalOcean 文档 中所示测试您的 webhook,但使用
node webhook.js
命令,因为nodejs
已弃用。有时即使身份验证失败,GitHub 也会显示最近成功交付。最可靠的方法是将代码更改推送到 GitHub 存储库,然后再次运行sudo systemctl status webhook
以查看最新提交的 SHA 是否已注册。
后续步骤
- 要安装 SSL,您需要 安装并运行 Let's Encrypt 的 Certbot。
- 为 Ubuntu 22.04 设置 支持 HTTP/2 的 Nginx。
🥳 您的 Strapi 项目已使用 Ubuntu 22.04 安装在 DigitalOcean Droplet 上。