使用docker-Nginx搭建网站遇到静态资源404报错

背景

最近在使用 docker 复现一个钓鱼网站的时候,在进行 docker 镜像的搭建时,选择了将 PHPNginxmysql 三个服务放在三个不同的镜像中,使用 docker-compose 进行相互通信来完成网站的复现搭建,但是在复现的过程中网站可以访问,但是 js、css、图片 等静态资源加载时, Nginx 会返回 404 找不到资源的错误。

问题及分析

docker启动的Nginx配置访问静态资源,访问失败404 ?

GET http://localhost:8080/Public/bootstrap/css/bootstrap.min.css net::ERR_ABORTED 404 (Not Found)
GET http://localhost:8080/Public/dist/css/AdminLTE.min.css net::ERR_ABORTED 404 (Not Found)

一般这种情况我们需要先考虑以下两点:

  • 配置文件中的 访问路径 有问题
  • 对应 文件不存在

但是按照 Nginx 配置文件访问静态资源,路径是正确的,PHP 容器中对应的文件也存在应该是没问题的,但浏览器在加载时始终显示404,而且网页是可以访问到的。

经过问题排查,发现原来Nginx是docker启动的,访问的静态资源必须是在docker容器里面的才可以,否则肯定找不到。PHP web服务容器中的网站目录并没有挂载到 Nginx 容器里面。而且 Nginxconf 配置文件进行路径映射的时候,映射的是容器里的文件路径。

server {
    listen 80;
    server_name loalhost;

    root /var/www/html;
    index index.php index.html index.htm;
	
	# 静态文件直接从本地Nginx容器获取
    location / {
        index index.php index.html admin.php;
        try_files $uri $uri/ /index.php?$query_string;
        autoindex  off;
    }

	# 以php结尾的请求则转发给php容器进行处理
    location ~ \.php(.*)$ {
        fastcgi_pass php:9000;
        fastcgi_index  index.php;
        fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO  $fastcgi_path_info;
        fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
        include        fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

解决办法

1.将资源挂载到 Ngnix 容器直接从容器获取:这里我创建了一个共享卷 website_code 将其分别挂在到 PHPNginx 容器,具体 docker-compose 文件如下所示,这里为了防止 Nginx 对网站代码进行修改,我们设置了 挂载共享卷只读 ,而 PHP 容器为可读可写(网站容器本身)。【推荐】

# edit by aurora
services:
  nginx:
    image: nginx:1.16.1
    container_name: nginx
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - website_code:/var/www/website:ro  # 挂载共享卷为只读
    depends_on:
      - php
    networks:
      - app-network

  php:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: php
    environment:
      MYSQL_DATABASE: mywebsite
      MYSQL_USER: root
      MYSQL_PASSWORD: root
      MYSQL_HOST: mysql
      MYSQL_PORT: 3306
    volumes:
      - website_code:/var/www/website  # 挂载共享卷为读写
    networks:
      - app-network

  mysql:
    image: mysql:5.7
    container_name: mysql
    volumes:
      - mysql_data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    environment:
      MYSQL_ROOT_PASSWORD: root
    networks:
      - app-network

volumes:
  mysql_data:
  website_code:

networks:
  app-network:
    driver: bridge

2.修改 Nginx 配置文件,将静态资源请求也转发到 PHP 容器进行处理。(可能会存在权限问题,需要自己去修改php配置文件,尝试修改php.ini文件中的security.limit_extensions设置,会存在一定安全问题)

在配置文件中添加如下代码,这部分只是一个示例,按照需求去更改

location ~* \.(css|js|png|jpg|jpeg|gif|ico|html)$ {
    fastcgi_pass php:9000;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

注意事项

  1. 如果是docker启动的单独的 Nginx,一定要注意映射目录,Nginx只能访问到自己容器内的目录,所以,在启动容器时就需要进行对应目录挂载。
  2. 在两个容器之间进行目录共享时,需要注意以下两点
    • 共享卷:创建共享卷,并将其挂载到 PHP和Nginx 容器中。对于 Nginx 容器,使用只读模式(ro),避免修改代码。
    • 避免本地挂载:没有本地代码目录挂载到 PHP 容器,避免了覆盖容器内的代码。
  3. 在进行网站 Docker 镜像的搭建时出于安全以及成功访问考虑,需要给网站目录进行权限设定。
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值