Nginx – serving static files, invoking PHP instead

nginxPHP

I'm having a problem migrating a website from Apache to nginx. Most of the things work fine, I just have a very specific problem with some static files here.

In the docroot of the server, a phpBB is installed, and the .css files from the theme are piped through the PHP interpreter, instead of directly being delivered by the nginx, and I just can't figure out why.

My nginx site config:

server {

  listen   81; ## listen for ipv4
  listen   [::]:81 default ipv6only=on; ## listen for ipv6

  server_name  www.wanda.eu;

  access_log  /var/log/nginx/wanda.eu.access.log;
  error_log   /var/log/nginx/wanda.eu.error.log debug;

  root /srv/www/wanda.eu;

  location /static {
    try_files $uri $uri/ @php_index =404;
    expires 24h;
  }

  location / {
    #Secure arbitrary code execution on NON php files (ex: .png with PHP code)
    fastcgi_index index.php;
    try_files $uri $uri/ /index.php =404;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass unix:/tmp/php-cgi/php-cgi.socket;
    fastcgi_param SCRIPT_FILENAME /srv/www/wanda.eu$fastcgi_script_name;
  }
  location /dynamic {
    #Secure arbitrary code execution on NON php files (ex: .png with PHP code)
    try_files $uri $uri/ /dynamic/index.php =404;
    include /etc/nginx/fastcgi_params;
    fastcgi_index index.php;
    fastcgi_pass unix:/tmp/php-cgi/php-cgi.socket;
    fastcgi_param SCRIPT_FILENAME /srv/www/wanda.eu$fastcgi_script_name;
  }
}

(the dynamic block is a special block for the website which is configured there, which generates images – which is working fine)

The problem here is when requesting the url /forum/styles/bastisstyle/theme/stylesheet.css

With debugging enabled in the error_log, I see the following there:

