Mezzio应用PHP内置服务运行正常 Docker部署报模板解析错误
Mezzio应用Docker部署模板解析错误解决方案
问题现象
我有一个Mezzio应用,使用composer serve启动PHP内置服务器时运行完全正常,但部署到Docker环境时抛出如下错误:
Fatal error: Uncaught Laminas\View\Exception\RuntimeException: Laminas\View\Renderer\PhpRenderer::render: Unable to render template "error::error"; resolver could not resolve to a file in /var/www/portal/vendor/laminas/laminas-view/src/Renderer/PhpRenderer.php:492 Stack trace: #0 /var/www/portal/vendor/mezzio/mezzio-laminasviewrenderer/src/LaminasViewRenderer.php(232): Laminas\View\Renderer\PhpRenderer->render(NULL) #1 /var/www/portal/vendor/mezzio/mezzio-laminasviewrenderer/src/LaminasViewRenderer.php(221): Mezzio\LaminasView\LaminasViewRenderer->renderModel(Object(Laminas\View\Model\ViewModel), Object(Laminas\View\Renderer\PhpRenderer), Object(Laminas\View\Model\ViewModel)) #2 /var/www/portal/vendor/mezzio/mezzio-laminasviewrenderer/src/LaminasViewRenderer.php(138): Mezzio\LaminasView\LaminasViewRenderer->renderModel(Object(Laminas\View\Model\ViewModel), Object(Laminas\View\Renderer\PhpRenderer)) #3 /var/www/portal/vendor/mezzio/mezzio/src/Response/ErrorResponseGeneratorTrait.php(61): Mezzio\LaminasView\LaminasViewRende in /var/www/portal/vendor/laminas/laminas-view/src/Renderer/PhpRenderer.php on line 492
相关配置
NGINX代理配置(nginx.conf)
user root; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 1024; } http { upstream nginx-web { server web:8110; } upstream nginx-portal { server portal:8115; } upstream nginx-api { server api:8120; } 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-Host $server_name; server { listen 80; server_name proxy; location /web { proxy_pass http://nginx-web; } location /portal { proxy_pass http://nginx-portal; } location /api { proxy_pass http://nginx-api; } } }
portal服务的Nginx配置(default.conf)
server { listen 8110; root /var/www/portal/public; server_name proxy; location / { try_files $uri $uri/ /index.php$is_args$args; index index.php; } location ~ ^/.+\.php(/|$) { fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }
docker-compose.yml配置
version: "3.9" services: db: container_name: db image: mysql:5.7 ports: - "3306:3306" volumes: - "${PROJECT_ROOT}/db:/var/lib/mysql" - ./conf/db/my.cnf:/etc/mysql/conf.d/my.cnf:ro env_file: - .env networks: - backend proxy: container_name: proxy image: nginx:mainline-alpine volumes: - ./conf/proxy/nginx.conf:/etc/nginx/nginx.conf:ro ports: - "80:80" - "8110:8110" # - "8115:8115" - "8120:8120" depends_on: - web - portal - api networks: - backend web: container_name: web image: nginx:mainline-alpine volumes: - "${PROJECT_ROOT}/web:/var/www/web" - ./conf/web/default.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - php networks: - backend portal: container_name: portal image: nginx:mainline-alpine volumes: - "${PROJECT_ROOT}/portal:/var/www/portal" - ./conf/portal/default.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - db - php port: - "8115:8115" networks: - backend api: container_name: api image: nginx:mainline-alpine volumes: - "${PROJECT_ROOT}/api:/var/www/api" - ./conf/api/default.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - php networks: - backend php: container_name: php image: maciejslawik/php-fpm-xdebug:latest ports: - "9000:9000" volumes: - "${PROJECT_ROOT}/web:/var/www/web" - "${PROJECT_ROOT}/portal:/var/www/portal" - "${PROJECT_ROOT}/api:/var/www/api" - ./conf/php/docker-php-ext-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini:ro networks: - backend composer: container_name: composer image: composer:2 restart: "no" command: install volumes: - "${PROJECT_ROOT}/composer:/app" - ./composer/composer.json:/app/composer.json networks: - backend phinx: container_name: phinx image: vegbrasil/phinx:latest volumes: - "${PROJECT_ROOT}/migrations/database/migrations:/app/database/migrations" - "${PROJECT_ROOT}/migrations/database/seeds:/app/database/seeds" - ./conf/phinx/phinx.php:/app/phinx.php:ro env_file: - .env depends_on: - db restart: "no" command: "status" environment: - TESTS_PHINX_DB_ADAPTER_MYSQL_HOST=db networks: - backend schemaspy: container_name: schemaspy image: schemaspy/schemaspy:latest volumes: - "${PROJECT_ROOT}/schemaspy/output:/output" - ./conf/schemaspy/schemaspy.properties:/schemaspy.properties:ro restart: "no" depends_on: - db networks: - backend networks: backend:
排查信息
已尝试通过xdebug排查问题,发现PhpRenderer.php无法解析.phtml模板文件。目前通过http://web.local:8115/dashboard访问应用正常,理想目标是通过http://web.local/portal/dashboard访问。
已确认模板文件存在且权限正常:
drwxrwxrwx 1 root root 4096 Oct 31 07:57 . drwxrwxrwx 1 root root 4096 Oct 31 07:57 .. -rwxrwxrwx 1 root root 197 Oct 31 07:57 summary.phtml
相关排查截图:


问题根因
- portal服务Nginx配置监听端口与docker-compose暴露端口不一致:default.conf监听8110,docker-compose配置portal服务端口为8115,导致代理转发请求失败触发404,404错误页模板未找到抛出最终报错
- docker-compose配置字段错误:portal服务下的配置项为
port,正确应为ports - Nginx代理路径转发规则错误:
location /portal转发时未去掉前缀,导致portal服务收到的请求路径为/portal/dashboard,与Mezzio配置的路由/dashboard不匹配触发404 - Mezzio未配置基础路径,导致路由、视图解析时路径匹配错误
解决方案
- 修正portal服务Nginx配置:将
default.conf中的listen 8110;修改为listen 8115; - 修正docker-compose配置:将portal服务下的
port:改为ports: - 调整Nginx代理转发规则:将nginx.conf中
location /portal块的proxy_pass http://nginx-portal;改为proxy_pass http://nginx-portal/;,末尾添加斜杠后Nginx会自动移除/portal前缀再转发请求 - 配置Mezzio基础路径:在Mezzio全局配置文件中添加
'base_path' => '/portal',确保路由生成、视图解析的路径均匹配前缀规则
内容的提问来源于stack exchange,提问作者GoharSahi
相关产品推荐
相关产品推荐

