Dify中的nginx服务

本文使用Dify v1.5.0版本,主要介绍了Dify中的nginx服务。涉及的配置文件包括.envdocker-compose.yamldefault.conf.templatedocker-entrypoint.shhttps.conf.templatenginx.conf.templateproxy.conf.template等。

一.配置文件引用关系解析

这些配置文件共同构建了一个基于Docker的部署环境,主要围绕Nginx反向代理的配置进行工作。

1.环境变量作为核心

  • docker/.env文件定义了所有服务使用的环境变量

  • 这些变量被注入到docker-compose和Nginx的各个配置模板中

2.Nginx配置模板系统

  • 所有*.template文件都是模板,在容器启动时被处理

  • 模板中的${变量名}会被实际环境变量替换

3.入口脚本处理流程

docker-entrypoint.sh是关键连接点,如下所示:

  • 检查是否启用HTTPS(NGINX_HTTPS_ENABLED

  • 根据配置决定使用哪些证书路径

  • 处理Let’s Encrypt证书挑战配置

  • 使用envsubst命令将环境变量注入到所有模板中

4.配置文件层次

  • nginx.conf.template → 主配置文件

  • default.conf.template → 站点配置,包含代理规则

  • proxy.conf.template → 通过include proxy.conf被引入

  • https.conf.template → 当HTTPS启用时,内容被注入到默认配置中

5.反向代理功能

  • default.conf.template定义了路由规则,将不同路径的请求代理到对应的后端服务

  • 例如:/apiapi:5001/web:3000

这种模板化配置方式非常灵活,使得可以通过修改环境变量来配置整个系统,而不需要直接编辑配置文件。

二.nginx服务

该配置定义了 Nginx 反向代理服务,用于将请求转发给 API 和 Web 服务。

1.基本配置

  • 镜像: 使用最新版 nginx:latest 官方镜像

  • 重启策略always – 容器异常退出时自动重启

2.挂载卷

(1)配置文件模板

  • nginx.conf.template: Nginx 主配置文件模板

  • proxy.conf.template: 代理设置模板

  • https.conf.template: HTTPS 设置模板

  • conf.d: 额外配置目录

(2)入口脚本

docker-entrypoint.sh是容器启动时执行的脚本,即该命令是设置 Nginx 容器的入口点(entrypoint),执行一系列操作来准备和启动容器。如下所示:

entrypoint: [ 'sh''-c'"cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ]

命令执行步骤,如下所示:

  • 使用 sh -c 运行一个 shell 命令序列

  • cp /docker-entrypoint-mount.sh /docker-entrypoint.sh – 将挂载的入口脚本复制到标准位置

  • sed -i 's/\r$$//' /docker-entrypoint.sh – 移除文件中可能存在的 Windows 风格的回车符(CR),解决跨平台文件格式问题

  • chmod +x /docker-entrypoint.sh – 给脚本添加执行权限

  • /docker-entrypoint.sh – 最后执行处理好的入口点脚本

这种处理方式确保了无论脚本最初是在 Windows 还是 Linux 环境下创建的,都能在容器中正确执行,避免了因文件格式和权限问题导致的容器启动失败。

(3)SSL/证书目录:

  • ./nginx/ssl: 传统证书存放位置

  • ./volumes/certbot/*: Let’s Encrypt 证书相关目录

3.环境变量

(1)服务器配置

  • NGINX_SERVER_NAME: 服务器名称,默认为 _

  • NGINX_PORT: HTTP 端口,默认 8

(2)HTTPS 设置

  • NGINX_HTTPS_ENABLED: 是否启用 HTTPS,默认 false

  • NGINX_SSL_PORT: HTTPS 端口,默认 443

  • NGINX_SSL_CERT_FILENAME: 证书文件名,默认 dify.crt

  • NGINX_SSL_CERT_KEY_FILENAME: 密钥文件名,默认 dify.key

  • NGINX_SSL_PROTOCOLS: 支持的 SSL 协议,默认 TLSv1.1 TLSv1.2 TLSv1.3

(3)性能设置

  • NGINX_WORKER_PROCESSES: 工作进程数,默认 auto

  • NGINX_CLIENT_MAX_BODY_SIZE: 客户端请求体大小限制,默认 15M

  • NGINX_KEEPALIVE_TIMEOUT: 保持连接超时时间,默认 65

  • NGINX_PROXY_READ_TIMEOUT: 代理读取超时,默认 3600s

  • NGINX_PROXY_SEND_TIMEOUT: 代理发送超时,默认 3600s

(4)Let’s Encrypt

  • NGINX_ENABLE_CERTBOT_CHALLENGE: 是否启用 Certbot 证书获取,默认 false

  • CERTBOT_DOMAIN: 证书申请域名

4.服务依赖

  • 依赖于 api 和 web 服务,确保这些服务先启动

5.端口映射

  • HTTP: ${EXPOSE_NGINX_PORT:-80}:${NGINX_PORT:-80}

  • HTTPS: ${EXPOSE_NGINX_SSL_PORT:-443}:${NGINX_SSL_PORT:-443}

6.使用说明

(1)若要启用 HTTPS,需设置 NGINX_HTTPS_ENABLED=true 并提供证书

(2)证书可手动放入 ./nginx/ssl 目录或使用 Certbot 容器自动申请

(3)容器入口脚本会处理配置文件模板并根据环境变量进行替换

三..env中的Nginx环境变量

环境变量 示例值 解释
NGINX_SERVER_NAME
_
Nginx 中 server_name 指令的取值。_ 表示将所有未显式匹配的域名都路由到该虚拟主机。
NGINX_HTTPS_ENABLED
FALSE
是否启用 HTTPS。设为 true 时,80 端口通常只做到 443 的重定向,并要求同时提供有效的证书与私钥。
NGINX_PORT
80
当 NGINX_HTTPS_ENABLED=false 时,Nginx 监听的 HTTP 端口。
NGINX_SSL_PORT
443
当 NGINX_HTTPS_ENABLED=true 时,Nginx 监听的 HTTPS 端口。
NGINX_SSL_CERT_FILENAME
dify.crt
TLS 证书文件名(放在 ./nginx/ssl/ 目录下)。仅在启用 HTTPS 时读取。
NGINX_SSL_CERT_KEY_FILENAME
dify.key
与证书配套的私钥文件名(同样位于 ./nginx/ssl/)。
NGINX_SSL_PROTOCOLS
TLSv1.1 TLSv1.2 TLSv1.3
允许的 TLS 协议版本,映射到 Nginx 的 ssl_protocols 指令。
NGINX_WORKER_PROCESSES
auto
Nginx 工作进程数。auto 让 Nginx 根据 CPU 核心数自动决定。
NGINX_CLIENT_MAX_BODY_SIZE
15M
允许客户端上传的单个请求体最大尺寸,对应 client_max_body_size。
NGINX_KEEPALIVE_TIMEOUT
65
Keep-alive 连接在空闲多少秒后关闭,节省资源。
NGINX_PROXY_READ_TIMEOUT
3600s
代理后端在多长时间内未返回数据就触发读超时(proxy_read_timeout)。常在处理长轮询 / 流式接口时调大。
NGINX_PROXY_SEND_TIMEOUT
3600s
向后端发送请求时如果在该时间内未能写完数据,则触发写超时(proxy_send_timeout)。
NGINX_ENABLE_CERTBOT_CHALLENGE
FALSE
设为 true 时,自动放行 /.well-known/acme-challenge/ 路径,方便 Certbot 通过 HTTP-01 方式续签证书。

四.default.conf.template

这是一个Nginx配置模板文件,用于Docker环境中的反向代理设置。

1.基本设置

  • 文件首行提醒用户不要直接编辑此文件,而是通过修改.env环境变量来配置Nginx

  • 监听端口和服务器名称由环境变量${NGINX_PORT}${NGINX_SERVER_NAME}决定

2.路由配置

该配置文件定义了多个路由规则,将不同路径的请求转发到不同的后端服务:

(1)API服务路由

  • /console/api → http://api:5001

  • /api → http://api:5001

  • /v1 → http://api:5001

  • /files → http://api:5001

(2)Web服务路由

  • /explore → http://web:3000

  • / (根路径) → http://web:3000

(3)插件服务路由

  • /e/ → http://plugin_daemon:5002,并设置了额外头部Dify-Hook-Url

3.通用配置

每个location块中的include proxy.conf引用了另一个文件中的通用代理设置。

4.扩展配置

  • ${ACME_CHALLENGE_LOCATION}是ACME挑战位置的占位符,用于SSL证书验证(如Let’s Encrypt)

  • ${HTTPS_CONFIG}是HTTPS配置的占位符,定义在https.conf.template文件中

这种配置典型地用于微服务架构,将Nginx作为前端网关,根据URL路径将请求分发到不同的后端服务。

五.proxy.conf.template

1.proxy.conf.template解析

这是一个Nginx代理配置模板文件,主要用于设置Nginx作为反向代理时的基本参数:

  • 文件特性:这是一个模板文件,通过环境变量动态配置某些参数

  • 不应直接编辑:应通过修改.env文件中的相关变量来更改配置

这些设置对于确保Nginx正确代理请求、保持客户端信息完整性以及控制连接行为非常重要。

配置
解释
proxy_set_header Host $host;
将原始请求的主机名传递给后端服务器
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
保留客户端原始IP地址
proxy_set_header X-Forwarded-Proto $scheme;
传递原始请求协议(http/https)
proxy_set_header X-Forwarded-Port $server_port;
传递原始请求的端口号
proxy_http_version 1.1;
使用HTTP 1.1协议
proxy_set_header Connection "";
清空Connection头,启用长连接
proxy_buffering off;
关闭代理缓冲,响应直接发送给客户端
proxy_read_timeout ${NGINX_PROXY_READ_TIMEOUT};
设置读取超时时间(从环境变量)
proxy_send_timeout ${NGINX_PROXY_SEND_TIMEOUT};
设置发送超时时间(从环境变量)

在 NGINX 配置中,$开头的变量通常是 NGINX 内置变量,直接由 NGINX 根据请求或服务器状态生成;${}语法表示的变量通常是外部环境变量,需要在运行环境中定义。NGINX 提供了一些预定义的变量,这些变量会根据请求或服务器的状态动态生成。如下所示:

  • $host:表示客户端请求的 Host 头字段的值。如果请求中没有 Host 头字段,NGINX 会使用服务器名称(server name)。

  • $proxy_add_x_forwarded_for:表示客户端的 IP 地址以及所有代理服务器的 IP 地址,通常用于追踪请求的来源。它会将客户端的 IP 地址添加到 X-Forwarded-For请求头中。

  • $scheme:表示请求使用的协议(如 http 或 https)。

  • $server_port:表示服务器监听的端口号。

2.Nginx常用内置变量

Nginx 的内置变量通常用于主配置文件 nginx.conf 以及各站点的虚拟主机配置文件(如 conf.d/*.conf 或 sites-enabled/*.conf)中,常见于 server 和 location 块中用于反向代理设置(如 proxy_passproxy_set_header)、日志记录格式(log_format)以及访问控制等指令中,帮助动态获取客户端请求信息、服务端状态或控制请求行为。

内置变量 解释
$host
客户端请求中的 Host 头部内容(若无则为服务器处理请求时的主机名)。
$server_name
当前虚拟主机配置中的 server_name 字段值。
$scheme
请求协议,http 或 https。
$remote_addr
客户端 IP 地址(若经过代理可结合 $http_x_forwarded_for 获取真实 IP)。
$remote_port
客户端源端口。
$server_addr
服务器本机 IP 地址(需开启 resolver 或使用 listen … proxy_protocol 时才准确)。
$server_port
接收到请求时服务器监听的端口号。
$request_method
请求方式,如 GET、POST、PUT 等。
$request_uri
完整原始请求 URI(包含查询字符串)。
$uri
去除查询字符串后的 URI,可能被内部重写(rewrite)修改。
$args
查询字符串部分(? 之后的内容),不含问号本身;若无则为空。
$document_root
当前请求对应的根目录(由 root 或 alias 指令决定)。
$body_bytes_sent
已发送给客户端的响应体字节数,不包括响应头。
$status
最终返回给客户端的 HTTP 状态码,如 200、404。
$request_time
处理当前请求花费的总时间(单位:秒,含小数)。
$upstream_addr
与后端 upstream 建立的最终连接地址(IP:端口)。仅在使用代理/反向代理时有值。
$upstream_status
upstream 返回的状态码,可包含多个值(若有重试)。
$upstream_response_time
upstream 处理请求的时间,支持多值。
$http_user_agent
客户端 User-Agent 头部内容。
$http_referer
客户端 Referer 头部内容(若无则为空)。

六.https.conf.template

这是一个NGINX的HTTPS配置模板文件,使用环境变量动态生成最终配置。按照第一行注释的建议,不应直接修改此文件,而应通过修改相关的环境变量来更改NGINX配置。

配置
解释
默认值
listen ${NGINX_SSL_PORT} ssl;
配置NGINX监听的SSL端口,端口号从环境变量获取
443
ssl_certificate ${SSL_CERTIFICATE_PATH};
指定SSL证书文件的路径
SSL_CERTIFICATE_PATH="/etc/ssl/${NGINX_SSL_CERT_FILENAME}"``NGINX_SSL_CERT_FILENAME=dify.crt
ssl_certificate_key ${SSL_CERTIFICATE_KEY_PATH};
指定SSL证书私钥文件的路径
SSL_CERTIFICATE_KEY_PATH="/etc/ssl/${NGINX_SSL_CERT_KEY_FILENAME}"``NGINX_SSL_CERT_KEY_FILENAME=dify.key
ssl_protocols ${NGINX_SSL_PROTOCOLS};
设置支持的SSL/TLS协议版本
NGINX_SSL_PROTOCOLS=TLSv1.1 TLSv1.2 TLSv1.3
ssl_prefer_server_ciphers on;
优先使用服务器定义的加密算法,提高安全性

ssl_session_cache shared:SSL:10m;
配置10MB的SSL会话共享缓存,提高性能

ssl_session_timeout 10m;
设置SSL会话缓存的有效期为10分钟

七.nginx.conf.template

文件顶部提醒用户不要直接编辑此文件,而是通过修改环境变量来调整Nginx配置,使配置更加灵活和可维护。

1.基础配置

(1)用户设置

user nginx – Nginx进程以nginx用户运行。

(2)工作进程

worker_processes ${NGINX_WORKER_PROCESSES} – 工作进程数从环境变量获取,默认为auto

(3)错误日志

error_log /var/log/nginx/error.log notice – 错误日志的位置和级别。

(4)PID文件

存储主进程ID的位置,即/var/run/nginx.pid

2.events块

events {
    worker_connections 1024;  # 每个工作进程最大并发连接数
}

3.http块

包含所有与HTTP服务相关的配置:

(1)MIME类型

/etc/nginx/mime.types文件加载。

(2)日志格式

定义了名为main的日志格式,记录客户端IP、请求时间、请求内容等。

(3)访问日志

位于/var/log/nginx/access.log

(4)性能优化

  • sendfile on – 启用高效文件传输

  • keepalive_timeout ${NGINX_KEEPALIVE_TIMEOUT} – 从环境变量获取连接保持时间,默认为65

(5)客户端设置

client_max_body_size ${NGINX_CLIENT_MAX_BODY_SIZE} – 从环境变量获取最大请求体大小,默认为15M

(6)包含额外配置

include /etc/nginx/conf.d/*.conf – 加载其它配置文件。

八.docker-entrypoint.sh

这个脚本是 Nginx Docker 容器的入口点,负责根据环境变量配置 Nginx 并启动服务。

1.HTTPS 配置处理

HTTPS_CONFIG=''

if [ "${NGINX_HTTPS_ENABLED}" = "true" ]; then
# 检查证书路径并设置
if [ -n "${CERTBOT_DOMAIN}" ] && \
       [ -f "/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_FILENAME}" ] && \
       [ -f "/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_KEY_FILENAME}" ]; then
# 使用 Let's Encrypt 证书
        SSL_CERTIFICATE_PATH="/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_FILENAME}"
        SSL_CERTIFICATE_KEY_PATH="/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_KEY_FILENAME}"
else
# 使用默认证书
        SSL_CERTIFICATE_PATH="/etc/ssl/${NGINX_SSL_CERT_FILENAME}"
        SSL_CERTIFICATE_KEY_PATH="/etc/ssl/${NGINX_SSL_CERT_KEY_FILENAME}"
fi
export SSL_CERTIFICATE_PATH
export SSL_CERTIFICATE_KEY_PATH

# 处理 HTTPS 配置模板
    HTTPS_CONFIG=$(envsubst < /etc/nginx/https.conf.template)
export HTTPS_CONFIG
    envsubst '${HTTPS_CONFIG}' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf
fi
export HTTPS_CONFIG

(1)初始化 HTTPS_CONFIG 为空

(2)如果启用了 HTTPS:

  • 检查 Let’s Encrypt 证书是否存在

  • 设置适当的证书路径

  • 导出证书路径变量

  • 从模板中读取 HTTPS 配置并进行环境变量替换

2.ACME 挑战配置

这部分配置 Let’s Encrypt 证书验证所需的 ACME 挑战路径。

if [ "${NGINX_ENABLE_CERTBOT_CHALLENGE}" = "true" ]; then
    ACME_CHALLENGE_LOCATION='location /.well-known/acme-challenge/ { root /var/www/html; }'
else
    ACME_CHALLENGE_LOCATION=''
fi
export ACME_CHALLENGE_LOCATION

3.配置文件处理

env_vars=$(printenv | cut -d= -f1 | sed 's/^/$/g' | paste -sd, -)

envsubst "$env_vars" < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
envsubst "$env_vars" < /etc/nginx/proxy.conf.template > /etc/nginx/proxy.conf

envsubst "$env_vars" < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf
  • 创建包含所有环境变量的列表

  • 将环境变量替换到各个 Nginx 配置模板中

4.启动Nginx

以前台模式启动 Nginx 服务器,确保容器保持运行状态。

exec nginx -g 'daemon off;'

这个脚本的核心功能是根据环境变量动态配置 Nginx,特别是处理 HTTPS 设置和证书配置,然后启动服务。

参考文献

[0] Dify中的nginx服务:https://z0yrmerhgi8.feishu.cn/wiki/F5fyweIKPiWCj2kcBuRcixbSnoe

[1] https://github.com/langgenius/dify/tree/main/docker/nginx


知识星球:Dify源码剖析及答疑,Dify扩展系统源码,AI书籍课程|AI报告论文,公众号付费资料。加微信buxingtianxia21进NLP工程化资料群,以及Dify交流群。

(文:NLP工程化)

发表评论