2012/08/08 16:24:20 [debug] 13885#0: *669 http request line: "GET /forum/styles/bastisstyle/theme/stylesheet.css HTTP/1.1"
2012/08/08 16:24:20 [debug] 13885#0: *669 http uri: "/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 http args: ""
2012/08/08 16:24:20 [debug] 13885#0: *669 http exten: "css"
2012/08/08 16:24:20 [debug] 13885#0: *669 http process request header line
2012/08/08 16:24:20 [debug] 13885#0: *669 http header: "Host: www.wanda.eu:81"
2012/08/08 16:24:20 [debug] 13885#0: *669 http header: "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1"
2012/08/08 16:24:20 [debug] 13885#0: *669 http header: "Accept: text/css,*/*;q=0.1"
2012/08/08 16:24:20 [debug] 13885#0: *669 http header: "Accept-Language: en-us,en;q=0.5"
2012/08/08 16:24:20 [debug] 13885#0: *669 http header: "Accept-Encoding: gzip, deflate"
2012/08/08 16:24:20 [debug] 13885#0: *669 http header: "Connection: keep-alive"
2012/08/08 16:24:20 [debug] 13885#0: *669 http header: "Referer: http://www.wanda.eu:81/forum/"
2012/08/08 16:24:20 [debug] 13885#0: *669 http alloc large header buffer
2012/08/08 16:24:20 [debug] 13885#0: *669 malloc: 0000000001469B00:256
2012/08/08 16:24:20 [debug] 13885#0: *669 malloc: 0000000001497800:8192
2012/08/08 16:24:20 [debug] 13885#0: *669 http large header alloc: 0000000001497800 8192
2012/08/08 16:24:20 [debug] 13885#0: *669 http large header copy: 693
2012/08/08 16:24:20 [debug] 13885#0: *669 recv: fd:17 214 of 7499
2012/08/08 16:24:20 [debug] 13885#0: *669 http header: "Pragma: no-cache"
2012/08/08 16:24:20 [debug] 13885#0: *669 http header: "Cache-Control: no-cache"
2012/08/08 16:24:20 [debug] 13885#0: *669 http header done
2012/08/08 16:24:20 [debug] 13885#0: *669 event timer del: 17: 1344435925526
2012/08/08 16:24:20 [debug] 13885#0: *669 generic phase: 0
2012/08/08 16:24:20 [debug] 13885#0: *669 add cleanup: 00000000014972F8
2012/08/08 16:24:20 [debug] 13885#0: *669 generic phase: 1
2012/08/08 16:24:20 [debug] 13885#0: *669 test location: "/"
2012/08/08 16:24:20 [debug] 13885#0: *669 test location: "static"
2012/08/08 16:24:20 [debug] 13885#0: *669 test location: "dynamic"
2012/08/08 16:24:20 [debug] 13885#0: *669 using configuration "/"
2012/08/08 16:24:20 [debug] 13885#0: *669 http cl:-1 max:1048576
2012/08/08 16:24:20 [debug] 13885#0: *669 generic phase: 3
2012/08/08 16:24:20 [debug] 13885#0: *669 post rewrite phase: 4
2012/08/08 16:24:20 [debug] 13885#0: *669 generic phase: 5
2012/08/08 16:24:20 [debug] 13885#0: *669 add cleanup: 0000000001497330
2012/08/08 16:24:20 [debug] 13885#0: *669 generic phase: 6
2012/08/08 16:24:20 [debug] 13885#0: *669 generic phase: 7
2012/08/08 16:24:20 [debug] 13885#0: *669 access phase: 8
2012/08/08 16:24:20 [debug] 13885#0: *669 access phase: 9
2012/08/08 16:24:20 [debug] 13885#0: *669 post access phase: 10
2012/08/08 16:24:20 [debug] 13885#0: *669 try files phase: 11
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 try to use file: "/forum/styles/bastisstyle/theme/stylesheet.css" "/srv/www/wanda.eu/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 try file uri: "/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 malloc: 000000000152A140:4096
2012/08/08 16:24:20 [debug] 13885#0: *669 http init upstream, client timer: 0
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "QUERY_STRING"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "QUERY_STRING: "
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "REQUEST_METHOD"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "GET"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "REQUEST_METHOD: GET"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "CONTENT_TYPE"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "CONTENT_TYPE: "
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "CONTENT_LENGTH"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "CONTENT_LENGTH: "
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "SCRIPT_NAME"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "SCRIPT_NAME: /forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "REQUEST_URI"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "REQUEST_URI: /forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "DOCUMENT_URI"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "DOCUMENT_URI: /forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "DOCUMENT_ROOT"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "/srv/www/wanda.eu"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "DOCUMENT_ROOT: /srv/www/wanda.eu"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "SERVER_PROTOCOL"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "HTTP/1.1"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "SERVER_PROTOCOL: HTTP/1.1"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "GATEWAY_INTERFACECGI/1.1"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "GATEWAY_INTERFACE: CGI/1.1"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "SERVER_SOFTWARE"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "nginx/"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "0.7.67"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "SERVER_SOFTWARE: nginx/0.7.67"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "REMOTE_ADDR"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "95.130.252.148"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "REMOTE_ADDR: 95.130.252.148"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "REMOTE_PORT"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "62676"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "REMOTE_PORT: 62676"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "SERVER_ADDR"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "109.75.187.90"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "SERVER_ADDR: 109.75.187.90"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "SERVER_PORT"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "81"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "SERVER_PORT: 81"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "SERVER_NAME"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "www.wanda.eu"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "SERVER_NAME: www.wanda.eu"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "REDIRECT_STATUS200"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "REDIRECT_STATUS: 200"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "SCRIPT_FILENAME"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script copy: "/srv/www/wanda.eu"
2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 fastcgi param: "SCRIPT_FILENAME: /srv/www/wanda.eu/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 http cleanup add: 000000000152A9E8
2012/08/08 16:24:20 [debug] 13885#0: *669 get rr peer, try: 1
2012/08/08 16:24:20 [debug] 13885#0: *669 socket 44
2012/08/08 16:24:20 [debug] 13885#0: *669 epoll add connection: fd:44 ev:80000005
2012/08/08 16:24:20 [debug] 13885#0: *669 connect to unix:/tmp/php-cgi/php-cgi.socket, fd:44 #684
2012/08/08 16:24:20 [debug] 13885#0: *669 connected
2012/08/08 16:24:20 [debug] 13885#0: *669 http upstream connect: 0
2012/08/08 16:24:20 [debug] 13885#0: *669 http upstream send request
2012/08/08 16:24:20 [debug] 13885#0: *669 chain writer buf fl:0 s:1816
2012/08/08 16:24:20 [debug] 13885#0: *669 chain writer in: 000000000152AA20
2012/08/08 16:24:20 [debug] 13885#0: *669 writev: 1816
2012/08/08 16:24:20 [debug] 13885#0: *669 chain writer out: 0000000000000000
2012/08/08 16:24:20 [debug] 13885#0: *669 event timer add: 44: 60000:1344435920767
2012/08/08 16:24:20 [debug] 13885#0: *669 http run request: "/forum/styles/bastisstyle/theme/stylesheet.css?"
2012/08/08 16:24:20 [debug] 13885#0: *669 http upstream check client, write event:1, "/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 http upstream recv(): -1 (11: Resource temporarily unavailable)
2012/08/08 16:24:20 [debug] 13885#0: *669 http upstream request: "/forum/styles/bastisstyle/theme/stylesheet.css?"
2012/08/08 16:24:20 [debug] 13885#0: *669 http upstream process header
2012/08/08 16:24:20 [debug] 13885#0: *669 malloc: 000000000152FAB0:32768
2012/08/08 16:24:20 [debug] 13885#0: *669 recv: fd:44 12488 of 32768
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi record byte: 01
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi record byte: 06
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi record byte: 00
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi record byte: 01
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi record byte: 1F
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi record byte: F8
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi record byte: 00
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi record byte: 00
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi record length: 8184
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi parser: 0
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi header: "X-Powered-By: PHP/5.3.3-7+squeeze13"
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi parser: 0
2012/08/08 16:24:20 [debug] 13885#0: *669 http fastcgi header: "Content-type: text/html"

