简体   繁体   中英

nginx - serving backend and frontend on different endpoints and same domain

I have installed nginx on OS X with php7.1 , mysql and so on... and the basic testing example is working.

When I try to configure nginx to serve Laravel backend on user.domain.dev/api/... and Angular frontend on user.domain.dev/... I am getting 404 or 403 . Nginx error log is mostly

/Users/name/Projects/domain.dev/api.domain.dev/" is forbidden

or

/Users/name/Projects/domain.dev/frontend.domain.dev/build/index.php" failed (2: No such file or directory)

I can't seem to understand nginx's location directive and so they're pointing to a wrong directories. Thanks for any advices or guidance.

My config is:

nginx.conf

user name staff;  
worker_processes auto;

events {  
    worker_connections  1024;
}

http {  
    include mime.types;
    default_type application/octet-stream;

    ssl_certificate ssl/nginx.crt;
    ssl_certificate_key ssl/nginx.key;

    access_log /usr/local/var/log/nginx/access.log;
    error_log /usr/local/var/log/nginx/error.log;

    sendfile on;
    keepalive_timeout 5;

    gzip  on;

    include servers/*.conf;
}

servers/domain.dev.conf

server {
    listen 80;
    listen 443 ssl http2 default_server;

    server_name domain.dev *.domain.dev www.domain.dev;

    charset utf-8;

    # removes trailing slashes (prevents SEO duplicate content issues)

    if (!-d $request_filename)
    {
        rewrite ^/(.+)/$ /$1 permanent;
    }

    # enforce NO www

    if ($host ~* ^www\.(.*))
    {
        set $host_without_www $1;
        rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
    }

    ##
    ## Backend HTTP server
    ##

    location /api {

        root /Users/name/Projects/domain.dev/api.domain.dev;
        index index.php;

        try_files $uri $uri/ /index.php?$query_string;

        location ~ \.php$ {
                    fastcgi_pass 127.0.0.1:9000;
                    fastcgi_split_path_info ^(.+\.php)(/.+)$;
                    try_files $fastcgi_script_name =404;
                    fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                    include fastcgi.conf;
            }
    }

    ##
    ## Frontend HTTP server
    ##

    location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
        access_log off;
        expires max;
    }

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

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

    location / {
        root /Users/name/Projects/domain.dev/frontend.domain.dev/build;
        index index.html;
    }

    location ~ /\. {
        deny all;
    }
}

The main problem is an inconsistent use of the root directive. You have two document roots, one for each application, but only specified in two of your locations. There is no root specified at the server { ... } block level, therefore if (!-d $request_filename) is meaningless, location ~* \\.(jpg|jpeg|gif|css|png|js|ico|html)$ will always result in a 404 response, etc.

Read this document to understand how nginx processes a request.

But you should probably set the frontend root in the server block and override it with the backend root in the location /api block.

server {
    root /Users/name/Projects/domain.dev/frontend.domain.dev/build;

    location / { ... }
    location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ { ... }

    location ^~ /api {
        root /Users/name/Projects/domain.dev/api.domain.dev;
        ...
    }
}

This would place the backend document root at: /Users/name/Projects/domain.dev/api.domain.dev/api -- note that the URI is always appended to the root .

Note also, the ^~ modifier is used to make the prefix location take precedence over regular expression locations at the same level. See this document for details.

I do not like the naked if blocks in your design. The if (!-d $request_filename) should probably be replaced with a try_files directive , and if ($host ~* ^www\\.(.*)) should probably be replaced by using a separate server block. See this document for more.

The try_files statement in your location /api block contains an incorrect default URI, it should probably be /api/index.php?$query_string .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM