webman实现多应用独立域名访问有四种方案:一、使用webman/domain插件自动绑定域名与应用;二、nginx反向代理+路径重写,将域名请求转为带应用前缀的内部路径;三、中间件读取$request->host()强制切换应用上下文;四、docker多容器+nginx网关按host头分发流量。

如果您已在Webman中配置了多个应用,但希望每个应用通过独立域名直接访问(如 admin.example.com 对应 admin 应用、api.example.com 对应 api 应用),而非依赖路径前缀(如 /admin/xxx),则需完成域名与应用的精准绑定。以下是实现此目标的多种可行方案:
一、使用 webman/domain 插件实现自动域名绑定
该插件专为多应用域名映射设计,支持动态识别 Host 头并路由至对应应用,无需修改 Nginx 重写规则即可实现 URL 简写(如 admin.example.com/user/list 直接命中 admin 应用的 UserController::list)。
1、执行 Composer 命令安装插件:
composer require webman/domain
2、确认插件配置文件已生成:plugin/webman/domain/app.php
3、编辑 plugin/webman/domain/app.php,设置域名与应用绑定关系:
return [
'enable' => true,
'bind' => [
'admin.example.com' => 'admin',
'api.example.com' => 'api',
'blog.example.com' => 'blog'
],
'check' => function ($bind, $domain, $app) {
return isset($bind[$domain]) && $bind[$domain] === $app;
}
];
4、确保全局路由配置 config/route.php 中未覆盖插件的域名匹配逻辑,且不启用冲突的路径前缀路由。
5、重启 Webman 服务使插件生效:
php start.php restart
二、Nginx 反向代理 + 路径重写方式
当无法使用插件或需兼容旧版 Webman 时,可通过 Nginx 在请求进入框架前完成 Host 判断与路径注入,将域名请求转换为带应用前缀的内部路径,再交由 Webman 统一路由解析。
1、为每个域名配置独立的 upstream 模块,例如:
upstream webman_admin {
server 127.0.0.1:8787;
}
2、添加 server 块,监听 admin.example.com 并重写路径:
server {
listen 80;
server_name admin.example.com;
root /path/to/webman/public;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
if (!-f $request_filename) {
rewrite ^/(.*)$ /admin/$1 break;
proxy_pass http://webman_admin;
}
}
}
3、为 api.example.com 创建另一组 server 块,仅修改 server_name 和 rewrite 目标为 /api/$1。
4、确保 Webman 的 config/app.php 中已正确定义 'admin' 和 'api' 应用的 controller_namespace。
5、重载 Nginx 配置:
nginx -s reload
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
三、基于中间件的域名鉴权路由方式
此方法不依赖外部组件或 Nginx 重写,完全在 PHP 层拦截请求,通过中间件读取 $request->host() 并强制切换当前应用上下文,适用于对部署环境控制力强、需细粒度权限校验的场景。
1、在 app/middleware/ 目录下新建 DomainBindMiddleware.php:
use support\Request;
use Webman\Http\Response;
class DomainBindMiddleware {
public function process(Request $request, \Closure $next): Response {
$host = $request->host();
$map = [
'admin.example.com' => 'admin',
'api.example.com' => 'api'
];
if (isset($map[$host])) {
$_SERVER['WEBMAN_APP'] = $map[$host];
} else {
return response('Domain not allowed', 404);
}
return $next($request);
}
}
2、在 config/middleware.php 的全局中间件数组中注册该中间件:
App\Middleware\DomainBindMiddleware::class
3、修改 config/app.php,在 applications 配置项中确保各应用键名与 $_SERVER['WEBMAN_APP'] 值严格一致。
4、在各应用的 route.php 中定义根路径路由,例如 app/admin/route.php 中:
Route::get('/', [app\admin\controller\IndexController::class, 'index']);
5、启动 Webman 后,访问 admin.example.com 将直接触发 admin 应用的根控制器,URL 中完全不出现 /admin/ 路径前缀。
四、Docker 多容器 + Nginx 入口网关方式
适用于生产环境高隔离性要求场景,每个 Webman 应用运行在独立容器中,通过宿主机 Nginx 作为统一入口,依据 Host 头将流量分发至不同容器端口,彻底避免应用间干扰。
1、为 admin 应用编写 docker-compose.yml 片段,暴露端口 8787:
services:
webman-admin:
image: ghcr.io/tinywan/docker-php-webman:latest
ports:
- "8787:8787"
volumes:
- ./admin:/app
2、为 api 应用编写另一服务,暴露端口 8989:
webman-api:
image: ghcr.io/tinywan/docker-php-webman:latest
ports:
- "8989:8787"
volumes:
- ./api:/app
3、在宿主机 Nginx 中配置基于域名的 proxy_pass:
server {
listen 80;
server_name admin.example.com;
location / {
proxy_pass http://127.0.0.1:8787;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:8989;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
4、执行 docker-compose up -d 启动全部容器。
5、验证 admin.example.com 与 api.example.com 是否分别返回各自应用内容,各容器进程完全独立,无共享内存或配置冲突风险。










