跳到主要内容

部署与配置

在上一篇文章中,我们介绍了快速开始使用 Logto的基础内容。本文将更深入地探讨,在生产环境中部署 Logto 的最佳实践和详细配置步骤。

环境变量​

我们在演示(docker-compose.yml)中使用了生成的环境变量预设,你应该用自己的变量替换,并在多个 Logto 实例之间保持一致。

你可以直接设置环境变量,或将 .env 文件放在 Logto 项目根目录下。如果你在使用 Docker 进行测试,请查看镜像在 /etc/logto 生成的 .env 文件。

基本项​

  • DB_URL Logto 数据库的 Postgres DSN。
  • DATABASE_STATEMENT_TIMEOUT(v1.36.0+)PostgreSQL 的 statement_timeout,单位为毫秒。使用数字字符串(如 5000)或 DISABLE_TIMEOUT(适用于 PgBouncer/RDS Proxy)。详见配置。
  • PORT Logto 监听的端口。默认 3001。
  • ENDPOINT 你可以为生产环境指定自定义域名的 URL(如 ENDPOINT=https://logto.domain.com)。这也会影响 OIDC 发行者 (Issuer) 标识符 的值。

启用管理控制台

  • ADMIN_PORT Logto 管理控制台监听的端口。默认 3002。
  • ADMIN_ENDPOINT 你可以为生产环境指定自定义域名的 URL(如 ADMIN_ENDPOINT=https://admin.domain.com)。这也会影响管理控制台重定向 URI 的值。

禁用管理控制台

  • ADMIN_DISABLE_LOCALHOST 设置为 1 或 true 可关闭管理控制台端口。如果未设置 ADMIN_ENDPOINT,将完全禁用管理控制台。

关于环境变量的更多详情,参见配置。

启用密钥保险库 (Secret Vault)

  • 若要使用 密钥保险库 (Secret Vault),你需要将 SECRET_VAULT_KEK 设置为你的密钥加密密钥(KEK)的 base64 编码字符串。此密钥用于加密密钥保险库中的数据加密密钥(DEK)。推荐使用 AES-256(32 字节)。示例:crypto.randomBytes(32).toString('base64')。

出站 HTTP 代理​

如果你的自托管 Logto 实例需要通过 HTTP 代理访问外部服务(如社交连接器 API 或验证码提供商),请启用环境代理支持并配置标准代理变量。

例如,在 Docker Compose 配置的 Logto 服务中添加如下环境变量:

services:
logto:
image: ghcr.io/logto-io/logto:latest
environment:
NODE_USE_ENV_PROXY: '1'
HTTP_PROXY: http://proxy.example.com:3128
HTTPS_PROXY: http://proxy.example.com:3128
NO_PROXY: localhost,127.0.0.1,::1,postgres,.internal.example.com
  • NODE_USE_ENV_PROXY=1 启用环境代理支持。在 Node.js 22 上,需要 22.21.0 或更高版本。
  • HTTP_PROXY 指定 HTTP 请求的代理。
  • HTTPS_PROXY 指定 HTTPS 请求的代理。代理 URL 本身可以使用 HTTP 或 HTTPS。
  • NO_PROXY 是一个以逗号分隔的主机列表,这些主机将直接访问。请包含所有不应通过代理访问的内部 HTTP 端点。

注意,此代理配置可能不会对所有出站请求生效。

HTTPS​

你可以直接使用 Node.js 提供 HTTPS 服务,或在 Node.js 前面设置 HTTPS 代理 / 负载均衡器。详见启用 HTTPS。

反向代理​

如果你想在服务器上使用反向代理(如 Nginx 或 Apache),需要在代理转发设置中分别映射 3001 和 3002 端口。假设你使用 Nginx,Logto 认证 (Authentication) 端点运行在 3001 端口,Logto 管理控制台运行在 3002 端口,请在 nginx.conf 中添加如下配置:

为使 Logto 信任转发头部,请设置 TRUST_PROXY_HEADER=1。使用 $http_host 作为 Host 和 X-Forwarded-Host,以保留公共 URL 中的非标准端口。

server {
listen 443 ssl;
server_name <your_endpoint_url>; // 例如 auth.your-domain.com
...

location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_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_pass http://127.0.0.1:3001;
}

ssl_certificate <path-to-your-certificate-for-auth-endpoint>;
ssl_certificate_key <path-to-your-certificate-key-for-auth-endpoint>
...
}

然后为管理控制台添加类似配置:

server {
listen 443 ssl;
server_name <your_admin_endpoint_url>; // 例如 admin.your-domain.com
...

location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_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_pass http://127.0.0.1:3002;
}

ssl_certificate <path-to-your-certificate-for-admin-endpoint>;
ssl_certificate_key <path-to-your-certificate-key-for-admin-endpoint>
...
}

