micro_proxy
一个用于管理微应用的工具,支持Docker镜像构建、容器管理、Nginx反向代理配置等功能。
功能特性
- 🔍 自动发现微应用 - 支持多个扫描目录,自动发现包含Dockerfile的微应用
- 🐳 Docker镜像构建 - 自动构建微应用的Docker镜像,支持环境变量传递
- 🔄 容器生命周期管理 - 启动、停止、清理容器
- 🌐 Nginx反向代理 - 自动生成nginx配置,作为统一入口
- 📦 Docker Compose集成 - 生成docker-compose.yml文件
- 📊 状态管理 - 基于目录hash判断是否需要重新构建
- 🌍 网络管理 - 统一管理Docker网络,支持微应用间通信
- 📝 脚本支持 - 支持预构建(setup.sh)和清理(clean.sh)脚本
- 📋 网络地址列表 - 生成网络地址列表,便于排查连通性问题
- 🔒 内部服务支持 - 支持Redis、MySQL等不需要nginx代理的内部服务
安装
从 crates.io 安装(推荐)
从源码构建
# 克隆仓库
# 构建
# 安装
快速开始
1. 创建配置文件
复制示例配置文件并根据需要修改:
2. 启动微应用
# 启动所有微应用
# 强制重新构建所有镜像
# 显示详细日志
3. 访问应用
所有应用通过Nginx统一入口访问,默认端口为80(可在 micro_proxy.yml 配置文件中的 nginx_host_port 字段修改):
# 访问主应用
# 访问API服务
命令说明
start - 启动微应用
选项:
-c, --config <path>: 指定配置文件路径(默认:./micro_proxy.yml)--force-rebuild: 强制重新构建所有镜像
stop - 停止微应用
选项:
-c, --config <path>: 指定配置文件路径(默认:./proxy-config.yml)
clean - 清理微应用
选项:
-c, --config <path>: 指定配置文件路径(默认:./proxy-config.yml)--force: 强制清理,不询问确认--network: 同时清理Docker网络
status - 查看状态
选项:
-c, --config <path>: 指定配置文件路径(默认:./proxy-config.yml)
network - 查看网络地址
选项:
-c, --config <path>: 指定配置文件路径(默认:./proxy-config.yml)-o, --output <path>: 指定输出文件路径(覆盖配置文件中的设置)
配置说明
主配置文件 (proxy-config.yml)
# 扫描目录列表(用于 Static 和 Api 类型)
scan_dirs:
- "./micro-apps"
# Nginx配置文件输出路径
nginx_config_path: "./nginx.conf"
# Docker Compose配置文件输出路径
compose_config_path: "./docker-compose.yml"
# 状态文件路径
state_file_path: "./proxy-config.state"
# 网络地址列表输出路径
network_list_path: "./network-addresses.txt"
# Docker网络名称
network_name: "proxy-network"
# Nginx监听的主机端口(统一入口)
nginx_host_port: 80
# 反向代理配置
apps:
# Static 和 Api 类型:name 必须与扫描发现的微应用文件夹名称一致
- name: "app-name"
routes: # 访问路径
container_name: "container" # 容器名称
container_port: 80 # 容器内部端口
app_type: "static" # 应用类型: static, api 或 internal
description: "应用描述" # 可选
nginx_extra_config: | # 可选:额外的nginx配置(仅 static 和 api 有效)
add_header 'X-Custom-Header' 'value';
# Internal 类型:不需要 nginx 反向代理,仅用于微应用间内部通信
- name: "redis"
routes: # Internal 类型 routes 为空
container_name: "redis-container"
container_port: 6379
app_type: "internal"
description: "Redis 缓存服务"
path: "./services/redis" # 必须配置,指向服务文件夹路径
扫描目录说明
scan_dirs 配置项用于指定扫描微应用的目录列表,以下是重要的使用规则:
1. 只扫描一级目录
- 系统只会读取指定目录下的一级子目录,不会递归扫描
- 每个一级子目录被视为一个独立的微应用
- 示例:
./micro-apps/ ├── app1/ # 会被扫描 ├── app2/ # 会被扫描 └── nested/ └── app3/ # 不会被扫描(二级目录)
2. 支持多个扫描目录
- 如果微应用分布在多个不同的目录下,可以在
scan_dirs中指定多个目录 - 示例:
scan_dirs: - "./frontend-apps" - "./backend-apps" - "./services"
3. 目录名称唯一性要求
- 在所有扫描目录中,不允许存在相同名称的目录
- 如果扫描到相同的目录名称,系统会报错并退出
- 示例(错误配置):
这种情况下,系统会报错:./frontend-apps/ └── common/ # 与 backend-apps 下的 common 重名 ./backend-apps/ └── common/ # 与 frontend-apps 下的 common 重名发现重复的微应用名称: common
4. 目录命名建议
- 建议使用有意义的、唯一的目录名称
- 目录名称将作为微应用的默认名称
- 避免使用特殊字符和空格
微应用开发专题
微应用目录结构
Static 和 Api 类型
Static 和 Api 类型的微应用目录结构:
micro-apps/
├── main-app/ # 文件夹名称即为微应用名称
│ ├── Dockerfile # 必须在项目根目录
│ ├── .env # 环境变量文件
│ ├── setup.sh # 可选:预构建脚本
│ ├── clean.sh # 可选:清理脚本
│ └── ... # 其他应用文件
├── resume-app/
│ ├── Dockerfile
│ ├── .env
│ └── ...
└── api-service/
├── Dockerfile
├── .env
└── ...
关键要求:
- 每个微应用必须是一个独立的文件夹
- 文件夹名称即为微应用的名称
- Dockerfile必须放在项目根目录
- .env文件用于定义环境变量(可选)
- setup.sh和clean.sh脚本放在项目根目录(可选)
Internal 类型
Internal 类型的微应用目录结构(如 Redis、MySQL 等):
services/
├── redis/ # 服务文件夹
│ ├── Dockerfile # 必须在项目根目录
│ ├── .env # 环境变量文件
│ ├── setup.sh # 可选:预构建脚本
│ ├── clean.sh # 可选:清理脚本
│ └── ... # 其他服务文件
└── mysql/
├── Dockerfile
├── .env
└── ...
关键要求:
- 服务文件夹可以放在任意位置(通过配置文件的 path 字段指定)
- Dockerfile必须放在项目根目录
- .env文件用于定义环境变量(可选)
- setup.sh和clean.sh脚本放在项目根目录(可选)
- 不需要通过 nginx 访问,仅用于微应用间内部通信
Dockerfile要求
- Dockerfile必须放在项目根目录
- 建议使用EXPOSE指令声明暴露的端口
- 如果没有EXPOSE指令,micro_proxy会发出警告
示例:
FROM nginx:alpine
EXPOSE 80
COPY . /usr/share/nginx/html
环境变量配置
在.env文件中定义环境变量,这些变量会在构建时传递给Docker:
APP_PORT=80
ENV=production
DEBUG=false
注意:
- .env文件是可选的
- 如果没有.env文件,micro_proxy仍然会构建镜像,但不会传递环境变量
- 环境变量只在构建时传递,运行时环境变量需要在Dockerfile中定义
脚本支持
micro_proxy支持在微应用中使用脚本来自动化构建和清理过程。
setup.sh - 预构建脚本
在构建镜像前执行,用于准备构建环境:
#!/bin/bash
# 执行一些准备工作,如安装依赖、构建前端等
clean.sh - 清理脚本
在清理时执行,用于清理构建产物:
#!/bin/bash
# 执行清理工作,如删除构建产物、清理缓存等
脚本执行时机:
- setup.sh在每次构建镜像前执行
- clean.sh在执行
micro_proxy clean命令时执行
应用类型
micro_proxy支持三种应用类型,影响Nginx配置和容器配置的生成:
static - 静态网站
适用于前端应用、静态页面等,启用缓存:
app_type: "static"
特性:
- 启用浏览器缓存
- 适合静态资源
- 响应头包含缓存控制
- 需要配置 routes(访问路径)
- 需要通过 nginx 反向代理访问
api - API服务
适用于后端API服务,禁用缓存:
app_type: "api"
特性:
- 禁用浏览器缓存
- 适合动态内容
- 支持自定义nginx配置
- 需要配置 routes(访问路径)
- 需要通过 nginx 反向代理访问
internal - 内部服务
适用于Redis、MySQL等不需要nginx代理的内部服务:
app_type: "internal"
path: "./services/redis" # 必须配置,指向服务文件夹路径
特性:
- 不需要 nginx 反向代理
- 不需要配置 routes(routes 为空)
- 不添加 HTTP 健康检查(可能不是 HTTP 服务)
- 仅用于微应用间内部通信
- 必须配置 path 字段,指向包含 Dockerfile 的文件夹路径
- 可以被其他微应用通过容器名称访问
使用场景:
- Redis 缓存服务
- MySQL 数据库服务
- MongoDB 数据库服务
- 其他不需要对外暴露的服务
反向代理配置约定
micro_proxy 为 Static 和 Api 类型的微应用生成 Nginx 反向代理配置时,遵循以下约定:
Static 类型的反向代理约定
Static 类型适用于前端应用、静态页面等,其反向代理行为如下:
根路径配置(route: "/")
- 直接转发请求,不修改 URI
- 示例:访问
/index.html→ 后端收到/index.html - 配置示例:
location / { proxy_pass http://${app-name_upstream_host}:80; }
非根路径配置(route: "/resume_app")
- 使用 rewrite 规则移除路径前缀
- 示例:
- 访问
/resume_app→ 后端收到/ - 访问
/resume_app/→ 后端收到/ - 访问
/resume_app/assets/style.css→ 后端收到/assets/style.css
- 访问
- 配置示例:
location /resume_app { rewrite ^/resume_app(/.*)?$ /$1 break; proxy_pass http://${app-name_upstream_host}:80; }
适用场景:
- 前端应用部署在子路径下(如 VITE_BASE_URL=/resume_app)
- 静态资源服务
- SPA(单页应用)
Api 类型的反向代理约定
Api 类型适用于后端 API 服务,其反向代理行为如下:
保留完整路径
- 不修改请求 URI,后端收到完整的请求路径
- 示例:访问
/api/v1/status→ 后端收到/api/v1/status - 配置示例:
location /api { proxy_pass http://${app-name_upstream_host}:8080; }
重要说明:
proxy_pass不以/结尾,确保后端收到完整的请求路径- 如果后端服务期望接收
/api前缀,请确保后端路由配置正确 - 如果后端服务不期望
/api前缀,请使用 Static 类型的配置方式
适用场景:
- RESTful API 服务
- GraphQL 服务
- 后端微服务
路径重写对比
| 类型 | 访问路径 | 后端收到路径 | 说明 |
|---|---|---|---|
| Static (/) | /index.html |
/index.html |
根路径直接转发 |
| Static (/app) | /app/index.html |
/index.html |
移除前缀 |
| Api (/api) | /api/v1/status |
/api/v1/status |
保留完整路径 |
配置建议
前端应用(Static)
- name: "frontend"
routes:
app_type: "static"
container_port: 80
- 前端应用通常部署在子路径下
- 使用 rewrite 规则移除路径前缀
- 前端路由配置应匹配子路径(如 VITE_BASE_URL=/app)
后端 API(Api)
- name: "backend"
routes:
app_type: "api"
container_port: 8080
- 后端 API 通常需要保留完整路径
- 后端路由应包含
/api前缀(如/api/v1/users) - 如果后端不期望
/api前缀,请考虑使用 Static 类型或调整后端路由
网络通信
所有微应用共享同一个Docker网络,可以通过服务名称相互访问:
# main-app访问api-service
# api-service访问main-app
# api-service访问redis(内部服务)
网络规则:
- 所有容器都在同一个Docker网络中
- 容器可以通过容器名称相互访问
- 端口映射由micro_proxy自动管理
- Static 和 Api 类型的应用通过 nginx 统一入口对外访问
- Internal 类型的应用仅用于内部通信,不对外暴露
反向代理配置
每个 Static 和 Api 类型的微应用都可以配置多个访问路径:
apps:
- name: "main-app"
routes: # 多个访问路径
container_port: 80 # 容器内部端口
app_type: "static"
路由规则:
- 所有请求通过Nginx统一入口(默认80端口)
- 根据routes配置将请求转发到对应容器
- 支持路径重写和自定义配置
- Internal 类型的应用不需要配置 routes
自定义Nginx配置
可以为每个 Static 和 Api 类型的应用添加额外的nginx配置:
apps:
- name: "main-app"
routes:
nginx_extra_config: |
add_header 'X-Custom-Header' 'value';
location /api {
proxy_pass http://backend:3000;
}
注意:
- nginx_extra_config 仅对 Static 和 Api 类型有效
- Internal 类型不需要也不应该配置 nginx_extra_config
故障排查
查看日志
# 显示详细日志
# 查看容器日志
# 查看nginx日志
查看网络地址
# 生成并查看网络地址列表
# 查看生成的文件
检查容器状态
# 查看所有容器状态
# 使用docker命令查看
项目结构
proxy-config/
├── src/
│ ├── main.rs # 主入口
│ ├── lib.rs # 库入口
│ ├── cli.rs # 命令行接口
│ ├── config.rs # 配置管理
│ ├── discovery.rs # 应用发现
│ ├── builder.rs # 镜像构建
│ ├── container.rs # 容器管理
│ ├── nginx.rs # Nginx配置生成
│ ├── compose.rs # Docker Compose生成
│ ├── state.rs # 状态管理
│ ├── script.rs # 脚本执行
│ ├── network.rs # 网络管理
│ ├── dockerfile.rs # Dockerfile解析
│ └── error.rs # 错误定义
├── Cargo.toml # 项目配置
├── proxy-config.yml.example # 配置文件示例
└── README.md # 项目文档
技术栈
- Rust - 主要编程语言
- Docker - 容器化
- Nginx - 反向代理
- Docker Compose - 容器编排
许可证
本项目采用 MIT 许可证 - 详见 LICENSE 文件
贡献
欢迎提交Issue和Pull Request!