Nginx Proxying

了解如何使用 Nginx 等代理应用程序来保护您的 Strapi 应用程序。

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

配置

以下配置基于 Nginx 虚拟主机,这意味着您为每个域创建配置,以允许在同一端口(例如 80(HTTP)或 443(HTTPS))上为多个域提供服务。它还使用中央上游文件来存储别名,以便在集群多个 Strapi 部署的情况下更轻松地进行管理、负载平衡和故障转移。

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
./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
./config/server.js
js
module.exports = ({ env }) => ({
  host: env('HOST', '0.0.0.0'),
  port: env.int('PORT', 1337),
  url: 'https://example.com/test',
})

Nginx Upstream

上游块用于将别名(例如“strapi”)映射到特定 URL(例如“localhost:1337”)。虽然在每个虚拟主机文件中定义这些会很有用,但如果您有多个虚拟主机文件,Nginx 目前不支持在虚拟主机中加载这些文件。相反,请在“conf.d”目录中配置这些文件,因为它在任何虚拟主机文件之前加载。

在以下配置中,“localhost:1337”映射到 Nginx 别名“strapi”:

/etc/nginx/conf.d/upstream.conf
sh
# Strapi server
upstream strapi {
    server 127.0.0.1:1337;
}

Nginx Virtual Host

虚拟主机文件用于存储特定应用、服务或代理服务的配置。对于 Strapi 的使用,此虚拟主机文件将处理 HTTPS 连接并将其代理到服务器上本地运行的 Strapi。此配置还使用 301 重定向将所有 HTTP 请求重定向到 HTTP。

在以下示例中,您需要替换您的域名,同样,您的 SSL 证书路径也需要根据您放置它们的位置进行更改,或者如果您使用 Let's Encrypt,则需要根据脚本放置它们的位置进行更改。还请注意,虽然以下路径显示“sites-available”,但您需要将文件符号链接到“sites-enabled”,以便 Nginx 启用配置。

以下是 2 个 Nginx 配置示例:

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

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

Subdomain

此配置使用仅专用于 Strapi 的子域。它将正常的 HTTP 流量重定向到 SSL,并将所有请求(API 和管理员)代理到在上面配置的上游别名上运行的 Strapi 服务器。

  • 示例域:api.example.com
  • 示例管理面板:api.example.com/admin
  • 示例 API:api.example.com/api
  • 示例上传文件(本地提供商):api.example.com/uploads
/etc/nginx/sites-available/strapi.conf
sh
server {
    # Listen HTTP
    listen 80;
    server_name api.example.com;

    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

server {
    # Listen HTTPS
    listen 443 ssl;
    server_name api.example.com;

    # SSL config
    ssl_certificate /path/to/your/certificate/file;
    ssl_certificate_key /path/to/your/certificate/key;

    # Proxy Config
    location / {
        proxy_pass http://strapi;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass_request_headers on;
    }
}

Subfolder unified

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

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

  • Example domain: example.com/test
  • Example admin: example.com/test/admin
  • Example API: example.com/test/api
  • Example uploaded files (local provider): example.com/test/uploads
/etc/nginx/sites-available/strapi.conf
sh
server {
    # Listen HTTP
    listen 80;
    server_name example.com;

    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

server {
    # Listen HTTPS
    listen 443 ssl;
    server_name example.com;

    # SSL config
    ssl_certificate /path/to/your/certificate/file;
    ssl_certificate_key /path/to/your/certificate/key;

    # Static Root
    location / {
        root /var/www/html;
    }

    # Strapi API and Admin
    location /test/ {
        rewrite ^/test/?(.*)$ /$1 break;
        proxy_pass http://strapi;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass_request_headers on;
    }
}

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

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

此示例配置要求管理面板可在 /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)
}