
Lazycat Advanced Routing
- 189 installs
- 54 repo stars
- Updated April 3, 2026
- whoamihappyhacking/lazycat-skills
Helps with ai & agent building tasks.
About
lazycat-advanced-routing is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- lazycat-advanced-routing
- AI & Agent Building
- AI-coding skill
Lazycat Advanced Routing by the numbers
- 189 all-time installs (skills.sh)
- +4 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #2,965 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/whoamihappyhacking/lazycat-skills --skill lazycat-advanced-routingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 189 |
|---|---|
| repo stars | ★ 54 |
| Last updated | April 3, 2026 |
| Repository | whoamihappyhacking/lazycat-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
懒猫微服高级路由与网络配置指南
你是一个专业的懒猫微服网络配置专家。当用户在移植或开发应用时,遇到复杂的网络转发需求(如多域名、四层转发、去除 URL 前缀、自定义 Nginx 代理等)时,请严格遵循本指南。
核心路由机制 (Core Routing Mechanisms)
懒猫微服提供了三种层级的路由控制能力,请根据用户的需求选择最合适的方案:
1. 基础 HTTP/HTTPS 路由 (application.routes)
适用于绝大多数标准的 HTTP 代理场景。 规则格式: URL_PATH=UPSTREAM 特点: 默认会去掉 URL_PATH 前缀。例如 - /api/=http://backend:80,访问 /api/v1 时,后端实际收到的是 /v1。
支持三种上游协议:
http(s)://$hostname/$path(最常用,转发给容器。域名格式需为$service_name.$appid.lzcapp)file:///$dir_path(直接托管静态文件)exec://$port,$exec_file_path(启动一个可执行文件并代理到本地端口)
2. 高级 HTTP 路由 (application.upstreams) (v1.3.8+)
适用于需要对 HTTP 请求进行精细控制的场景。 能力包括:
- 基于域名的分流: 使用
domain_prefix。 - 保留 URL 前缀: 设置
disable_trim_location: true。 - 解决 Host 校验报错: 设置
use_backend_host: true。 - 跳过 SSL 验证: 设置
disable_backend_ssl_verify: true。 - 清除特定 Header (解决跨域等): 使用
remove_this_request_headers: [Origin, Referer]。
示例:
upstreams:
- location: /api
backend: http://backend.cloud.lazycat.app.demo.lzcapp:80
disable_trim_location: true # 保留 /api 前缀3. TCP/UDP 四层转发 (application.ingress)
绝对不要使用 routes 处理非 HTTP 流量! 如果用户需要暴露 SSH、数据库、游戏私服等非 HTTP 端口,必须使用 ingress。 警告:
ingress仅提供底层网络转发,没有鉴权保护,开发者需自行在应用内处理安全问题。- 除非极特殊情况,严禁主动接管 80 和 443 端口。
示例:
application:
ingress:
- protocol: tcp
port: 3306
service: mysql # 转发到 mysql 容器的 3306 端口
- protocol: udp
publish_port: 20000-30000 # 动态端口范围转发
service: app复杂反向代理最佳实践 (APP Proxy)
如果 routes 和 upstreams 仍然无法满足需求(比如需要极度复杂的 URL 重写、多域名分别指向不同后端,或者需要在微服中查看详细的请求日志),请使用官方提供的 app-proxy 镜像。
镜像地址: registry.lazycat.cloud/app-proxy:v0.1.0 (本质是一个 OpenResty)
使用方式:通过 `setup_script` 覆盖 Nginx 配置 这是处理多域名 (配合 application.secondary_domains) 最强大的方式。
application:
subdomain: myapp
secondary_domains:
- myadmin
routes:
- /=http://app-proxy.cloud.lazycat.app.myapp.lzcapp:80
services:
app-proxy:
image: registry.lazycat.cloud/app-proxy:v0.1.0
setup_script: |
cat <<'EOF' > /etc/nginx/conf.d/default.conf
server {
server_name myapp.*; # 匹配默认域名
location / { proxy_pass http://frontend:3000; }
}
server {
server_name myadmin.*; # 匹配附加域名
location / { proxy_pass http://backend:8080; }
}
EOF平台兼容性说明
如果需要查看 routes, upstreams, ingress 的完整规范,或需要查看 APP Proxy 的更详细用法,请主动读取本技能包 references/ 目录下的相关 Markdown 文档。
高级路由
简介
官方维护了一个APP Proxy镜像,方便开发者实现复杂的路由功能,以及查看对应的请求日志。 APP Proxy本质是一个基于Openresty的镜像,镜像地址:registry.lazycat.cloud/app-proxy:v0.1.0。
使用方法
目前有两种使用模式:
- 通过环境变量配置:适用于只有一个HTTP上游服务的情况
- 通过setup_script配置:直接覆盖Openresty的配置文件,可以使用任何Openresty支持的配置
::: danger 禁止混合使用两种模式。 :::
下面详细介绍每种模式的使用方法。
环境变量
APP Proxy抽象了一些特定功能,可以让不熟悉Nginx/Openresty配置的开发者,通过环境变量快速配置,目前支持的环境变量:
| 环境变量 | 作用 | 示例 |
|---|---|---|
| UPSTREAM(必填) | 设置代理的上游HTTP服务 | UPSTREAM=http://whoami:80 |
| BASIC_AUTH_HEADER | 设置Authorization header,绕过Basic Auth | BASIC_AUTH_HEADER="Basic dXNlcjpwYXNzd29yZA==" |
| REMOVE_REQUEST_HEADERS | 移除HTTP请求头,多个请求头以英文;分隔 | REMOVE_REQUEST_HEADERS="Origin;Host;" |
setup_script
在开始之前,您需要先了解setup_script的原理;除此之外,还需要了解Nginx的配置。
您可以直接在setup_script中,覆盖Openresty的配置文件,甚至还可以写一些Lua脚本,进行更为复杂的配置。
这里给出一个简单的示例:
lzc-sdk-version: '0.1'
name: APP Proxy Test
package: cloud.lazycat.app.app-proxy-test
version: 0.0.1
application:
routes:
# 将请求转发到APP Proxy(app-proxy service)
- /=http://app-proxy:80
subdomain: app-proxy-test
services:
app-proxy:
image: registry.lazycat.cloud/app-proxy:v0.1.0
setup_script: |
# 覆盖Openresty的配置文件
cat <<'EOF' > /etc/nginx/conf.d/default.conf
# 任何Nginx/Openresty支持的配置
server {
server_name app-proxy-test.*;
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
}示例
查看应用请求日志
只要使用了APP Proxy,您就可以通过lzc-cli docker logs -f查看请求日志。 比如,在以下示例中,你就可以通过lzc-cli docker logs -f cloudlazycatappapp-proxy-test-app-proxy-1查看请求日志。
lzc-sdk-version: '0.1'
name: APP Proxy Test
package: cloud.lazycat.app.app-proxy-test
version: 0.0.1
application:
routes:
- /=http://app-proxy:80
subdomain: app-proxy-test
services:
app-proxy:
image: registry.lazycat.cloud/app-proxy:v0.1.0
environment:
- UPSTREAM="http://whoami:80"
whoami:
image: registry.lazycat.cloud/snyh1010/traefik/whoami:c899811bc4a1f63a绕过Basic Auth
通过设置BASIC_AUTH_HEADER环境变量,您可以为请求注入Authorization请求头,让应用实现免登录。
BASIC_AUTH_HEADER的值为Basic base64(用户名:密码)。在以下示例中,假设用户名是user,密码是password,echo -n "user:password" | base64得到的base64编码为dXNlcjpwYXNzd29yZA==。
lzc-sdk-version: '0.1'
name: APP Proxy Test
package: cloud.lazycat.app.app-proxy-test
version: 0.0.1
application:
routes:
- /=http://app-proxy:80
subdomain: app-proxy-test
services:
app-proxy:
image: registry.lazycat.cloud/app-proxy:v0.1.0
environment:
- UPSTREAM="http://whoami:80"
- BASIC_AUTH_HEADER="Basic dXNlcjpwYXNzd29yZA=="
whoami:
image: registry.lazycat.cloud/snyh1010/traefik/whoami:c899811bc4a1f63a删除请求Header
通过设置REMOVE_REQUEST_HEADERS,环境变量,可以删除特定的请求头。
假如,我们想删除Origin请求头,我们可以设置REMOVE_REQUEST_HEADERS="Origin",然后就可以删除Origin请求头。
lzc-sdk-version: '0.1'
name: APP Proxy Test
package: cloud.lazycat.app.app-proxy-test
version: 0.0.1
application:
routes:
- /=http://app-proxy:80
subdomain: app-proxy-test
services:
app-proxy:
image: registry.lazycat.cloud/app-proxy:v0.1.0
environment:
- UPSTREAM="http://whoami:80"
- REMOVE_REQUEST_HEADERS="Origin;Cache-Control;"
whoami:
image: registry.lazycat.cloud/snyh1010/traefik/whoami:c899811bc4a1f63a多域名支持
目前,懒猫微服已经支持一个应用使用多个域名。
结合setup_script,您可以实现复杂的路由功能,将多个域名,分别转发到应用的不同后端。
在以下示例中,不同的域名将会被转发到不同的后端:
app-proxy-test.xxx.heiyu.space将会被转发到Openresty的默认首页portainer.xxx.heiyu.space将会被转发到Portainerwhoami.xxx.heiyu.space将会被转发到whoami
lzc-sdk-version: '0.1'
name: APP Proxy Test
package: cloud.lazycat.app.app-proxy-test
version: 0.0.1
application:
routes:
- /=http://app-proxy.cloud.lazycat.app.app-proxy-test.lzcapp:80
subdomain: app-proxy-test # 应用列表里默认打开的域名
secondary_domains:
- portainer
- whoami
services:
app-proxy:
image: registry.lazycat.cloud/app-proxy:v0.1.0
setup_script: |
cat <<'EOF' > /etc/nginx/conf.d/default.conf
server {
server_name app-proxy-test.*;
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
}
server {
server_name portainer.*;
location / {
proxy_pass http://portainer:9000;
}
}
server {
server_name whoami.*;
location / {
proxy_pass http://whoami:80;
}
}
EOF
portainer:
image: registry.lazycat.cloud/u8997806945/portainer/portainer-ce:d393c0c7d12aae78
whoami:
image: registry.lazycat.cloud/snyh1010/traefik/whoami:c899811bc4a1f63aTCP/UDP 4层转发 {#tcp-udp-ingress}
::: warning 正常http流量,请使用application.routes功能
ingress的TCP/UDP转发能是为了提供给微服客户端之外使用,比如命令行或第三方应用。 如果只是为了转发容器的某个http端口,请使用lzcapp的http路由功能。
:::
如果您想提供一些 TCP/UDP 服务,可以在 lzc-manifest.yml 文件中的 application 字段下加一个 ingress 子字段
application:
ingress:
- protocol: tcp
port: 8080
- protocol: tcp
description: 数据库服务
port: 3306
service: mysql
- protocol: tcp
description: 2W-3W端口来源转发到对应端口
service: app
publish_port: 20000-30000
- protocol: tcp
description: 1.6W-1.8W端口来源都转发到6666端口
service: app
port: 6666
publish_port: 16000-18000protocol: 对外服务的协议, 有tcp和udp两种选择description: 对此服务的描述,便于管理员了解基本情况port: 目标服务的端口号,若不写则为实际入站端口号。(v1.3.8之前的版本不支持port为80或443)service: 服务名称,用来定位具体的service container。默认值为apppublish_port: 入站端口号,默认值为port对应的端口号。支持3306以及1000-50000两种写法。
设置好以后, 就可以通过浏览器来进行访问啦, 比如您的应用域名为 app-subdomain (lzc-manifest.yml 文件的 subdomain 字段), 设备名为 devicename, 您就可以通过访问 app-subdomain.devicename.heiyu.space:3306 来访问对外提供的 TCP 服务啦。
::: warning 安全提示 当您使用TCP/UDP功能时,微服系统仅能提供底层虚拟网络的保护,从原理上无法提供鉴权流程。 微服客户端上的其他进程可以不受限制的访问对应TCP/UDP端口。 若用户使用端口转发工具进行转发则会进一步降低安全性,因此开发者在提供TCP/UDP功能时一定要妥善处理鉴权逻辑。 :::
::: warning 80/443
当您的应用直接接管443时(v1.3.8+支持),流量是直接到达您容器内,因此系统无法做一些预处理,包括但不限于
- 账户鉴权
- 自动唤醒应用
- HTTPS证书配置
- application.routes,application.upstreams等配置
几乎所有情况下您都不应该去使用443端口配置。
目前设想唯一合理的场景是:使用微服分配的EIP,全流量转发到另外一台主机/NAS上,并配置一个非微服域名。
如果您真的确定要自行处理80/443流量则需要在对应ingress条目里明确声明yes_i_want_80_443:true
:::
路由规则 =========
application.routes字段为 []Rule类型
Rule按照URL_PATH=UPSTREAM的形式声明, 其中URL_PATH为浏览器访问时的实际URL路径(不含hostname部分), UPSTREAM为具体的上游服务, 目前支持以下3种协议
file:///$dir_pathexec://$port,$exec_file_pathhttp(s)://$hostname/$path
注意:application.routes 在转发时默认会去掉 URL_PATH 前缀。例如下面规则, 当浏览器请求 /api/v1 时,后端实际收到的是 /v1。
routes:
- /api/=http://backend:80如果需要保留前缀,请改用 application.upstreams 并设置 disable_trim_location: true(lzcos v1.3.9+)。
http上游 =======
http/https支持内网或外网服务. 比如内置的应用商店这个lzcapp只有一行代码.
routes:
- /=https://appstore.lazycat.cloud当访问https://appstore.$微服名称.heiyu.space时会将所有请求都直接转发到上游的https://appstore.lazycat.cloud, 这种 情况下页面内的js代码依旧可以使用lzc-sdk/js的功能, 应用商店的安装\打开逻辑是在微服中运行的,但代码是部署在公有云上,方便统一维护.
绝大部分情况下,lzcapp的http路由是转发到应用内某个service的http端口上, 比如bitwarden这个密码管理lzcapp, 就是将整个lzcapp的 http服务转发到bitwarden这个service的80端口上.
package: cloud.lazycat.app.bitwarden
description: 一款自由且开源的密码管理服务
name: Bitwarden
application:
routes:
- /=http://bitwarden.cloud.lazycat.app.bitwarden.lazcapp:80
- /or_use_this_short_domain=http://bitwarden:80
subdomain: bitwarden
services:
bitwarden:
image: bitwarden/nginx:1.44.1
1. http://bitwarden:80中的bitwarden是services中的service名称,这个名称在运行时会自动解析为service实际的ip. 2. http://bitwarden.cloud.lazycat.app.bitwarden.lzcapp:80的写法为$service_name.$appid.lzcapp
注意 1. lzcos-1.3.x之后会引入应用隔离,应用之间禁止相互访问,因此如果没有特殊原因直接使用service_name的形式作为域名更简便,也方便修改appid。(xxx.lzcapp本身不会被废弃,任意应用都能解析到正确IP,但隔离后无法访问到目标IP) 2. 但以下特殊情况依旧需要使用xxx.lzcapp域名形式 1. 在lzcos-1.3.x之前因为没有进行应用隔离,所有应用看到的service_name都是互通的。当不同应用有相同service_name时,可能被错误解析到其他容器IP。 因此service_name是app、db这类大概率会冲突的情况下在应用网络隔离前依旧需要使用xxx.lzcapp形式。 2. 如果上游服务会检测http request host之类的,则需要使用xxx.lzcapp形式,否则上游服务解析http request时, http header host会是service_name而非aaaa.xxx.heiyu.space。 此限制是因为上游服务也可能是一个公网服务,此时host必须原封不动传递给上游否则大概率会出现跨域之类的问题。 如果有相关需求,建议使用upstreams.[].use_backend_host=true明确指定此行为。
file上游 =========
file路由用来加载静态html文件, 比如pptist这个lzcapp是一个纯前端应用,因此仅使用了一条静态file路由规则,没有运行任何其他service
package: cloud.lazycat.app.pptist
name: PPTist
description: 一个基于 Vue3.x + TypeScript 的在线演示文稿(幻灯片)应用
application:
subdomain: pptist
routes:
- /=file:///lzcapp/pkg/content/
file_handler:
mime:
- x-lzc-extension/pptist # app支持.pptist
actions: # 打开对应文件的url路径,由文件管理器等app调用
open: /?file=%u # %u是某个webdav上的具体文件路径,一定存在文件名后缀
一般静态资源是通过lpk文件打包时引入的,lpk对应的contentdir内容最终会在运行时原封不动的以readonly的形式存放在/lzcapp/pkg/content/目录
exec上游 =========
exec://$port,$exec_file_path路由稍微特殊一点,由两部分组成
1. 最终提供服务的端口号$port,这里强制隐含了host为127.0.0.1 2. 具体的可执行文件路径. 可以为任意路径下的脚本或elf文件.
lzcapp启动时,系统会执行exec路由中的$exec_file_path文件,并假设此文件提供的服务运行在http://127.0.0.1:$port上. 系统本身不会检测此服务是否真的由$exec_file_path启动. (因此也能基于这个特性做一些初始化相关的操作)
一个lzcapp可以创建任意条不同类型的路由规则. 比如官方的懒猫网盘lzcapp的路由规则为
application:
image: registry.lazycat.cloud/lzc/lzc-files:v0.1.47
subdomain: file
routes:
- /api/=exec://3001,/lzcapp/pkg/content/backend
- /files/=http://127.0.0.1:3001/files/
- /=file:///lzcapp/pkg/content/dist其中前端页面由静态文件/lzcapp/pkg/content/dist提供, 所有以/api/开头的路径由可执行文件/lzcapp/pkg/content/backend启动后在http://127.0.0.1:3001上提供服务, 并且所有以/files/开头的路径也转发到http://127.0.0.1:3001/files上.
UpstreamConfig =============== 除此外还(v1.3.8+)可以使用applications.upstreams字段配置更细致的路由规则,
比如,
subdomain: debug
routes: #简单版本的routes也是可以一起工作的
- /=http://app1.org.snyh.debug.whoami.lzcapp:80
upstreams:
# 明确指定一些细微行为
- location: /search
backend: https://baidu.com/
use_backend_host: true #如果不设置则一般外网服务器会因为host字段不对拒绝服务
disable_auto_health_checking: true #不要针对这条路由做健康检测
remove_this_request_headers: #删除origin,referer等header避免跨域之类的问题
- origin
- Referer
disable_url_raw_path: true # 将原始url也进行规范化的转化
# 跳过后端自签SSL证书问题
- location: /other
backend: https://app2.snyh.debug.lzcapp:4443 #正常情况下这个域名是不会有合法正式的
disable_backend_ssl_verify: true #因此需要在这里配置跳过SSL验证
# 使用domain_prefix做基于域名前缀的分流
- location: /
domain_prefix: config #当访问https://config-debug.xx.heiyu.space/时走这里的规则
backend: http://config.snyh.debug.lzcapp:80
# 使用backend_launch_command替代exec路由规则,语义更明确
- location: /api
backend: http://127.0.0.1:3001/
backend_launch_command: /lzcapp/pkg/content/my-super-backend -listen :3001
一个应用使用多个域名 ===================
lzc-manifest.yml:application.subdomain是开发者期望使用的域名,但微服系统(v1.3.6+后)会进行一定调整
1. 如果多个应用使用相同的subdomain字段,则后安装的会被添加域名小尾巴 2. 多实例类型应用,同一个应用每个用户会分配独立的域名,因此非管理员看到的域名大概率会加上小尾巴 3. 域名前缀概念: xxxx-subdomain的域名和subdomain的效果是一致,即每个应用自动拥有任意多个域名。 4. 最终实际分配到的subdomain只能通过环境变量LAZYCAT_APP_DOMAIN获取到。 5. 所有前缀域名进入的流量都会忽略TCP/UDP Ingress配置。 (不影响默认应用域名进入的流量)
v1.3.8已支持基于域名的流量转发
由于application.routes不支持基于域名的转发,如果需要比较细致的调整路由规则, 可以添加一条特殊route规则,- /=http://nginx.$appid.lzcapp。 注意这里一定要用$service.$appid.lzcapp的形式,否则nginx无法收到完整的域名信息,原因见
比如,下面这个配置的效果是 1. 应用列表里打开默认是whoami.xx.heiyu.space(假设实际分配到的subdomain是whoami) 2. nginx-whoami.xx.heiyu.space流量会返回默认的nginx静态hello world 3. 任意内容-whoami.xx.heiyu.space与访问whoami.xx.heiyu.space效果相同
package: org.snyh.debug.whoami
name: whoami-lazycatmicroserver
application:
subdomain: whoami
routes:
- /=http://nginx.org.snyh.debug.whoami.lzcapp:80
services:
nginx:
image: registry.lazycat.cloud/snyh1010/library/nginx:54809b2f36d0ff38
setup_script: |
cat <<'EOF' > /etc/nginx/conf.d/default.conf
server { # whoami.xxx.heiyu.space以及其他任意域名前缀都转发到traefix/whoami
server_name _;
location / {
proxy_pass http://app1:80;
#目前setup_script机制还有点问题,这里不能直接写环境变量,如果有这个需求则
#只能使用binds的形式把文件放到pkg/content中binds进去
}
}
server { # nginx开头的域名转发到nginx默认页,比如nginx3-whoami.xxx.heiyu.space, nginx-whoami.xxx.heiyu.space
server_name ~^nginx.*-.*;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
EOF
app1:
image: registry.lazycat.cloud/snyh1010/traefik/whoami:c899811bc4a1f63a