…. and a lot more lines, which indicate that it is sent out by nginx.

The problem is here, that the content type is set to text/html, and very clearly, the php interpreter is run for the stylesheet, which is absolutely unnecessary.

Especially these lines here throw me in for a loop:

2012/08/08 16:24:20 [debug] 13885#0: *669 http script var: "/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 try to use file: "/forum/styles/bastisstyle/theme/stylesheet.css" "/srv/www/wanda.eu/forum/styles/bastisstyle/theme/stylesheet.css"
2012/08/08 16:24:20 [debug] 13885#0: *669 try file uri: "/forum/styles/bastisstyle/theme/stylesheet.css"

nginx is looking for the correct file in the correct location, but doesn't seem to recognize it. It isn't a permission problem, as I can open the file when I su to the www-data user (which is the nginx user).

Any help here, why the server is showing this behaviour, would be greatly appreciated.

Best regards,
Jens

EDIT 1

I think I solved it by myself, although I don't have a real clue how this config is so different from the first one, and why the behaviour in the first config example was as I described it. I tried to fix another problem I had with that site, and it fixed the problems with the stylesheets as well.

Here is the config which works:

server {

  listen   81; ## listen for ipv4
  listen   [::]:81 default ipv6only=on; ## listen for ipv6

  server_name  www.wanda.eu;

  access_log  /var/log/nginx/wanda.eu.access.log;
  error_log   /var/log/nginx/wanda.eu.error.log debug;

  root /srv/www/wanda.eu;
  index index.php index.html;

  location /static {
    try_files $uri $uri/ @php_index =404;
    expires 24h;
  }

  location / {
    try_files $uri $uri/ $uri/index.html $uri/index.htm @php;
  }
  location /dynamic {
    try_files $uri $uri/ /dynamic/index.php =404;
    include /etc/nginx/fastcgi_params;
    fastcgi_index index.php;
    fastcgi_pass unix:/tmp/php-cgi/php-cgi.socket;
    fastcgi_param SCRIPT_FILENAME /srv/www/wanda.eu$fastcgi_script_name;
  }

  location @php {
    try_files $uri /index.php =404;
    include /etc/nginx/fastcgi_params;
    fastcgi_index index.php;
    fastcgi_pass unix:/tmp/php-cgi/php-cgi.socket;
   fastcgi_param SCRIPT_FILENAME /srv/www/wanda.eu$fastcgi_script_name;
  }

  location ~ \.php$ {
    try_files $uri /index.php =404;
    include /etc/nginx/fastcgi_params;
    fastcgi_index index.php;
    fastcgi_pass unix:/tmp/php-cgi/php-cgi.socket;
    fastcgi_param SCRIPT_FILENAME /srv/www/wanda.eu$fastcgi_script_name;
  }
}

Best Answer

The answer to your question is, that you told nginx to always run PHP whenever a request matches that location. No matter what kind of file it is. Let me elaborate.

location / {
    fastcgi_pass php;
}

Now anything that matches this location will be processed by PHP, no matter what.

location / {
    try_files $uri /index.php;
    fastcgi_pass php;
}

This doesn't change anything! If the $uri matches, nginx goes on and will process the fastcgi_pass php; directive. If $uri doesn't exist it will do an internal redirect to /index.php go on and process the fastcgi_pass php; directive.

location / {
    try_files $uri @php;
}
location @php {
    fastcgi_pass php;
}

Well, this changes a lot. If $uri matches there's nothing left to process, so nginx will simply return the file. If $uri doesn't match nginx will go on and see the named location @php and therefor goes to that location where it then encounters the fastcgi_pass php; directive, which it will process of course.

This should answer your specific question. You already found the solution yourself, but I thought it might be from interest to you why this is as it is.