Trouble adding /pma location to all virtual hosts

Discussion in 'Server Operation' started by cbj4074, Jun 26, 2013.

  1. cbj4074

    cbj4074 Member

    I posted the same question to the nginx mailing list, but have not received a reply.

    I'm trying to accomplish something that feels like it should be very simple, yet I'm struggling. I'm new to nginx, and I feel a bit lost as I try to "translate" everything that I've done in Apache over the years to nginx. So, please bear with me. I've done my research and asking this list for help is a last-resort.

    I have an application, phpMyAdmin, installed in /var/www/pma. I would like to modify the nginx configuration such that every virtual-host whose configuration file is located in /etc/nginx/sites-available/ has access to the files in this directory by browsing to the location /pma/, relative to the domain root.

    The filesystem information for /var/www/pma is as follows (the permissions are set recursively on the entire directory -- for now):

    Code:
    # ls -lah /var/www | grep "pma"
    drwxrwxr-x  9 www-data www-data 4.0K Jun 17 16:37 pma
    
    I figured that it might be simpler to get phpMyAdmin working for a single vhost before attempting the same move server-wide.

    On the surface, it looks to be this simple:

    Code:
    location /pma/ {
        alias /var/www/pma/;
        include /etc/nginx/fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors on;
    }
    
    When I try this configuration, I have the following in error.log:

    Code:
    2013/06/25 14:04:07 [error] 29741#0: *21 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 1.2.3.4, server: example.com, request: "GET /pma/ HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "example.com" 
    
    While researching the cause of this error, I have seen others state that SCRIPT_FILENAME has to be modified when using an alias in this way, e.g.

    fastcgi_param SCRIPT_FILENAME $request_filename;

    but the error messages are the same with this line, too.

    So, I tried to use the "root" directive, instead of "alias", as I have no particular reason for using one over the other in this scenario.

    Code:
    location /pma/ {
        #alias /var/www/pma/;
        root /var/www;
        include /etc/nginx/fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors on;
    }
    
    This "kind of works". The index file at location /pma/index.php is parsed via PHP, but requests for all other resources on the page yield "403 Forbidden". The log states:

    Code:
    2013/06/25 14:21:46 [error] 30343#0: *12 FastCGI sent in stderr: "Access to the script '/var/www/pma/favicon.ico' has been denied (see security.limit_extensions)" while reading response header from upstream, client: 1.2.3.4, server: example.com, request: "GET /pma/favicon.ico HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "example.com"
    
    Obviously, the aim here is not to execute '/var/www/pma/favicon.ico' as a PHP script.

    I found a thread at http://serverfault.com/questions/486368/nginx-and-php-fpm-403-forbidden which seems to address this intended behavior (the rationale is sound). So, I split my configuration up into the following sections, so that PHP scripts would be handled via php-fpm and static content would be handled directly:

    Code:
    location ~ /pma/.*\.php$ {
        root /var/www;
        include /etc/nginx/fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors on;
    }
    
    location /pma/ {
        root /var/www;
        # Adding the following line makes no difference:
        index index.php;
    }
    
    With this configuration, PMA's index page won't even load. The location /pma/ returns a 404, as does /pma/index.php.

    Nothing is written to the vhost's error.log when /pma/ or /pma/index.php is requested. Only the following (I've omitted the irrelevant bits) is written to access.log:

    Code:
    "GET /pma/ HTTP/1.1" 404 200 "-"
    "GET /pma/index.php HTTP/1.1" 404 200 "-"
    
    I must be doing something completely asinine.

    Other misc. details:

    - PHP's open_basedir directive includes the path /var/www/pma.

    - nginx is executing the request as the user "web2" who is in the group "client2" (this is configured via ISPConfig).

    - The group "client2" is in the group "www-data", and /var/www/pma's user:group is www-data:www-data and the permissions on the directory are 0775, recursively.

    Thanks in advance for any help here!
     
  2. cbj4074

    cbj4074 Member

    I was able to accomplish my objective with some help from the tutorial at: http://www.howtoforge.com/running-phpmyadmin-on-nginx-lemp-on-debian-squeeze-ubuntu-11.04

    Code:
    location /pma {
       root /var/www/;
       index index.php index.html index.htm;
       location ~ ^/pma/(.+\.php)$ {
           try_files $uri =404;
           root /var/www/;
           fastcgi_pass unix:/var/run/php5-fpm.sock;
           fastcgi_param HTTPS on;
           fastcgi_index index.php;
           fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
           include /etc/nginx/fastcgi_params;
       }
       location ~* ^/pma/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
           root /var/www/;
       }
    }
    location /PMA {
           rewrite ^/* /pma last;
    }
    
    I don't know if the key is the nested location block, or something else. If anyone is able to point-out the fundamental differences between the configuration snippet that I posted previously and the snippet above, which actually works, I would be most appreciative.

    Thank you!
     
  3. cbj4074

    cbj4074 Member

    More and more questions... :confused:

    So, now that PMA functions as expected, I am hoping to achieve the same with Roundcube webmail.

    In theory, I should be able to use nearly the same configuration directives. The only difference between PMA and Roundcube is that the request directory and the filesystem directory share the same name (I chose "pma") for PMA, but for Roundcube, I want to use "/webmail" for the location and "roundcube" on the filesystem.

    To better illustrate:

    Code:
    LOCATION -> FILESYSTEM PATH
    ------------------------------------
    /pma -> /var/www/pma
    /webmail -> /var/www/roundcube
    
    My limited understanding of nginx dictates that the Roundcube case calls for the use of the alias directive, as opposed to the root directive.

    So, I tried replacing "pma" with "webmail" in each location's first line, and replacing root /var/www/ with alias /var/www/roundcube/ within each location's body.

    This didn't work. I receive a 404 when requesting the /webmail URL, with no errors logged (just standard 404s in the vhost's access.log).

    I diddled with adding the regex capture groups to the end of the alias and such, but this didn't seem to change the behavior.

    Here's where I gave-up:

    Code:
    location /webmail {
        alias /var/www/roundcube/;
        index index.php index.html index.htm;
        location ~ ^/webmail/(.+\.php)$ {
            try_files $uri =404;
            alias /var/www/roundcube/$1;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_param HTTPS on;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            # Using the below line instead of the above didn't seem to change anything.
            #fastcgi_param SCRIPT_FILENAME $request_filename;
            include /etc/nginx/fastcgi_params;
        }
        location ~* ^/webmail/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
            alias /var/www/roundcube/$1;
        }
    }
    location /WEBMAIL {
        rewrite ^/* /webmail last;
    }
    
    Any help is much appreciated!

    UPDATE: This is the kind of thing that makes one want to drink to excess. After searching the darkest corners of my brain, I remembered reading in the nginx Documentation, "Note that there is a longstanding bug that alias and try_files don't work together." So, I commented-out the try_files line and everything worked!
     
    Last edited: Jun 26, 2013

Share This Page