重载 Nginx 配置以应用最新更改:

nginx -s reload

一切就绪。打开浏览器访问 https://admin.your-domain.com,你应该能看到 Logto 欢迎页面。

容器化​

在生产环境中,你可以使用 Docker 对 Logto 进行容器化。你可以在项目根目录找到 Dockerfile。如果你想运行多个 Logto 实例,例如在 Kubernetes 集群中部署 Logto,则需要执行一些额外步骤。

数据库初始化​

为 Logto 准备一个 Postgres 数据库。强烈建议使用 Logto CLI 初始化数据库。

npm run cli db seed -- --swe

详见 Logto CLI。

离线或隔离环境安装:

如果你的部署环境无法访问 api.pwnedpasswords.com,请在 logto init 或 npm run cli db seed 命令后添加 --disable-admin-pwned-password-check,这样首次管理员注册时不会因 Have I Been Pwned 检查而卡住。详见离线或隔离环境的初始化。

共享连接器文件夹​

默认情况下,Logto 会在 core 文件夹根目录下创建一个 connectors 文件夹。官方 Docker 镜像已经在此文件夹中包含了官方连接器,因此如果你只使用官方连接器,无需共享该文件夹。

如果你需要使用镜像中未包含的连接器(如自定义连接器),建议在多个 Logto 实例之间共享该文件夹。将 packages/core/connectors 文件夹挂载到容器,并运行 npm run cli connector add -- --official 部署官方连接器,然后将自定义连接器添加到同一文件夹。挂载卷到该文件夹会隐藏镜像自带的连接器,因此需要重新添加官方连接器,这需要访问 npm registry。

以下是 Kubernetes 的最小示例 deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
name: logto
namespace: default
spec:
selector:
matchLabels:
app: logto
template:
metadata:
labels:
app: logto
spec:
volumes:
- name: connectors
emptyDir: {}
initContainers:
- image: ghcr.io/logto-io/logto
command:
- /bin/sh
args:
- '-c'
- 'npm run cli connector add -- --official'
name: init
volumeMounts:
- name: connectors
mountPath: /etc/logto/packages/core/connectors
containers:
- image: ghcr.io/logto-io/logto
name: logto
volumeMounts:
- name: connectors
mountPath: /etc/logto/packages/core/connectors

在此示例中,我们创建了一个空目录作为卷并挂载到容器。然后在初始化容器中运行 npm run cli connector add -- --official 下载连接器。最后,每个容器都将共享同一个包含官方连接器的 connectors 文件夹。

备注:

这是一个示例 yaml,要运行 Logto,你需要正确设置环境变量。

在生产环境中,你可以将 "empty dir" 卷替换为持久卷,并用你自己的方式完成 "init" 操作,你知道你在做什么!

数据库变更​

与连接器类似,数据库变更需要在单个实例中运行。你可以使用 job 来运行变更脚本。

当以非交互方式运行变更时,必须设置 CI=true 环境变量。

apiVersion: batch/v1
kind: Job
metadata:
name: alteration
spec:
template:
spec:
containers:
- name: alteration
image: ghcr.io/logto-io/logto
imagePullPolicy: Always
env:
- name: CI
value: 'true'
- name: DB_URL
value: postgresql://user:password@localhost:5432/logto
command:
- /bin/sh
args:
- '-c'
- 'npm run alteration deploy latest'
restartPolicy: Never

关于变更命令的详细信息,参见 数据库变更。