由于 Strapi 不直接处理 SSL,并且在“边缘”网络上托管 Node.js 服务并不是一个安全的解决方案,因此建议您使用某种代理应用程序,例如 Nginx、Apache、HAProxy、Traefik 或其他应用程序。以下文档提供了 HAProxy 的一些示例配置,当然这些配置可能并不适合所有环境,您可能需要调整它们以满足您的需求。
配置
以下示例充当“SSL 终止”代理,这意味着 HAProxy 仅接受 SSL 上的请求并代理到其他后端服务,例如 Strapi 或其他 Web 服务器。HAProxy 无法提供静态内容,因此它通常用于在故障转移或负载平衡情况下处理多服务器部署。以下示例基于同一服务器上存在的所有内容,但可以轻松调整以适应多服务器部署。
Strapi 服务器
为了充分利用代理 Strapi 应用程序,应配置 Strapi 以使其了解上游代理。与以下配置一样,有 3 个匹配的示例。可以在 服务器配置 和 管理配置 文档中找到更多信息。
这些示例使用默认 API 前缀 /api
。无需直接修改 Nginx 配置即可更改此前缀(请参阅 API 前缀 文档)。
如果在 ./config/admin.js
或 ./config/server.js
文件中更改了 url
键,则需要使用 yarn build
或 npm run build
重建管理面板。
子域名 Strapi 配置
- 示例域名:
api.example.com
- 示例管理员:
api.example.com/admin
- 示例 API:
api.example.com/api
- 示例上传文件(本地提供商):
api.example.com/uploads
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
url: 'https://api.example.com',
})
子文件夹统一 Strapi 配置
- 示例域:
example.com/test
- 示例管理员:
example.com/test/admin
- 示例 API:
example.com/test/api
- 示例上传文件(本地提供商):
example.com/test/uploads
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
url: 'https://example.com/test',
})
HAProxy
以下示例要么将所有请求直接代理到 Strapi,要么在 Strapi 和其他后端 Web 服务器(如 Nginx、Apache 等)之间拆分请求。
以下是 2 个示例 HAProxy 配置:
- 基于子域,例如
api.example.com
- 基于子文件夹,API 和 Admin 都位于同一子文件夹中,例如
example.com/test/api
和example.com/test/admin
Strapi 不支持也不推荐使用子文件夹拆分(例如:https://example.com/dashboard
和 https://example.com/api
)。建议您使用子域名(例如:https://api.example.com
)或子文件夹统一(例如:https://example.com/strapi/dashboard
和 https://example.com/strapi/api
)。
::card{type=tip} HAProxy SSL 支持
如果您不熟悉 HAProxy 并且在 bind 指令上使用 SSL 证书,则应将您的 SSL 证书、密钥和任何 CA 文件合并到单个 .pem
包中,并在 bind 指令中使用其路径。有关更多信息,请参阅 HAProxy 的 bind 文档。大多数 Let's Encrypt 客户端不会生成这样的文件,因此您可能需要自定义“发行后”脚本来为您执行此操作。
::
Subdomain
此配置使用仅专用于 Strapi 的子域。它将正常的 HTTP 流量重定向到 SSL,并将所有请求(API 和管理员)代理到服务器上运行的 Strapi 服务器。
- 示例域:
api.example.com
- 示例管理面板:
api.example.com/admin
- 示例 API:
api.example.com/api
- 示例上传文件(本地提供商):
api.example.com/uploads
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA3$
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
# 此行以上的所有内容均为 HAProxy 默认值
frontend api.example.com
bind *:80
bind *:443 ssl crt /path/to/your/cert+key+ca.pem
http-request redirect scheme https unless { ssl_fc }
default_backend strapi-backend
backend strapi-backend
server local 127.0.0.1:1337
子文件夹统一
此配置使用专用于 Strapi 的子文件夹。它将正常的 HTTP 流量重定向到 SSL,并将前端代理到 localhost:8080
,但将 example.com/test
子路径上的所有 Strapi 请求代理到本地运行的 Strapi 应用程序。
HAProxy 无法提供静态内容,以下示例将前端流量代理到在本地主机端口 8080 上运行的其他 Web 服务器。
- Example domain:
example.com/test
- Example admin panel:
example.com/test/admin
- Example API:
example.com/test/api
- Example uploaded Files (local provider):
example.com/test/uploads
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
# 默认 SSL 材料位置
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA3$
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
# 此行以上的所有内容均为 HAProxy 默认值
frontend example.com
bind *:80
bind *:443 ssl crt /path/to/your/cert+key+ca.pem
http-request redirect scheme https unless { ssl_fc }
acl test path_beg /test
use_backend strapi-backend if test
default_backend default-backend
backend default-backend
# HAProxy 无法自行提供静态内容
# 此示例正在将流量中继到其他后端 Web 服务器
server somewebserver 127.0.0.1:8080
backend strapi-backend
http-request set-path "%[path,regsub(^/test/?,/)]"
server local 127.0.0.1:1337
将登录页面重定向到管理面板
如果您不希望将默认登录页面安装在 /
上,您可以使用下面的示例代码创建自定义中间件,以自动重定向到您的管理面板。
此示例配置要求管理面板可在 /admin
上访问。如果您使用上述配置之一将其更改为 /dashboard
,您还需要调整此示例配置。
module.exports = ({ env }) => [
// ...
{ resolve: '../src/middlewares/admin-redirect' },
]
module.exports = (_config, { strapi }) => {
const redirects = ['/', '/index.html'].map(path => ({
method: 'GET',
path,
handler: ctx => ctx.redirect('/admin'),
config: { auth: false },
}))
strapi.server.routes(redirects)
}