Kennedy
Kennedy

Reputation: 77

Emulating Apache Directory Alias on Nginx

With Apache we can do something like this:

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/app1/public
        <Directory />
                Options +Indexes +FollowSymLinks +MultiViews
                AllowOverride FileInfo
                Require all granted
        </Directory>

        Alias /app2 "/var/www/app2/public"
        <Directory "/var/www/app2/public">
                DirectoryIndex index.php
                Options +Indexes +FollowSymLinks +MultiViews
                AllowOverride All
                Require all granted
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log
        # Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
        LogLevel warn
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

So, in this approach I have two different applications:

Both was developed with Laravel (PHP Framework) and need to receive QUERY STRING to work.

I wanna move to Nginx and currently my config is this:

server {

    listen 80;
    server_name host.com;
    root /var/www/app1/current/public;

    index index.php;
    charset utf-8;

    # App 1
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ ^/index\.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/app.log error;

    sendfile off;
    client_max_body_size 100m;

    location ~ /\.ht {
        deny all;
    }
}

The app1 (root application) works fine. The issue is: How can I set the app2 in that config file?

I've tried:

# App 2
location ^~ /app2 {
    alias /var/www/app2/current/public;
    try_files $uri $uri/ /index.php?$query_string;
}

But, without success.

Upvotes: 2

Views: 3666

Answers (2)

Kennedy
Kennedy

Reputation: 77

For those who did not understand exactly what I want: I need to host multiple PHP applications on the same domain name (without subdomain).

I finally solved the problem. This is my final configuration:

server {

    listen 80 deferred;

    server_name server.com;
    index index.php;
    charset utf-8;

    # App 1 (main app)
    location / {
        root /var/www/app1/current/public;
        try_files $uri $uri/ /index.php?$query_string;

        error_log /var/log/nginx/app1.notice.log notice;
        error_log /var/log/nginx/app1.error.log error;

        location ~* ^/index\.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME /var/www/app1/current/public/index.php;
            fastcgi_intercept_errors off;
            fastcgi_buffer_size 16k;
            fastcgi_buffers 4 16k;
        }
    }

    # App 2
    location ~* /app2 {
        alias /var/www/app2/current/public;
        try_files $uri $uri/ /app2/index.php?$query_string;

        error_log /var/log/nginx/app2.notice.log notice;
        error_log /var/log/nginx/app2.error.log error;

        location ~* ^/app2/index\.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME /var/www/app2/current/public/index.php;
            fastcgi_intercept_errors off;
            fastcgi_buffer_size 16k;
            fastcgi_buffers 4 16k;
        }
    }

    # Files
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    # Error
    access_log off;
    rewrite_log on;

    # Disable .htaccess access
    location ~ /\.ht {
        deny all;
    }
}

Upvotes: 1

fideloper
fideloper

Reputation: 12293

Few things I'd try.

# App 2
# Possibly no need for regex, this will capture urls 
# /app2 and /app2/anything/else
location /app2 {
    alias /var/www/app2/current/public;
    try_files $uri $uri/ /index.php?$query_string;
}

That might be your only issue and could possibly fix it.

However! If there are still issues (no input file error, or if it goes to app1 still), then we have the complicating factor of using /index.php with try_files. That makes it go on down to your location ~ ^/index\.php$ { block, which is probably grabbing the wrong $document_root.

In this case, I'm not sure if the best thing would be to not use an alias, and instead use two PHP blocks. Hopefully alias takes care of changing $documentroot automagically.

Upvotes: 1

Related Questions