Laravel 在 Docker 环境下访问 storage 静态资源 404 问题解决

最近在学习使用docker编排laravel运行环境,遇到了在容器部署项目无法访问静态资源的问题,最终得以解决,在这里记录一下

问题复现

在项目storage/app/public目录下有一张图片img.png:

Laravel在Docker环境下访问storage静态资源404问题解决

并且已经在容器中执行php artisan storage:link来创建了软链接:

Laravel在Docker环境下访问storage静态资源404问题解决

然后打开浏览器,访问localhost/storage/img.png,结果返回404…

Laravel在Docker环境下访问storage静态资源404问题解决

在这里贴一下我的docker-compose.yml文件内容:


version: '3.7'
services:
  app:
    build:
      context: ./docker
      dockerfile: app.dockerfile
    working_dir: /var/www
    volumes:
      - ./:/var/www:cached
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=database
      - DB_PORT=3306
      - DB_DATABASE=iartisan
      - DB_USERNAME=root
      - DB_PASSWORD=123456
      - REDIS_HOST=redis
      - REDIS_PORT=6379

  database:
    build:
      context: ./docker
      dockerfile: database.dockerfile
    restart: always
    volumes:
      - mysql_data:/var/lib/mysql:rw
      - mysql_log:/var/log/mysql:rw
      - mysql_config:/etc/mysql:rw
    environment:
      - MYSQL_ROOT_PASSWORD=$DB_PASSWORD

  redis:
    image: redis:5

  proxy:
    build:
      context: ./docker
      dockerfile: nginx.dockerfile
    working_dir: /var/www
    volumes:
      - nginx_conf:/etc/nginx/conf.d:cached
      - ./public:/var/www/public:cached
    ports:
      - 80:80

volumes:
  mysql_data:
  mysql_log:
  mysql_config:
  nginx_conf:
    name: nginx_conf

networks:
  default:
    driver: bridge

app.dockerfile文件:

FROM php:7.4-fpm

COPY ./composer-setup.sh /

RUN apt-get clean \
    && cd /var/lib/apt \
    && mv lists lists.old \
    && mkdir -p lists/partial \
    && apt-get clean \
    && echo "deb http://mirrors.aliyun.com/debian/ buster main non-free contrib \n \
        deb-src http://mirrors.aliyun.com/debian/ buster main non-free contrib \n \
        deb http://mirrors.aliyun.com/debian-security buster/updates main \n \
        deb-src http://mirrors.aliyun.com/debian-security buster/updates main \n \
        deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib \n \
        deb-src http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib" > /etc/apt/sources.list \
    # 更新及安装库
    && apt-get update \
    && apt-get install -y libmagickwand-dev libmcrypt-dev libpq-dev libzip-dev zip \
    # PHP扩展安装
    && docker-php-ext-install -j$(nproc) pdo_mysql bcmath \
    && pecl install redis imagick mcrypt zip \
    && docker-php-ext-enable redis imagick mcrypt zip

nginx.dockerfilevhost.conf文件内容:

FROM nginx

COPY ./vhost.conf /etc/nginx/conf.d/default.conf
server {
    listen 80;
    server_name 127.0.0.1;
    index index.php index.html;
    root /var/www/public;

    error_log /var/log/nginx/error.log notice;
    access_log /var/log/nginx/access.log main;

    location / {
        try_files $uri /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

解决流程

起初尝试了docker 部署 Laravel,无法访问 storage 目录中的 文件这个帖子中评论的解决方案,以为是目录权限问题,尝试了给public/storage切换到www-data用户或者权限0777,结果都不行。

然后以为是路径问题,尝试了使用相对路径的软链接,结果不出意料,还是不行😄

Laravel在Docker环境下访问storage静态资源404问题解决

然而在容器外使用valet或者php artisan serve都是可以成功请求图片的?

Laravel在Docker环境下访问storage静态资源404问题解决

我还以为是nginx的问题,最后搞得我想用OSS来替代本地存储了,最后看到了这篇问题:

Dockerized Laravel App, always 404 on assets

发现可能是数据卷的映射问题,然后修改了docker-compose.yml的数据卷映射配置为映射项目根目录:


volumes:

- nginx_conf:/etc/nginx/conf.d:cached

# - ./public:/var/www/public:cached

- ./:/var/www:cached

重新构建,然后访问

Laravel在Docker环境下访问storage静态资源404问题解决

真是太感动了😭原来就是数据卷映射的问题

不过还有个值得注意的点,现在是可以访问了,但是此时在public目录下的storage软链接是相对路径../storage/app/public。经过测试,相对路径的软链接在容器内外都生效,而使用php artisan storage:link所创建的软链接是绝对路径,而docker容器内的目录是和宿主机不同的,这就导致了在哪种环境下执行的storage:link命令,就只能在哪种环境下生效

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 1

我也遇到这问题 网上找了好久资料 好几个处理方案都不行 老哥你这文章帮我搞定了 谢谢老哥

3年前 评论
邢闯洋 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!