Caddy Proxying

了解如何使用像 Caddy 这样的代理应用程序来保护您的 Strapi 应用程序。

由于 Strapi 不直接处理 SSL,并且在“边缘”网络上托管 Node.js 服务并不是一个安全的解决方案,因此建议您使用某种代理应用程序,例如 Nginx、Apache、HAProxy、Traefik 或其他。本指南包含一些 Caddy 的示例配置,当然这些配置可能不适合所有环境,您可能需要调整它们以满足您的需求。

Caddy 有一些非常易于使用的选项,与 Let's encrypt 和自动 SSL 证书颁发/更新有关,虽然它肯定是“较新的” Web 服务器市场,但它正在迅速成为一个很棒的“非技术”用户代理应用程序。

Caddy 仍处于开发阶段,因此经常更新,本指南基于 Caddy v2.0.0。

配置

以下配置基于“Caddy 文件”类型,这是 Caddy 将用于运行 Web 服务器的单个文件配置。本指南不会介绍其他多种选项,例如 Caddy REST API,您应该查看 Caddy 文档 以获取有关替代方案的更多信息。您还可以访问 Caddy 社区 与其他人讨论配置问题。

Strapi 服务器

为了充分利用代理 Strapi 应用程序,应配置 Strapi 以使其了解上游代理。与以下配置一样,有 3 个匹配的示例。可以在 服务器配置管理配置 文档中找到更多信息。

这些示例使用默认 API 前缀 /api。无需直接修改 Nginx 配置即可更改此前缀(请参阅 API 前缀 文档)。

如果在 ./config/admin.js./config/server.js 文件中更改了 url 键,则需要使用 yarn buildnpm run build 重建管理面板。

子域名 Strapi 配置

  • 示例域名:api.example.com
  • 示例管理员:api.example.com/admin
  • 示例 API:api.example.com/api
  • 示例上传文件(本地提供商):api.example.com/uploads
js
path: ./config/server.js
js
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
js
path: ./config/server.js
js
module.exports = ({ env }) => ({
  host: env('HOST', '0.0.0.0'),
  port: env.int('PORT', 1337),
  url: 'https://example.com/test',
})

Caddy file

Caddyfile 是一种方便人类使用的 Caddy 配置格式。它是大多数人使用 Caddy 的首选方式,因为它易于编写、易于理解,并且对于大多数用例来说具有足够的表现力。

在以下示例中,您将需要替换您的域,如果您希望使用 SSL,则需要调整这些 Caddy 文件配置以满足您的需求,本指南不涵盖 SSL,您应该查看 Caddy 文档。

以下是 2 个示例 Caddy 配置:

  • 基于子域,例如 api.example.com
  • 基于子文件夹,API 和 Admin 都位于同一子文件夹中(例如 example.com/test/apiexample.com/test/admin
不支持子文件夹拆分

Strapi 不支持也不推荐使用子文件夹拆分(例如:https://example.com/dashboardhttps://example.com/api)。建议您使用子域名(例如:https://api.example.com)或子文件夹统一(例如:https://example.com/strapi/dashboardhttps://example.com/strapi/api)。

子域

此配置使用仅专用于 Strapi 的子域。它将绑定到端口 80 HTTP,并将所有请求(API 和管理员)代理到在指定地址上本地运行的 Strapi 服务器。如果您已正确配置 Caddy 来处理自动 SSL,则可以删除“http://”,Caddy 将自动将所有 HTTP 转换为 HTTPS 流量。

  • Example domain: api.example.com
  • Example admin panel: api.example.com/admin
  • Example API: api.example.com/api
  • Example uploaded Files (local provider): api.example.com/uploads
/etc/caddy/Caddyfile
bash
http://api.example.com {
  reverse_proxy 127.0.0.1:1337
}

子文件夹统一

此配置使用仅专用于 Strapi 的子文件夹。它将绑定到端口 80 HTTP 并像普通 Web 服务器一样在 /var/www 上托管前端文件,但代理 example.com/test 子路径上的所有 Strapi 请求。

此示例配置不专注于前端托管,应根据您的前端软件要求进行调整。

  • 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
/etc/caddy/Caddyfile
sh
http://example.com {
  root * /var/www
  file_server
  route /test* {
    uri strip_prefix /test
    reverse_proxy 127.0.0.1:1337
  }
}

将登录页面重定向到管理面板

如果您不希望将默认登录页面安装在 / 上,您可以使用下面的示例代码创建自定义中间件,以自动重定向到您的管理面板。

此示例配置要求管理面板可在 /admin 上访问。如果您使用上述配置之一将其更改为 /dashboard,您还需要调整此示例配置。

./config/middlewares.js
js
module.exports = ({ env }) => [
  // ...
  { resolve: '../src/middlewares/admin-redirect' },
]
./src/middlewares/admin-redirect.js
js
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)
}