Dynamic route's controller method not firing I'm trying to use the Background Image module, but there seems to be a problem with the dynamic route it registers for generating CSS. I've been debugging it, but I have run into a wall. It's basically a duplicate of the core Image module's routing setup, so I'm not sure what's wrong, but the controller method never fires; the controller isn't even instantiated. Here's the config file:

route_callbacks:
  - '\Drupal\background_image\Routing\BackgroundImageRoutes::routes'


Here's the routes method:

  public function routes() {
    error_log('Router::routes');
    $routes = [];
    // Generate background image CSS files. If clean URLs are disabled the
    // files will always be served through the menu system. If clean URLs are
    // enabled and the file already exists, PHP will be bypassed.
    $directory_path = $this-&gt;streamWrapperManager-&gt;getViaScheme('public')-&gt;getDirectoryPath();

    $routes['background_image.css'] = new Route(
      '/' . $directory_path . '/background_image/css/{background_image}/{scheme}/{file}',
      [
        '_controller' =&gt; '\Drupal\background_image\Controller\BackgroundImageCssController::deliver',
      ],
      [
        '_access' =&gt; 'TRUE',
      ]
    );
    error_log(print_r($routes, true));
    return $routes;
  }


Here's the $routes object:

Array
(
    [background_image.css] =&gt; Symfony\Component\Routing\Route Object
        (
            [path:Symfony\Component\Routing\Route:private] =&gt; /sites/default/files/background_image/css/{background_image}/{scheme}/{file}
            [host:Symfony\Component\Routing\Route:private] =&gt; 
            [schemes:Symfony\Component\Routing\Route:private] =&gt; Array
                (
                )
            [methods:Symfony\Component\Routing\Route:private] =&gt; Array
                (
                )
            [defaults:Symfony\Component\Routing\Route:private] =&gt; Array
                (
                    [_controller] =&gt; \Drupal\background_image\Controller\BackgroundImageCssController::deliver
                )
            [requirements:Symfony\Component\Routing\Route:private] =&gt; Array
                (
                    [_access] =&gt; TRUE
                )
            [options:Symfony\Component\Routing\Route:private] =&gt; Array
                (
                    [compiler_class] =&gt; Symfony\Component\Routing\RouteCompiler
                )
            [compiled:Symfony\Component\Routing\Route:private] =&gt; 
            [condition:Symfony\Component\Routing\Route:private] =&gt; 
        )
)


If I try to hit a URL such as /sites/default/files/background_image/css/3/public/dq5DbF1hqHxkHXGiHSl9yuXubPox08bOX6nE12gX2h0.css?p2aptq (which the module correctly generates when I've got a background image set up on the site) I get a 404 error and nothing in the error log.

I'm using docker4drupal and have checked the nginx config and am 99% sure that's not the issue (there are no rules for /sites/default/files/ and I do see the 404 in the nginx log.)

Why doesn't the dynamic route work as it should, and as it doesn't for the Image module?
Well, I'm an idiot. The problem was nginx after all. There actually was a block to handle CSS/JS assets that was preventing the dynamic route from executing because of a lack of physical files. I had to place the following above that rule:

location ~ ^/sites/.*/files/background_image/ {
    try_files $uri @drupal;
}


Here's the offending rule:

location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|xml|otf|ttf|eot|woff|woff2|svg|svgz)$ {
    expires 30d;
    tcp_nodelay off;
    open_file_cache off;
    open_file_cache_valid 45s;
    open_file_cache_min_uses 2;
    open_file_cache_errors off;

    location ~* ^.+\.svgz$ {
        gzip off;
        add_header Content-Encoding gzip;
    }
}


I found the solution after searching for relevant issues on other modules that generate dynamic files, such as imagecache, which led me to the official nginx Drupal guide. Definitely a learning exercise.