ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Immich 反向代理部署指南:Nginx、Caddy、Apache 与 Traefik 实战配置

Immich 反向代理部署指南:Nginx、Caddy、Apache 与 Traefik 实战配置 Immich 反向代理部署指南Nginx、Caddy、Apache 与 Traefik 实战配置【免费下载链接】immichHigh performance self-hosted photo and video management solution.项目地址: https://gitcode.com/GitHub_Trending/im/immich在自托管场景中Immich 官方 Docker 镜像默认直接暴露 2283 端口见 docker-compose.yml。当你需要通过公网访问、使用统一域名、终结 TLS、做多级负载均衡时就需要在 Immich 前面加一层自定义反向代理。本文覆盖反向代理的全部通用要求头部转发、上传限制、子路径限制、/.well-known/immich发现端点的作用以及 Nginx、Caddy、Apache 2、Traefik 3 四套可直接复制的完整配置并结合服务端与移动端源码说明这些要求背后的实现原理。读完本文你将能够正确配置任意主流反向代理使其与 Immich 完全兼容理解public_url/backend_url的设置方式排查上传中断499 错误、WebSocket 失效、移动端连接失败等典型问题。反向代理的通用要求Immich 支持在用户与服务器之间部署任意数量的反向代理代理层可以负责 TLS 终结、负载均衡或其他高级功能。但为了保证完全兼容所有位于 Immich 与用户之间的反向代理必须做到两点完整转发所有请求头并将以下四个头部设置为正确值头部作用Host转发真实域名否则服务器无法识别多租户/多域名场景X-Real-IP客户端真实 IP用于日志与访问统计X-Forwarded-Proto原始协议http/https影响服务端生成的重定向 URLX-Forwarded-For完整代理链中的客户端 IP 序列允许足够大的上传体积。Immich 上传的是原图与原始视频体积可达数 GB代理必须相应调大 body 大小限制并调整超时否则大文件上传会在中途失败。服务端如何信任这些头部上面的头部转发不是建议而是必要原因在于服务端启用了 Express 的 trust proxy 机制。从 app.common.ts 的启动代码可以看到app.set(trust proxy, [loopback, ...network.trustedProxies]);即 NestJS 应用会信任回环地址以及IMMICH_TRUSTED_PROXIES配置中列出的 IP 段。相关配置在 config.repository.ts 中解析network: { trustedProxies: dto.IMMICH_TRUSTED_PROXIES ?? [linklocal, uniquelocal], },也就是说默认信任链路本地linklocal169.254.0.0/16与私有网段uniquelocal10/8、172.16/12、192.168/16。如果反向代理部署在公网 IP 或非标准网段应通过环境变量IMMICH_TRUSTED_PROXIES逗号分隔的 IP 或 CIDR 列表取值说明见 environment-variables.md显式声明代理 IP否则来自该代理的X-Forwarded-For等头部可能不被信任导致 IP 统计失真。该变量的校验规则定义在 env.dto.ts 的trustedProxiesSchema中每个条目必须能通过 IP 或 IP 段校验IsIPRange({ requireCIDR: false })格式非法会直接报[IMMICH_TRUSTED_PROXIES] Must be an ip address or ip address range错误这一点在 config.repository.spec.ts 的测试用例中有明确验证合法值如10.1.0.0,10.2.0.0, 169.254.0.0/16非法值如10.1会被拒绝。必须部署在域名根路径不支持子路径一个关键限制Immich 不支持以子路径方式提供服务例如 Nginx 里写成location /immich { ... }是不行的必须将 Immich 服务在某个子域名的根路径下例如https://photos.example.com/而不是https://example.com/immich/。/.well-known/immich发现端点如果你的反向代理使用 Lets Encrypt 的 http-01 challenge需要特别注意验证 Immich 的 well-known 端点/.well-known/immich能被正确路由到 Immich 服务器否则它可能被路由到其他服务导致移动端应用遇到连接问题。这个端点并非最好有而是移动端的核心发现机制。服务端实现位于 app.controller.tsApiExcludeEndpoint() Get(.well-known/immich) Authenticated({ public: true }) getImmichWellKnown() { return { api: { endpoint: /api, }, }; }它是一个公开端点返回 JSON{api:{endpoint:/api}}。移动端在登录/解析服务器地址时会主动访问它api.service.dart 中的resolveEndpoint会对用户输入的服务器 URL 发起GET {baseUrl}/.well-known/immich请求5 秒超时成功时读取data[api][endpoint]并据此拼接出真实 API 地址若相对路径以/开头则相对 baseUrl 解析。若该端点被反向代理吞掉或路由到别处移动端只能回退为把用户输入地址直接当作 API 端点再探测/api在多服务共域名的部署下极易连接失败。Nginx 示例配置官方文档给出的 Nginx 完整配置如下。使用前需将public_url设置为实例的前端对外 URLbackend_url设置为 Immich 服务器的路径地址。server { server_name public_url; # allow large file uploads client_max_body_size 50000M; # disable buffering uploads to prevent OOM on reverse proxy server and make uploads twice as fast (no pause) proxy_request_buffering off; # increase body buffer to avoid limiting upload speed client_body_buffer_size 1024k; # Set headers proxy_set_header Host $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; # enable websockets: http://nginx.org/en/docs/http/websocket.html proxy_http_version 1.1; proxy_redirect off; # set timeout proxy_read_timeout 600s; proxy_send_timeout 600s; send_timeout 600s; location / { proxy_pass http://backend_url:2283; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } # useful when using Lets Encrypt http-01 challenge # location /.well-known/immich { # proxy_pass http://backend_url:2283; # } }逐项说明这些指令为什么这样写client_max_body_size 50000M允许最大约 50 GB 的上传请求体对应通用要求中的足够大的上传。低于该值的请求会被 Nginx 直接以 413 拒绝。proxy_request_buffering off关闭请求体缓冲。开启时 Nginx 会先把上传内容完整写入磁盘/内存再转发大视频上传会占满代理服务器内存或磁盘文档注释明确指出这是为防止 OOM关闭后数据边收边转还能消除停顿官方注释称可使上传速度提高约一倍。client_body_buffer_size 1024k增大体缓冲避免上传速率被限制。四个proxy_set_header正是前述必转头部要求的最小实现。$proxy_add_x_forwarded_for会自动追加多级代理链$scheme保证X-Forwarded-Proto反映真实的 http/https。proxy_http_version 1.1Upgrade/Connection upgrade启用 WebSocket 支持。Immich 的 Web 端与实时功能依赖 WebSocket缺少这段会导致连接建立后立刻被降级或断开。proxy_read_timeout/proxy_send_timeout/send_timeout设为 600s视频上传过程中两次写数据之间的间隔可能较长600 秒的读/写超时可覆盖大多数大文件上传场景超时后会返回 504。proxy_pass http://backend_url:2283目标端口 2283 是 Immich 服务端默认 API 端口与 docker-compose.yml 中的2283:2283端口映射一致。可选的location /.well-known/immich当 Lets Encrypt http-01 challenge 由 Nginx 自身处理location /.well-known/acme-challenge时其余/.well-known/*路径可能被别的路由规则截获此精确匹配规则确保发现端点仍能到达 Immich。Caddy 示例配置Caddy 可作为 Nginx 的替代方案自带自动 HTTPS 证书申请与续期配置极其简洁。官方示例immich.example.org { reverse_proxy http://snip:2283 }snip处替换为 Immich 服务器的实际地址容器网络中的服务名或 IP。Caddy 的reverse_proxy默认会正确设置X-Forwarded-For、X-Forwarded-Proto等头部并支持 WebSocketHTTP/1.1 长连接透传因此上述通用要求无需额外声明。注意 Caddy 默认对请求体大小无硬限制适合直接承载大文件上传但如需精细控制超时可在reverse_proxy指令中追加transport http下的read_timeout/write_timeout。Apache 2 示例配置Apache 2 的站点级配置示例VirtualHost *:80 ServerName snip ProxyRequests Off # set timeout in seconds ProxyPass / http://127.0.0.1:2283/ timeout600 upgradewebsocket ProxyPassReverse / http://127.0.0.1:2283/ ProxyPreserveHost On /VirtualHost要点说明ProxyRequests Off只作为反向代理禁用正向代理能力这是 Apache 反向代理场景的标准安全配置。ProxyPass ... timeout600将代理连接超时设为 600 秒与 Nginx 示例中的 600s 超时策略对应用于大文件上传场景。upgradewebsocket开启 mod_proxy 的 WebSocket 升级支持保证 Immich 的 WebSocket 通道可用。ProxyPreserveHost On等价于把Host头部保持为客户端请求的原始值满足头部转发要求。ProxyPassReverse改写后端返回的Location等头部避免重定向把客户端带回到内部地址 127.0.0.1:2283。使用 Apache 前需确认已启用mod_proxy、mod_proxy_http模块。Traefik 3 示例配置以下示例针对 Traefik 版本 3。第一部分traefik.yaml中增大 respondingTimeouts。最关键的一步是增大 immich 所用 entrypoint 的respondingTimeouts。以 443 端口的websecure为例默认值是 60 秒这会导致视频上传进行 1 分钟后中断错误码 499。配置为 600 秒后上传将在 10 分钟后才失败多数场景已足够必要时继续调大[... # traefik.yaml entryPoints: websecure: address: :443 # this section needs to be added transport: respondingTimeouts: readTimeout: 600s idleTimeout: 600s第二部分docker-compose.yml中为 immich-server 添加 Traefik 标签services: immich-server: [ ... ] labels: traefik.enable: true # increase readingTimeouts for the entrypoint used here traefik.http.routers.immich.entrypoints: websecure traefik.http.routers.immich.rule: Host(immich.example.com) traefik.http.services.immich.loadbalancer.server.port: 2283路由规则用Host()匹配子域名呼应必须部署在子域名根路径的限制负载目标端口 2283 与前面各方案一致。最后要注意网络可达性Traefik 必须能与 immich 所在网络通信通常的做法是把 Traefik 所在的网络加入immich-server服务的 networks 配置中。总结部署 Immich 反向代理可归纳为四条检查清单Immich 位于子域名的根路径不做子路径路由代理层转发全部头部并正确设置Host、X-Real-IP、X-Forwarded-Proto、X-Forwarded-For四个头部必要时用IMMICH_TRUSTED_PROXIES声明代理网段默认信任 linklocal 与 uniquelocal见 config.repository.ts放大上传体积限制与读/写/空闲超时Nginx 50000M / 600sTraefikrespondingTimeouts600sApachetimeout600并开启 WebSocket 支持确保/.well-known/immich能路由到 Immich服务端实现见 app.controller.ts否则移动端api.service.dart 的resolveEndpoint可能无法解析出 API 端点。按 docker-compose.yml 的默认端口映射2283接入后以上任一代理方案即可与 Immich 完全兼容地对外提供服务。【免费下载链接】immichHigh performance self-hosted photo and video management solution.项目地址: https://gitcode.com/GitHub_Trending/im/immich创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表