Question

How to deploy 2 node express api (One for test and one for production) on two different subdomains with nginx and pm2?

Posted November 3, 2021 102 views
NginxNode.js

I am trying to deploy two node application on two subdomains. One subdomain is for production and another one is for testing development updates. I have created a directory webapps/myapp/pro in my home directory. Then i pull production builds into webapps/myapp/pro/dist and development builds into webapps/myapp/pro/dev. nginx configuration for production in sites-available is -

server {
#    return 301 https://$host$request_uri;
        root /home/user/webapps/myapp/pro/dist/browser;
        index index.html index.htm index.nginx-debian.html;

    server_name www.pro.mydomain.com pro.mydomain.com;


location /api0/ {
        proxy_pass http://localhost:5000;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Proto $scheme;
}

    location /api1/ {
        proxy_pass http://localhost:7000;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
  proxy_set_header X-NginX-Proxy true;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Proto $scheme;

# ALLOW CORS ORIGIN SITES
        add_header "Access-Control-Allow-Credentials" "true";
    }


    location /localStorage/ {
        alias /home/user/webapps/myapp/pro/localStorage/;


        # ALLOW CORS ORIGIN SITES
        #add_header "Access-Control-Allow-Origin" "*";
        #add_header "Access-Control-Allow-Credentials" "true";
        #add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
        #add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";

    }



    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mydomain.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.pro.mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80  ;
    server_name www.pro.mydomain.com pro.mydomain.com;


}

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



    server_name www.pro.example.com pro.mydomain.com;
    listen 80;
    return 404; # managed by Certbot


}

And nginx configuration for development in sites-available is -

server {
#    return 301 https://$host$request_uri;
        root /home/user/webapps/myapp/pro/dev/browser;
        index index.html index.htm index.nginx-debian.html;

    server_name www.dev.mydomain.com dev.mydomain.com;


location /api0/ {
        proxy_pass http://localhost:5001;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Proto $scheme;
}

    location /api1/ {
        proxy_pass http://localhost:7001;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
  proxy_set_header X-NginX-Proxy true;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Proto $scheme;

# ALLOW CORS ORIGIN SITES
        add_header "Access-Control-Allow-Credentials" "true";
    }


    location /localStorage/ {
        alias /home/user/webapps/myapp/pro/localStorage/;


        # ALLOW CORS ORIGIN SITES
        #add_header "Access-Control-Allow-Origin" "*";
        #add_header "Access-Control-Allow-Credentials" "true";
        #add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
        #add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";

    }



    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mydomain.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.dev.mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80  ;
    server_name www.dev.mydomain.com dev.mydomain.com;


}

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



    server_name www.dev.example.com dev.mydomain.com;
    listen 80;
    return 404; # managed by Certbot


}

Then i start api apps with pm2 for production like this -

cd webapps/myapp/pro/dist
pm2 start app1.js
pm2 start app2.js

And started api apps with pm2 for development like this -

cd webapps/myapp/pro/dev
pm2 start app1.js
pm2 start app2.js

I checked the netstat and the application are running on correct ports. i.e, 5000, 5001, 7000 and 7001.

Now, when i run just the production server it runs without any issue. It works as expected. But when i start development server along with production server, The first page of the Application works fine and it fetches all the data as expected from both apis (API1 and API2). But when i click some buttons to fetch some collections from the API it throws a 502 error.

I checked the nginx log and i found this error -

connect() failed (111: Connection refused) while connecting to upstream, client: client.ip, server: my.server, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:3000/", host: "my.server"

How does the connection established for some requests but fails for other?

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

×
Submit an Answer
1 answer

Hello,

The setup looks correct I believe. However the error indicates that there should be a service listening on port 3000, is this the case?

If there is no service listening on that port, then you would need to adjust your reverse proxy configuration to match the port that the service is listening on.

Also, keep in mind that you can not have multiple services listening on the same ports. So you would need to make sure that your Dev and Prod applications are running on different ports.

Regards,
Bobby