Laravel Horizon and Nginx Proxy Manager: Static File Trouble
Problem: You've set up Laravel Horizon with Nginx Proxy Manager, but you're encountering an issue where static files (like CSS, JS, and images) aren't being served from your production server. Everything works flawlessly on your local machine, leaving you scratching your head.
Simplified: Imagine a website where the text is perfect, but all the pictures and styling are missing. That's what's happening with your static files - they're invisible!
Scenario:
You're building a Laravel application with a robust queue system powered by Horizon. You've chosen Nginx Proxy Manager for seamless SSL certificates and easy domain management. On your local machine, everything runs flawlessly - the application is responsive, and all static assets load correctly. However, when you deploy to your production server, the static files vanish, leaving a barebones website.
Original Code:
Nginx Proxy Manager Configuration (Simplified):
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://127.0.0.1:8000;
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-Proto $scheme;
}
}
Laravel Horizon Configuration:
'redis' => [
'client' => 'phpredis',
'options' => [
'cluster' => 'redis',
'prefix' => 'horizon:',
],
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
'horizon' => [
'processes' => env('HORIZON_PROCESSES', 1),
'supervisor-path' => '/usr/bin/supervisor',
],
Analysis:
The root of the issue typically lies in the Nginx Proxy Manager configuration and how it handles static assets. Your Nginx configuration is proxying all requests to your Laravel application running on port 8000. This means that even requests for static files are forwarded to Laravel, which is designed to handle dynamic content, not serve static assets directly.
Solution:
The solution involves tweaking your Nginx configuration to serve static files directly without relying on Laravel. Here's how:
-
Define a location block for static files: Add a new
location
block within your Nginx server configuration specifically for static files. This block will handle requests for files within thepublic
directory of your Laravel project.location / { proxy_pass http://127.0.0.1:8000; 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-Proto $scheme; } location ~* \.(?:css|js|png|jpg|jpeg|gif)$ { root /path/to/your/laravel/public; }
Replace
/path/to/your/laravel/public
with the actual path to thepublic
directory of your Laravel project. -
Configure Nginx Proxy Manager: Ensure your Nginx Proxy Manager configuration correctly maps the relevant domain to your server and this updated Nginx configuration file.
Important Notes:
- File Permissions: Make sure the
public
directory and its contents have the correct read permissions for the Nginx user (usuallywww-data
ornginx
). - Cache Busting: Implement cache busting techniques to ensure your browser fetches the latest version of static files when changes are made. This can be achieved using asset versioning, a CDN, or similar methods.
- Performance Optimization: If you have a lot of static files, consider using a CDN to distribute them globally for faster loading times.
Additional Value:
- Debugging Tips: If you're unsure where the issue stems from, enable Nginx error logging and analyze the logs to identify any specific error messages.
- Security Considerations: Be cautious when handling static files on your server and ensure that you implement proper security measures to prevent unauthorized access.
Conclusion:
Understanding the interaction between Laravel Horizon, Nginx Proxy Manager, and static file serving is crucial for a smooth production deployment. By following the outlined steps, you can effectively serve your static files and ensure your website appears as intended, both locally and on your production server.