Magento – Static Content 404 with Magento 2 and Nginx

dockermagento2magento2.3nginxstatic-content

Preface: I have read through as many posts as I can find about this issue, but I have tried all solutions suggested already.

The Issue
Using a quick docker setup to get a local instance of Magento 2 up for contributing development. I used this dockerize module for convenience. I have the site up and running, but all static content is throwing 404. The homepage pulls up, and all content including the media are loaded. But none of the static content (js/css) are resolving.

Environment Details

  • Currently on the 2.3-develop branch of the core Magento 2 repo.
  • My host machine is Ubuntu 18.04
  • As mentioned, I'm using arvatorSCM/dockerize which includes:
    • Nginx
    • Redis
    • MySQL
    • I have replaced the php image with a local build of the same thing except using PHP 7.1

Already tried

  • I am using the nginx.conf.sample file that comes with Magento.
  • I have tried both developer mode without deploying static content and production mode with setup:static-content:deploy. Both of these result in 404's on all pub/static... URLs.
  • I have tried disabling static content signing as well. No change in results.
  • Yes I have flush, cleared, and disabled all of the caches with every test as well as emptying directories such as generated, pub/static, var/cache, var/page_cache, var/view_preprocessed.

I did some debugging in the Nginx config file by adding cookies in each of the location blocks. The strange thing is the /static/ block never seems to be executed. The cookie being added in the first line of this block never gets added to any static content responses. I also tried throwing some debugging into pub/static.php and it doesn't appear to ever be executed.

I understand this has to be an environmental config issue, but I am out of ideas on what to try. I have completely wiped my setup and started over multiple times, but my result is always the same.

Below are some screenshots from my testing. What's interesting is all CSS requests show as (canceled) status, but all JS show as 404.
Console errors
CSS Request
JS Request

To clarify, my official question here is for any recommendations of what might cause the static content to 404, and if anyone has any ideas to try to resolve the issue that I haven't already tried. Thank you for your time and any assistance.

UPDATE

My Nginx config file, which is taken directly from the linked docker setup, but I stripped out all Magento stuff and instead included the sample file.

upstream fastcgi_backend {
   server   php:9000;
}

server {
    listen                      80 default_server;
    listen                      443 default_server ssl;

    server_name                 magento2.docker;

    ssl_certificate             /etc/nginx/ssl/cert.pem;
    ssl_certificate_key         /etc/nginx/ssl/key.pem;

    client_max_body_size        10M;

    set                         $MAGE_ROOT /var/www/html;
    set                         $MAGE_MODE developer;

    include /var/www/html/nginx.conf.sample;
}

My docker-compose.yml file for reference is the same as this – https://github.com/arvatoSCM/dockerize-magento2/blob/develop/docker-compose.yml

And my nginx.conf.sample file hasn't been modified from the repo – https://github.com/magento/magento2/blob/2.3-develop/nginx.conf.sample

UPDATE 2

After some more testing I found that if I manually do the rewrite from /pub/static/ to /static.php?resource=$1 it results in a successful call.
For example, if I try to go to magento2.docker/pub/static/frontend/Magento/luma/en_US/css/styles-m.css I get a 404. But if I to go magento2.docker/static.php?resource=frontend%2FMagento%2Fluma%2Fen_US%2Fcss%2Fstyles-m.css I get the CSS file successfully. This means the /static/ location in the Nginx config file isn't getting properly triggered I think. I just can't figure out why.

UPDATE 3

I was able to get the assets to load by moving the location /static/ blocks in nginx.conf.sample to be inside the location /pub/ block as follows. This is just a temporary fix though, because it means the alias in pub isn't working properly I think. Anyone have suggestions on why that might be the case?

location /pub/ {
    add_header Set-Cookie nginxlocation="pub";
    location ~ ^/pub/media/(downloadable|customer|import|theme_customization/.*\.xml) {
        deny all;
    }
    alias $MAGE_ROOT/pub/;
    add_header X-Frame-Options "SAMEORIGIN";

    # Moved from /static/
    location ~ ^/pub/static/version {
        rewrite ^/pub/static/(version[^/]+/)?(.*)$ /static/$2 last;
    }
    location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|json)$ {
        add_header Cache-Control "public";
        add_header X-Frame-Options "SAMEORIGIN";
        expires +1y;

        if (!-f $request_filename) {
            rewrite ^/pub/static/?(.*)$ /static.php?resource=$1 last;
        }
    }
    location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
        add_header Cache-Control "no-store";
        add_header X-Frame-Options "SAMEORIGIN";
        expires    off;

        if (!-f $request_filename) {
           rewrite ^/pub/static/?(.*)$ /static.php?resource=$1 last;
        }
    }
    if (!-f $request_filename) {
        rewrite ^/pub/static/?(.*)$ /static.php?resource=$1 last;
    }
    add_header X-Frame-Options "SAMEORIGIN";
}

Best Answer

I followed the above (moving the /static block inside the /pub block) but it didn't work for me. In the end, what did the trick was then adding in a new block for /static as follows :

location /static/ {
    if (!-f $request_filename) {
         rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
    }
}

Note that is subtly different to the similar rewrite at the end of your code in Update 3.

Related Topic