You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel结合Docker部署时php artisan storage:link命令的问题排查与自动化解决方案咨询

I get exactly what you're dealing with here—separating Nginx and PHP-FPM into different containers makes symlinks tricky because the link created in one container might not resolve correctly in the other, even with shared volumes. Manual fixes haven't worked, so let's jump into automated solutions that work during build or startup, no manual intervention needed:

Since you're building a custom PHP-FPM image (build: php-fpm), you can bake the symlink directly into the image during the build phase. This ensures the link exists as soon as the container starts, with consistent paths and permissions across both containers.

Update your php-fpm/Dockerfile with these steps:

# Set working directory to your Laravel app root inside the container
WORKDIR /nginx-home/PortalRads

# Create the symlink from public/storage to storage/app/public
RUN ln -s ../storage/app/public public/storage

# Optional: Ensure correct permissions for the storage directory
RUN chown -R www-data:www-data /nginx-home/PortalRads/storage

Because both containers share the ./nginx-home volume, Nginx will see the symlink exactly as it exists in the PHP-FPM container, eliminating path or permission mismatches.

If you prefer a dynamic approach (e.g., if your app path might change), you can configure the PHP-FPM container to run Laravel's official storage link command automatically when it starts.

Option A: Use a Startup Script

Create a start.sh file in your php-fpm directory:

#!/bin/bash
# Navigate to the Laravel app root
cd /nginx-home/PortalRads
# Create the storage link (only if it doesn't already exist)
php artisan storage:link
# Start PHP-FPM
php-fpm

Then update your php-fpm/Dockerfile to use this script:

COPY start.sh /usr/local/bin/start.sh
RUN chmod +x /usr/local/bin/start.sh
CMD ["start.sh"]

Option B: Embed the Command in docker-compose.yml

No need to modify the Dockerfile—add the command directly to your docker-compose config:

php-fpm:
    build: php-fpm
    volumes:
      - ./nginx-home:/nginx-home
    command: >
      sh -c "cd /nginx-home/PortalRads && php artisan storage:link && php-fpm"

This runs the link command first, then starts PHP-FPM every time the container launches.

If symlinks are proving too problematic, you can configure Nginx to map /storage requests directly to the actual storage directory, no symlink required.

Add this location block to your Nginx default.conf inside the server block:

location /storage/ {
    alias /nginx-home/PortalRads/storage/app/public/;
    # Optional: Add caching headers for static assets like profile photos
    expires 30d;
    add_header Cache-Control "public, immutable";
}

Now when users visit https://dockerlaravel.medical.ky/storage/profile-photos/image.png, Nginx will pull the file directly from storage/app/public/ without relying on a symlink. This is great for environments where symlink permissions are hard to manage.

Chances are your manual attempts didn't work for one of these reasons:

  • The symlink you created in the PHP-FPM container used an absolute path that doesn't resolve the same way in the Nginx container (even with shared volumes, container-internal paths can differ).
  • The Nginx user (www-data) didn't have read access to the storage/app/public directory. The permission fix in the first solution addresses this.

内容的提问来源于stack exchange,提问作者SScotti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 09:47:49