Setup NGINX with Nodejs - PART 2

Setup NGINX with Nodejs - PART 2

Configuring NGINX Continues…

Next, we will configure the server block to suit our needs. We want to configure NGINX to pass all requests through to our Nodejs server API. Replace the server block which is explained in PART1 with a new block as given below:

http {
    include / etc / nginx / mime.types;
    default_type application / octet - stream;
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /
        var / log / nginx / access.log main;
    sendfile on;

    #tcp_nopush on;
    keepalive_timeout 65;

    #gzip on;
    upstream < DOCKER_CONTAINER_NAME > {
        server < DOCKER_CONTAINER_NAME >: <PORT_NUMBER > ;
    }
    include / etc / nginx / conf.d /*.conf;
    server{
        server_name <SERVER_HOST_IP>;
        listen <HOST_PORTNUMBER> ssl;
        ssl_certificate /etc/ssl/<CACERTIFICATE_WITH_EXTENSION>;
        ssl_certificate_key /etc/ssl/<PRIVATEKEY_WITH_EXTENSION>;
        ssl_dhparam /etc/ssl/<PEMFILE_WITH_EXTENSION>;
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
        ssl_prefer_server_ciphers on;

        #change to override default header size (8k) to 64k for Cookie too large issuelarge_client_header_buffers 8 2048k;
        client_max_body_size 9M;

        # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
        ssl_trusted_certificate /etc/ssl/<CACERTIFICATE_WITH_EXTENSION>;

        #Security hardening settingsserver_tokens off;
        add_header X-Frame-Options SAMEORIGIN;
        add_header X-Content-Type-Options nosniff;

        #Do not release header information unnecessarilyproxy_hide_header X-Powered-By;
        proxy_hide_header X-Generator;

        # Enable XSS protectionadd_header X-XSS-Protection "1; mode=block";
        set $domain $1;
        location ~ proxy {
            return 403;
        }
        location / {
            proxy_pass http://<DOCKER_CONTAINER_NAME>/;
            proxy_redirect http://<DOCKER_CONTAINER_NAME>/ /;
            proxy_read_timeout 720s;
            proxy_cookie_path ~^/auth/.*$ /;

            # May not need or want to set Host. Should default to the above hostname.
            proxy_set_header          Host            $host;
            proxy_set_header          X-Real-IP       $remote_addr;
            proxy_set_header          X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

As you can see, the web server will listen on http://localhost port 443. The location / block tells NGINX what to do with any incoming request. We use proxy_pass to point to our Nodejs API, which is running at http://localhost:3000 in our case.

Now, if you access https://localhost, your connection will be secure. The configuration above assumes that the certificate and private key are located at /etc/nginx/ssl/servercertificate.crt and /etc/nginx/ssl/serverkey.key respectively, but you can change these locations if you wish.


Setting up Docker for your deployment

As, Iam using node version as 10 for this deployment, you can use latest version of node or which ever is greater and that supports to you.

Create a working directory as usr/src/app , then copy your package.json like dependency stuffs and initial RUN npm install . Finally your Dockerfile will look like as mentioned below,

FROM node:10

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "run", "start"]

Iam using docker version as 3.1 , here we use apline as nginx’s image with my container name as <CONTAINER_NAME> . Your docker-compose.yml file will look like as mentioned below,

version: <DOCKER_VERSIONNUMBER>
services:
   <IMAGE_NAME>:
      image: "nginx:alpine"
      depends_on:
      - <CONTAINER_NAME>
      restart: always
      ports:
      - <ACCESSING_PORTNUMBER>:<DEPLOYED_PORTNUMBER>
      volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs/ssl:/etc/ssl:z

   <IMAGE_NAME>:
      container_name: <CONTAINER_NAME>
      build:
      context: .
      ports:
      - '<ACCESSING_PORTNUMBER>:<DEPLOYED_PORTNUMBER>'
      restart: always

Conclusion

Finally, we had seen how to use NGINX as a reverse proxy for our Nodejs API and configure SSL. By using NGINX to handle the static resources, you can also take some load off your Node application.