发布时间:2026/9/4 15:02:41
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),仅供参考

相关新闻

2026/9/4 14:57:41

生产异常闭环Agent:从异常识别到根因分析与整改跟踪

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/4 14:57:41

基于STM32与云平台的智能窗帘系统全栈开发实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/4 15:57:48

FreeCAD 安装实操:30 分钟从下载到第一次运行

FreeCAD 安装实操:30 分钟从下载到第一次运行 【免费下载链接】FreeCAD Official source code of FreeCAD, a free and opensource multiplatform 3D parametric modeler. 项目地址: https://gitcode.com/GitHub_Trending/fr/FreeCAD FreeCAD 是一款开源、免…

2026/9/4 15:57:48

Label Studio 源码开发环境避坑指南:热重载配置一次讲清

Label Studio 源码开发环境避坑指南:热重载配置一次讲清 【免费下载链接】label-studio Label Studio is a multi-type data labeling and annotation tool with standardized output format 项目地址: https://gitcode.com/GitHub_Trending/la/label-studio …

2026/9/3 18:28:26

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/9/3 14:29:47

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/9/3 14:30:35

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/9/4 0:00:58

STM32H743 SPI从机DMA双缓冲通信实战

简介:本资源是面向嵌入式开发工程师与STM32进阶学习者的SPI DMA双机通信从机端完整实现方案,聚焦STM32H743高性能Cortex-M7单片机在工业控制与高速数据交互场景下的从机通信开发痛点。压缩包含1355个文件,主体为599个C源码与321个头文件&…

2026/9/4 0:00:58

CPU开盖降温教程:20元成本让温度直降30度的原理与实践

最近很多朋友都在抱怨,自己的电脑一到夏天就变成"烤箱",玩游戏时CPU温度动不动就飙到90度以上,风扇噪音堪比直升机。更让人头疼的是,明明配置不错,却因为高温降频导致性能大打折扣。如果你也遇到了类似问题&…

2026/9/4 0:00:58

ArkTS 表单工程:场地预约页的三态场次 Grid 与校验

ArkTS 表单工程:场地预约页的三态场次 Grid 与校验 App 14「运动场地预约」场地 Tab(Func1Tab),是整 App 交互最丰富的页面——场地横向切换 三色图例 渐变预约预览卡 快捷模板 今日场次 Grid(可选/已选/已满三态&…

2026/9/3 20:43:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/3 17:51:43

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/3 21:06:57

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…