Traefik 不能直接代理 PHP 是因为其仅支持 HTTP/HTTPS 等七层协议,而 PHP-FPM 使用不兼容的 FastCGI 协议;必须通过 Nginx(或类似服务器)作为中间层解析 HTTP 并转发 FastCGI 请求。
traefik 本身不直接运行 PHP,它只是反向代理;PHP 和 Nginx 需各自独立运行(比如用
),再由 Nginx 处理
请求,最后让 traefik 把流量转发给 Nginx。硬凑“trae配置
php
”会踩进进程模型混淆的坑。
为什么不能让 traefik 直连 php-fpm?
traefik 是 HTTP/HTTPS 反向代理,只理解七层协议(HTTP、gRPC、TLS SNI 等)。
使用的是 FastCGI 协议(二进制+私有帧格式),和 HTTP 完全不兼容。你没法在 traefik 的
中直接指向
—— 它根本解析不了 FastCGI 包。
必须保留 Nginx(或 Apache、Caddy)作为 FastCGI 终端:接收 HTTP 请求 → 解析 URI → 转发 .php 文件给
→ 拿回响应 → 返回给客户端。
典型三容器结构怎么编排?
推荐用 Docker Compose 实现隔离与复用。关键点不是“配置”,而是网络打通和路径对齐:
立即学习
“
PHP免费学习笔记(深入)
”;
Nginx 容器暴露端口(如
),不映射到宿主机;只和 traefik 同一个自定义网络(如
)
PHP-FPM 容器不暴露端口,只和 Nginx 在同一网络(可共用
网络),Nginx 通过服务名(如
)访问它
traefik 容器启用
provider,监听容器 label,并把请求路由到
服务(不是 php)
所有容器共享代码卷(如
),确保 Nginx 能读文件、php-fpm 能执行文件
示例片段(
片段):
nginx
.conf 里 fastcgi_pass 怎么写才不报 502?
错误常见于网络不通或 php-fpm 没监听对地址。在容器内,
必须指向 php 服务名 + 端口(默认
),不能写
或
—— 那是 Nginx 自己的 loopback,不是 php 容器。
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
正确写法(在
的
块中):
同时确认 php 容器里
或
没改过监听地址(保持默认
或
);若用了 socket(
),则需挂载相同路径并改用
。
traefik 路由规则漏掉静态资源怎么办?
traefik 默认把所有匹配
的请求都转给 Nginx,但如果你在 Nginx 里没配好 root 或 try_files,容易出现 CSS/JS 404,或 PHP 脚本被当静态文件下载。核心是:Nginx 必须自己决定哪些走 PHP,哪些直出。
最小可用
块应包含:
}
注意:
比
更可靠,能处理符号链接;
保证
前端
路由(如 Vue Router history 模式)也能 fallback 到
。
最常被忽略的是 volume 挂载路径一致性 —— Nginx 和 php 容器看到的
必须是同一份文件,否则修改 PHP 代码后刷新页面还是旧的,或者提示 “No input file specified”。
php-fpm.phpphp-fpmservicesphp-fpm:9000php-fpm80traefik-publicinternalphp:9000dockernginx./src:/var/www/htmldocker-compose.yml
services:
nginx:
image: nginx:alpine
volumes:
- ./src:/var/www/html
- ./nginx.conf:/etc/nginx/nginx.conf
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`app.test`)"
- "traefik.http.routers.myapp.entrypoints=web"
networks:
- traefik-public
php:
image: php:8.2-fpm-alpine
volumes:
- ./src:/var/www/html
networks:
- internal
traefik:
... 其他配置
networks:
- traefik-public
- internal
fastcgi_pass9000127.0.0.1:9000localhost:9000nginx.conflocation ~ \.php$
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
php-fpm.confwww.conf0.0.0.0:9000php:9000/var/run/php/php8.2-fpm.sockfastcgi_pass unix:/var/run/php/php8.2-fpm.sock;Hostserver
server {
listen 80;
root /var/www/html;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}$realpath_root$document_roottry_filesindex.php/var/www/html