VividDreams
VividDreams

Reputation: 93

Nginx multiple node apps with multiple subdomains

I have a private VPS and want to host multiple node apps (or static websites) based on subdomain using nginx.

I want to achieve something like this:

johndoe.com -> node app 1 (port 5000)
blog.johndoe.com -> node app 2 (port 5001)
statichtml.johndoe.com -> static html from defined path

Right now I have this kind of config in sites-available/default file.

server {
    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;
    server_name www.johndoe.com johndoe.com; # managed by Certbot


    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        proxy_pass http://localhost:5000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
    }


    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/johndoe.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/johndoe.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = www.johndoe.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = johndoe.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80 ;
    listen [::]:80 ;
    server_name www.johndoe.com johndoe.com;
    return 404; # managed by Certbot
}

Right now on johndoe.com, the app from port:5000 is hosted and it works correct. When I enter subdomain like blog.johndoe.com it also works at the same port. I want to specify another port for this subdomain or even serve static pages. It looks like no matter what subdomain I use, it is always using default "/" location. How to achieve this?

Upvotes: 4

Views: 6245

Answers (1)

Ivan Shatsky
Ivan Shatsky

Reputation: 15697

One of the available server blocks for each listening port/network interface always acts as the default sever capturing all the incoming requests on that port/interface no matter of HTTP Host header value. The default server can be defined explicitly with the default_server flag of the listen directive otherwise it would be the first server block listening on that IP/port combination. Read this documentation page to find the details.

As of now your only server block listening on port 80 acts as the default server block serving any HTTP request no matter is it contains johndoe.com, blog.johndoe.com, statichtml.johndoe.com or any other Host header (or if it contains the Host header at all). Here is a configuration you can use for your particular example:

# server blocks for incoming HTTP requests
server {
    # server block for 'johndoe.com', 'www.johndoe.com' domains
    listen 80;
    listen [::]:80;
    server_name johndoe.com www.johndoe.com;
    # redirect any HTTP request to HTTPS
    return 301 https://$http_host$request_uri;
}
server {
    # server block for 'blog.johndoe.com' domain
    listen 80;
    listen [::]:80;
    server_name blog.johndoe.com;

    location / {
        proxy_pass http://localhost:5001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
server {
    # server block for 'statichtml.johndoe.com' domain
    listen 80;
    listen [::]:80;
    server_name statichtml.johndoe.com;
    root /your/root/path;
    index index.html index.htm;
    location / {
        try_files $uri $uri/ =404;
    }
}
server {
    # server block for all the other requests
    # this block will be a default server block listening on port 80
    listen 80 default_server;
    listen [::]:80 default_server;
    # close the connection immediately
    return 444;
}

# server blocks for incoming HTTPS requests
server {
    # server block for 'johndoe.com', 'www.johndoe.com' domains
    listen [::]:443 ssl;
    listen 443 ssl;
    server_name johndoe.com www.johndoe.com;

    # SSL configuration by certbot
    ssl_certificate /etc/letsencrypt/live/johndoe.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/johndoe.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Upvotes: 6

Related Questions