Docker-Nginx与PHP容器正常运行但无法提供HTML文件的技术问询
问题
Windows 10 Pro环境搭配最新版Docker Desktop,通过docker-compose部署了nginx_container和php_container两个容器。PHP文件(index.php、test.php)放在php容器的/var/www/html/目录下能正常访问,但同目录下的HTML文件(test.html)访问时返回404。排查发现Nginx容器是从自身的/var/www/html目录读取静态文件,导致两个容器的代码目录不一致。需要实现HTML和PHP文件从同一目录提供服务。
解决方案:用Docker共享卷统一代码目录
核心思路是创建一个共享卷(或绑定本地目录),让Nginx和PHP-FPM容器同时挂载到各自的/var/www/html目录,这样静态文件由Nginx直接读取,PHP文件转发给PHP-FPM处理,两者访问的是同一套代码文件。
步骤1:修改docker-compose.yml,添加共享卷
更新docker-compose.yml,添加一个命名卷(或绑定本地src目录),让两个容器都挂载到/var/www/html:
version: '3.8' services: php_container: container_name: php_container build: context: . dockerfile: Dockerfile.php restart: on-failure:3 networks: - backend volumes: - app_code:/var/www/html # 挂载共享卷到php容器的代码目录 nginx_container: container_name: nginx_container build: context: . dockerfile: Dockerfile.nginx ports: - "80:80" - "443:443" restart: on-failure:3 depends_on: - php_container networks: - backend - default volumes: - app_code:/var/www/html # 挂载同一个共享卷到nginx容器的代码目录 networks: backend: volumes: app_code: # 定义命名共享卷
如果希望本地
src目录的修改实时同步到容器,可以把命名卷换成绑定挂载:volumes: - ./src:/var/www/html
步骤2:调整Dockerfile.php,移除构建时复制代码的步骤
因为已经用共享卷挂载代码,不需要在构建PHP镜像时复制src目录,修改Dockerfile.php:
FROM php:8.3-fpm-alpine # Update, upgrade and install some things RUN apk update && \ apk upgrade && \ apk add --no-cache \ nano \ ncdu \ libzip-dev \ zip # Install some stuff RUN docker-php-ext-install \ zip # Clean up RUN rm -rf /var/cache/apk/* # 移除原有的COPY代码步骤,改为依赖卷挂载 # COPY --chown=www-data:www-data ./src/ /var/www/html/ # RUN chmod -R 755 /var/www/html WORKDIR /var/www/html/
步骤3:确认Nginx配置无需修改
你的nginx.conf配置已经正确设置了root /var/www/html,并且静态文件的location /规则也没问题,保持原配置即可:
server { listen 80; server_name localhost; root /var/www/html; index index.php index.html index.htm; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; location = /50x.html { root /usr/share/nginx/html; } location / { try_files $uri $uri/ =404; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php_container:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }
步骤4:重新构建并启动容器
执行以下命令重新构建镜像并启动容器:
docker-compose down docker-compose build docker-compose up -d
将本地src目录下的index.php、test.html、test.php文件放入,此时Nginx可以直接读取HTML文件,PHP文件转发给PHP-FPM处理,两者都指向同一目录的文件,问题解决。
内容的提问来源于stack exchange,提问作者Darcey

