متعدد طریقے ہیں جن سے آپ اپنی نوڈج ایپ کو تعینات کر سکتے ہیں، چاہے وہ آن کلاؤڈ ہو یا آن پریمیسس۔ تاہم، یہ صرف آپ کی درخواست کو تعینات کرنے کے بارے میں نہیں ہے بلکہ اسے صحیح طریقے سے تعینات کرنا ہے۔ سیکیورٹی بھی ایک اہم پہلو ہے جس کو نظر انداز نہیں کیا جانا چاہیے، اور اگر آپ ایسا کرتے ہیں تو ایپلیکیشن زیادہ دیر تک قائم نہیں رہے گی اور اس سے سمجھوتہ کیے جانے کا بہت زیادہ امکان ہے۔ لہذا، یہاں ہم آپ کی مدد کرنے کے لیے ہیں Nodejs ایپ کو AWS میں تعینات کرنے کے لیے۔ ہم آپ کو بالکل دکھائیں گے کہ کس طرح نوڈجز ایپ کو سرور پر ڈوکر کنٹینرز، RDS Amazon Aurora، Nginx کے ساتھ HTTPS کے ساتھ تعینات کیا جائے، اور ڈومین نام کا استعمال کرتے ہوئے اس تک رسائی حاصل کی جائے۔ فہرست کا خانہ ٹول اسٹیک - آرکیٹیکچر: Docker کنٹینر، RDS Amazon Aurora، Nginx کے ساتھ HTTPS کا استعمال کرتے ہوئے ec2 سرور پر Nodejs ایپ تعینات کریں، اور ڈومین نام کا استعمال کرتے ہوئے اس تک رسائی حاصل کریں۔ - شرائط - AWS پر Ubuntu 20.04 LTS EC2 مثال بنائیں - AWS پر MySql مثال کے ساتھ ایک RDS Aurora بنائیں - EC2 مثال پر انحصار انسٹال کریں۔ - Nodejs ایپ کو AWS EC2 مثال میں ایک Docker کنٹینر، RDS Amazon Aurora، Nginx کے ساتھ HTTPS کا استعمال کرتے ہوئے تعینات کریں، اور ڈومین نام کا استعمال کرتے ہوئے اس تک رسائی حاصل کریں۔ - Nodejs ایپ کو AWS میں کیسے تعینات کیا جائے اس کے بعد کیا ہے؟ - نتیجہ اخذ کرنا - اکثر پوچھے گئے سوالات == ٹول اسٹیک == **نوڈج نمونہ ایپ** ایک نمونہ نوڈج ایپ جس میں 3 APIs یعنی اسٹیٹس، داخل اور فہرست ہے۔ یہ APIs ایپ کی حیثیت کو چیک کرنے، ڈیٹا بیس میں ڈیٹا داخل کرنے اور بازیافت کرنے کے لیے استعمال کیے جائیں گے۔& ڈیٹا بیس سے ڈیٹا ڈسپلے کریں۔ **AWS EC2 مثال** ایک Ubuntu 20.04 LTS Amazon Elastic Compute Cloud (Amazon EC2) مثال کنٹینرائزڈ Nodejs ایپ کو تعینات کرنے کے لیے استعمال کیا جائے گا۔ ہم اس مثال میں ڈوکر انسٹال کریں گے جس کے اوپر کنٹینرز بنائے جائیں گے۔ ہم مثال کے طور پر MySql کلائنٹ بھی انسٹال کریں گے۔ ایک مطلوبہ ٹیبل بنانے کے لیے MySql کلائنٹ کو ارورہ انسٹینس سے جڑنے کی ضرورت ہے۔ **AWS RDS Amazon Aurora** ہمارا ڈیٹا AWS RDS Amazon Aurora میں محفوظ کیا جائے گا۔ ہم سادہ فیلڈز جیسے صارف نام، ای میل آئی ڈی اور عمر کو AWS RDS Amazon Aurora Instance میں اسٹور کریں گے۔ Amazon Aurora ایک MySQL اور PostgreSQL ہم آہنگ رشتہ دار ڈیٹا بیس ہے جو AWS پر دستیاب ہے **ڈوکر** ڈوکر ایک کنٹینرائزیشن پلیٹ فارم ہے جو ڈوکر امیجز بنانے اور کنٹینرز کا استعمال کرتے ہوئے ان کو تعینات کرتا ہے۔ ہم Nodejs ایپ کو سرور، Nginx، اور Certbot پر ڈاکر کنٹینرز کے طور پر تعینات کریں گے **ڈوکر کمپوز** Nodejs، Nginx، Certbot کنٹینرز کو گھمانے کے لیے، ہم Docker-compose استعمال کریں گے۔ ڈوکر کمپوز کنٹینر کی تعیناتی اور انتظامی وقت کو کم کرنے میں مدد کرتا ہے۔ **نگینکس** اس کا استعمال نمونہ نوڈجز ایپ کے لیے HTTPS کو فعال کرنے اور صارف کی تمام درخواستوں کو Nodejs ایپ پر بھیجنے کے لیے کیا جائے گا۔ یہ صارف کی درخواستوں کو ایپلی کیشن میں ری ڈائریکٹ کرنے کے لیے ایک ریورس پراکسی کے طور پر کام کرے گا اور SSL/HTTPS کو فعال کرنے کے لیے کنفیگریشن فراہم کر کے کنکشن کو محفوظ بنانے میں بھی مدد کرے گا۔ **Certbot** یہ ہمیں ڈومین کی توثیق اور SSL سرٹیفکیٹ جاری کرنے کے لیے خود بخود LetâÃÂÃÂs Encrypt استعمال کرنے کے قابل بنائے گا۔ **ڈومین** دستاویز کے اختتام پر، آپ HTTPS پر اپنے ڈومین نام کا استعمال کرتے ہوئے نمونہ Nodejs ایپلیکیشن تک رسائی حاصل کر سکیں گے، یعنی آپ کے نمونے Nodejs کو انٹرنیٹ پر محفوظ کر لیا جائے گا۔ **ڈاکیا** ہم اپنے APIs کی جانچ کرنے کے لیے پوسٹ مین کا استعمال کریں گے، یعنی اسٹیٹس چیک کرنے، ڈیٹا داخل کرنے، اور ڈیٹا بیس سے ڈیٹا کی فہرست بنانے کے لیے جیسا کہ میں نے کہا، ہم Docker کنٹینرز، RDS Amazon Aurora، Nginx کے ساتھ HTTPS کا استعمال کرتے ہوئے Nodejs ایپ کو سرور پر تعینات کریں گے، اور ڈومین نام کا استعمال کرتے ہوئے اس تک رسائی حاصل کریں گے۔ Â، آئیے سب سے پہلے فن تعمیر کو سمجھیں اس سے پہلے کہ ہم اپنا ہاتھ پکڑیں == فن تعمیر: Docker کنٹینر، RDS Amazon Aurora، Nginx کے ساتھ HTTPS کا استعمال کرتے ہوئے ec2 سرور پر Nodejs ایپ تعینات کریں، اور ڈومین نام کا استعمال کرتے ہوئے اس تک رسائی حاصل کریں == Docker کا استعمال کرتے ہوئے ec2 مثال میں Nodejs ایپ کو تعینات کریں پورٹ 3000 پر دستیاب ہوگا۔ یہ نمونہ Nodejs ایپ RDS Amazon Aurora مثال سے ڈیٹا حاصل کرتا ہے جو EC2 مثال کے طور پر اسی VPC میں بنایا گیا ہے۔ ایک Amazon Aurora DB مثال نجی ہوگی اور اسی وجہ سے اسی VPC میں قابل رسائی ہوگی۔ EC2 مثال پر تعینات Nodejs ایپلیکیشن کو پورٹ 3000 پر اس کے عوامی IP کا استعمال کرتے ہوئے رسائی حاصل کی جا سکتی ہے، لیکن ہم یہ نہیں کر سکیں گے۔ غیر معیاری بندرگاہوں پر ایپلیکیشنز تک رسائی کی سفارش نہیں کی جاتی ہے، اس لیے ہمارے پاس Nginx ہوگا جو ریورس پراکسی کے طور پر کام کرے گا اور SSL ختم کرنے کو فعال کرے گا۔ صارفین ڈومین نام کا استعمال کرتے ہوئے درخواست تک رسائی حاصل کرنے کی کوشش کریں گے اور یہ درخواستیں Nginx کو بھیج دی جائیں گی۔ Nginx درخواست کی جانچ کرے گا اور API کی بنیاد پر، یہ اس درخواست کو نوڈج ایپ پر بھیج دے گا۔ ایپلیکیشن کو SSL کے ساتھ بھی ختم کر دیا جائے گا، اس کے نتیجے میں کلائنٹ اور سرور کے درمیان رابطہ محفوظ اور محفوظ ہو جائے گا۔ یہاں آرکیٹیکچر ڈایاگرام ہے جو AWS پر نوڈج ایپ کی تعیناتی کی وضاحت دیتا ہے == شرطیں == اس سے پہلے کہ ہم Nodejs ایپ کو AWS میں تعینات کرنے کے لیے آگے بڑھیں، یہ فرض کیا جاتا ہے کہ آپ کے پاس پہلے سے ہی درج ذیل شرائط موجود ہیں - AWS اکاؤنٹ - APIs کو جانچنے کے لیے آپ کی مشین پر پوسٹ مین یا کوئی دوسرا متبادل - آپ کے AWS اکاؤنٹ میں ایک رجسٹرڈ ڈومین == AWS پر ایک Ubuntu 20.04 LTS EC2 مثال بنائیں == httpsAWS.amazon.com/console/ پر جائیں اور اپنے اکاؤنٹ میں لاگ ان کریں۔ اپنے اکاؤنٹ میں کامیابی سے لاگ ان ہونے کے بعد، سرچ بار میں کلک کریں اور EC2 تلاش کریں۔ EC2 مثال بنانے کے لیے EC2 ڈیش بورڈ پر جانے کے لیے نتیجہ پر کلک کریں۔ یہاں، EC2 مثال کو ترتیب دینے اور بنانے کے لیے âÃÂÃÂلانچ انسٹینسز پر کلک کریں۔ âÃÂÃÂUbuntu Server 20.04 LTSâÃÂàAMI میں آپ کو صرف ٹیسٹ کے مقاصد کے لیے t3.small کو منتخب کرنے کی سفارش کروں گا، اس میں 2 CPUs اور 2GB RAM ہوگی۔ آپ اپنی ضرورت اور پسند کے مطابق مثال کی قسم کا انتخاب کرسکتے ہیں۔ آپ پہلے سے طے شدہ ترتیبات کو برقرار رکھ سکتے ہیں اور آگے بڑھ سکتے ہیں۔ یہاں، میں نے پہلے سے طے شدہ VPC منتخب کیا ہے، اگر آپ چاہیں تو آپ اپنا VPC منتخب کر سکتے ہیں۔ ایک نوٹ کریں کہ، یہاں میں پبلک سب نیٹ میں ایک مثال بناؤں گا۔ 30GB پر ڈسک کی بڑی جگہ رکھنا بہتر ہے۔ باقی پہلے سے طے شدہ ہوسکتے ہیں۔ ایک âÃÂÃÂنام تفویض کریں اپنی پسند کی کسی بھی قدر کو ٹیگ کریں۔ آپ اس قدم کو چھوڑ بھی سکتے ہیں۔ صرف اپنے آئی پی سے پورٹ 22 سے کنکشن کی اجازت دیں۔ اگر آپ اسے 0.0.0.0/0 سے اجازت دیتے ہیں، تو آپ کی مثال پورٹ 22 پر کسی کو بھی اجازت دے گی۔ ایک بار کنفیگریشن کا جائزہ لیں، اور ایک مثال بنانے کے لیے اگر سب کچھ ٹھیک لگتا ہے تو لانچ کریں پر کلک کریں۔ اس سے پہلے کہ مثال بن جائے، اسے کلیدی جوڑے کی ضرورت ہے۔ آپ یا تو ایک نیا کلیدی جوڑا بنا سکتے ہیں یا موجودہ کو استعمال کر سکتے ہیں۔ âÃÂÃÂLunch instancesâÃÂàبٹن پر کلک کریں جو مثال کی تخلیق کا آغاز کرے گا۔ کنسول پر جانے کے لیے اور اپنی مثال چیک کرنے کے لیے، âÃÂÃÂدیکھیں مثال کے بٹن پر کلک کریں یہاں، آپ دیکھ سکتے ہیں کہ مثال بنائی گئی ہے اور âÃÂÃÂInitiatingâÃÂàمرحلے میں ہے۔ ایک یا 2 منٹ کے اندر، آپ اپنی مثال کو اوپر اور چلتے ہوئے دیکھ سکتے ہیں۔ دریں اثنا، آئیے ایک RDS مثال بنائیں == AWS پر MySql مثال کے ساتھ RDS Aurora بنائیں == صفحہ کے اوپری حصے میں سرچ بار پر دوبارہ کلک کریں اور اس بار âÃÂÃÂRDSâÃÂàتلاش کریں۔ RDS ڈیش بورڈ پر جانے کے لیے نتیجہ پر کلک کریں۔ RDS ڈیش بورڈ پر، RDS مثال کو ترتیب دینے اور تخلیق کرنے کے لیے âÃÂÃÂCreate databaseÃÂÃÂàبٹن پر کلک کریں۔ âÃÂÃÂEasy createâÃÂàطریقہ منتخب کریں، âÃÂÃÂAmazon Auroraâà àانجن کی قسم، âÃÂÃÂDev/TestâÃÂàDB انسٹینس سائز حسب ذیل تھوڑا سا نیچے سکرول کریں اور âÃÂÃÂDB کلسٹر شناخت کنندہ کی وضاحت کریں ڈیٹا بیس۔ آپ اپنی پسند کا کوئی بھی نام بتا سکتے ہیں کیونکہ یہ صرف ایک نام ہے جو RDS مثال کو دیا گیا ہے۔ تاہم، میں وہی نام استعمال کرنے کا مشورہ دوں گا تاکہ اگلے مراحل پر عمل کرتے ہوئے آپ کو الجھن نہ ہو۔ اس کے علاوہ، ایک ماسٹر صارف نام بطور âÃÂÃÂadminâÃÂÃÂ، اس کا پاس ورڈ، اور پھر âÃÂà پر کلک کریں ڈیٹا بیس بنائیں یہ RDS Amazon Aurora Instance کی تخلیق کا آغاز کرے گا۔ ایک نوٹ کریں کہ پروڈکشن یا لائیو ماحول کے لیے، آپ کو سادہ صارف نام اور پاس ورڈ سیٹ نہیں کرنا چاہیے۔ یہاں، آپ دیکھ سکتے ہیں کہ مثال âÃÂÃÂCreatingâÃÂàحالت میں ہے۔ تقریباً 5-10 منٹوں میں، آپ کو مثال کے طور پر تیار ہونا چاہیے۔ یہاں چند نوٹ بنائیں: - RDS Amazon Aurora مثال بطور ڈیفالٹ نجی ہوگی، جس کا مطلب ہے کہ RDS Amazon Aurora مثال بیرونی دنیا سے قابل رسائی نہیں ہوگی اور صرف VPC کے اندر دستیاب ہوگی۔ - EC2 مثال اور RDS مثال ایک ہی VPC سے تعلق رکھتے ہیں۔ - RDS مثال EC2 مثال سے قابل رسائی ہے۔ == EC2 مثال == پر انحصار انسٹال کریں۔ اب، آپ ہماری تخلیق کردہ مثال سے منسلک ہو سکتے ہیں۔ میں مثال سے منسلک ہونے کے بارے میں تفصیلات میں نہیں جاؤں گا اور مجھے یقین ہے کہ آپ اسے پہلے ہی جانتے ہیں۔ مائی ایس کیو ایل کلائنٹ ہمیں RDS Amazon Aurora مثال سے جڑنے اور اس میں ڈیٹا بیس بنانے کے لیے ایک MySQL کلائنٹ کی ضرورت ہوگی۔ EC2 مثال سے جڑیں اور اس سے درج ذیل کمانڈز پر عمل کریں۔ - sudo apt اپ ڈیٹ - sudo apt mysql-client انسٹال کریں۔ ایک ٹیبل بنائیں ہمیں اپنے ایپلیکیشن ڈیٹا کو ذخیرہ کرنے کے لیے اپنے RDS Amazon Aurora مثال میں ایک ٹیبل کی ضرورت ہوگی۔ ٹیبل بنانے کے لیے، MySQL کلائنٹ کا استعمال کرتے ہوئے Amazon RDS Aurora مثال سے جڑیں جسے ہم نے پچھلے مرحلے میں EC2 مثال پر انسٹال کیا تھا۔ ایمیزون ارورہ مثال سے ڈیٹا بیس اینڈ پوائنٹ کو کاپی کریں۔ درج ذیل کامن کو درست اقدار کے ساتھ انجام دیں۔ - mysql -u -p -h Here, my command looks as follows - mysql -u admin -padmin1234 -h my-Nodejs-database.cluster-cxxjkzcl1hwb.eu-west-3.rds.amazonAWS.com Once you get connected to the Amazon RDS Aurora instance, execute the following commands to create a table named “users” show databases; use main; CREATE TABLE IF NOT EXISTS users(id int NOT NULL AUTO_INCREMENT, username varchar(30), email varchar(255), age int, PRIMARY KEY(id select * from users; Refer to the following screenshot to understand command executions Create an Application Directory Now, let’s create a directory where we will store all our codebase and configuration files - pwd - cd /home/ubuntu/ - mkdir Nodejs-docker - cd Nodejs-docker Clone the code repository on the EC2 instance Clone my Github Repository containing all the code. This is an optional step, I have included all the code in this document - pwd - cd /home/ubuntu/ - git clone httpsgithub.com/shivalkarrahul/DevOps.git - cp /home/ubuntu/DevOps/AWS/Nodejs-docker/* /home/ubuntu/Nodejs-docker **Note: **This is an optional step. If you copy all the files from the repository to the application directory then you do not need to create files in the upcoming steps; however, you will still need to make the necessary changes == Deploy Nodejs app to AWS EC2 instance using a Docker container, RDS Amazon Aurora, Nginx with HTTPS, and access it using the Domain Name == Docker, why use docker in your ec2 instance Docker is a containerization tool used to package our software application into an image that can be used to create Docker Containers. Docker helps to build, share and deploy our applications easily The first step of Dockerization is installing Docker Install Docker - Check Linux Version - cat /etc/issue - Update the apt package index - sudo apt-get update - Install packages to allow apt to use a repository over HTTPS - sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release - Add Docker’s official GPG key: - curl -fsSL httpsdownload.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg - Set up the stable repository - echo “deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] httpsdownload.docker.com/linux/ubuntu $(lsb_release -cs) stable” | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - Update the apt package index - sudo apt-get update - Install the latest version of Docker Engine and containerd - sudo apt-get install docker-ce docker-ce-cli containerd.io - Check Docker version - docker –version - Manage Docker as a non-root user - Create ‘docker’ group - sudo groupadd docker - Add your user to the docker group - sudo usermod -aG docker - Exit - exit - Login back to the terminal - Verify that you can run docker commands without sudo - docker run hello-world - Upon executing the above run command, you should see the output as follows - Refer to the following screenshot to see the command that I have executed Dockerize your Node.js application in the EC2 instance Once you have Docker installed, the next step is to Dockerize the app. Dockerizing a Nodejs app means writing a Dockerfile with a set of instructions to create a Docker Image Let’s create Dockerfile and a sample Nodejs app - pwd - cd /home/ubuntu/Nodejs-docker - Create Dockerfile and paste the following in it, alternatively, you can copy the content from here as well - vim Dockerfile #Base Image node:12.18.4-alpine FROM node:12.18.4-alpine #Set working directory to /app WORKDIR /app #Set PATH /app/node_modules/.bin ENV PATH /app/node_modules/.bin:$PATH #Copy package.json in the image COPY package.json ./ #Install Packages RUN npm install express --save RUN npm install mysql --save #Copy the app COPY . ./ #Expose application port EXPOSE 3000 #Start the app CMD ["node", "index.js"] - Create index.js and paste the following in it, alternatively, you can copy the content from here as well. This will be our sample Nodejs app - vim index.js const express = require('express const app = express const port = 3000; const mysql = require('mysql const con = mysql.createConnection({ host: "my-Nodejs-database.cluster-cxxjkzcl1hwb.eu-west3.rds.amazonAWS.com", user: "admin", password: "admin1234"app.getstatus', (req, res) => res.send({status: "I'm up and running app.listen(port, () => console.log(`Dockerized Nodejs Applications is listening on port ${port app.postinsert', (req, res) => { if (req.query.username && req.query.email && req.query.age) { console.log('Received an insert call con.connect(function(err) { con.query(`INSERT INTO main.users (username, email, age) VALUES req.query.username req.query.email req.query.age function(err, result, fields) { if (err) res.send(err); if (result) res.send({username: req.query.username, email: req.query.email, age: req.query.age if (fields) console.log(fields);} else { console.log('Something went wrong, Missing a parameter }app.getlist', (req, res) => { console.log('Received a list call con.connect(function(err) { con.query(`SELECT * FROM main.users`, function(err, result, fields) { if (err) res.send(err); if (result) res.send(result); In the above file, change values of the following variables with the one applicable to your RDS Amazon Aurora instance: - host: “my-Nodejs-database.cluster-cxxjkzcl1hwb.eu-west-3.rds.amazonAWS.com” - user: “admin” - password: “admin1234” - Create package.json and paste the following in it, alternatively, you can copy the content from here as well - vim package.json { “name”: “Nodejs-docker”, “version”: “12.18.4”, “description”: “Nodejs on ec2 using docker container”, “main”: “index.js”, “scripts”: { “test”: “echo \”Error: no test specified\” && exit 1″ }, “author”: “Rahul Shivalkar”, “license”: “ISC” } Update the AWS Security Group To access the application, we need to add a rule in the Security Group to allow connections on port 3000. As I said earlier, we can access the application on port 3000, but it is not recommended. Keep reading to know our recommendations - Go to the EC2 Dashboard, select the instance, switch to the “Security” tab, and then click on the Security groups link - Select the “Inbound rules” tab and click on the “Edit inbound rules” button - Add a new rule that will allow external connection from “MyIp” on the “3000” port Learn more with our blog How to Dockerize a Node.js application Deploy the node.js server on the EC2 Server (Instance) - Let’s build a docker image from the code that we have - cd /home/ubuntu/Nodejs-docker - docker build -t Nodejs - Start a container using the image that we just build and expose it on port 3000 - docker run –name Nodejs -d -p 3000:3000 Nodejs - You can see the container is running - docker ps - You can even check the logs of the container - docker logs Nodejs Now we have our Nodejs App Docker Container running - Now you can access the application from your browser on port 3000 - Check the status of the application on /status api using the browser. httppublic-ip-of-ec2-instance>:3000/status - You can insert some data in the application on /insert api using the Postman app using POST request httppublic-ip-of-ec2-instance>:3000/insert?username=abc&[email protected]&age=2 - You can list the data from your application by using /list api from the browser httppublic-ip-of-ec2-instance>:3000/list - Alternatively, you can use the curl command from within the EC2 instance to check status, insert data, list data - curl -XGET “httppublic-ip-of-ec2-instance>:3000/list” - curl -XPOST “httppublic-ip-of-ec2-instance>:3000/insert?username=abc&email=[email protected]&age=26″ - Stop and remove the container - docker stop Nodejs - docker rm Nodejs In this section, we tried to access APIs available for the application directly using the Public IP:Port of the EC2 instance. However, exposing non-standard ports to the external world in the Security Group is not at all recommended. Also, we tried to access the application over the HTTP protocol, which means the communication that took place from the Browser to the Application was not secure and an attacker can read the network packets To overcome this scenario, it is recommended to use Nginx Nginx setup Let’s create an Nginx conf that will be used within the Nginx Container through a Docker Volume. Create a file and copy the following content in the file, alternatively, you can copy the content from here as well - cd /home/ubuntu/Nodejs-docker - mkdir nginx-conf - vim nginx-conf/nginx.conf server { listen 80; listen 80; location ~ /.well-known/acme-challenge { allow all; root /var/www/html; } location / { rewrite ^ httpshost$request_uri? permanent; } } server { listen 443 ssl http2; listen 443 ssl http2; server_name Nodejs.devopslee.com www.Nodejs.devopslee.com; server_tokens off; ssl_certificate /etc/letsencrypt/live/Nodejs.devopslee.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/Nodejs.devopslee.com/privkey.pem; ssl_buffer_size 8k; ssl_dhparam /etc/ssl/certs/dhparam-2048.pem; ssl_protocols TLSv1.2 TLSv1.1 TLSv1; ssl_prefer_server_ciphers on; ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5; ssl_ecdh_curve secp384r1; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8; location / { try_files $uri @Nodejs; } location @Nodejs { proxy_pass httpNodejs:3000; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always; } root /var/www/html; index index.html index.htm index.nginx-debian.html; } In the above file make changes in the 3 lines mentioned below. Replace my subdomain.domain, i.e. Nodejs.devopslee, with the one that you want and have - server_name Nodejs.devopslee.com www.Nodejs.devopslee.com; - ssl_certificate /etc/letsencrypt/live/Nodejs.devopslee.com/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/Nodejs.devopslee.com/privkey.pem; Why do you need Nginx in front of the node.js service? Our Nodejs application runs on a non-standard port 3000. Nodejs provides a way to use HTTPS; however, configuring the protocol and managing SSL certificates that expire periodically within the application code base, is something we should not be concerned about To overcome these scenarios, we need to have Nginx in front of it with SSL termination and forward user requests to Nodejs. Nginx is a special type of web server that can act as a reverse proxy, load balancer, mail proxy, and HTTP cache. Here, we will be using Nginx as a reverse proxy to redirect requests to our Nodejs application and have SSL termination Why not Apache? Apache is also a web server and can act as a reverse proxy. It also supports SSL termination; however, there are a few things that differentiate Nginx from Apache. Due to the following reasons, mostly Nginx is preferred over Apache. Let’s see them in short - Nginx has a single or a low number of processes, is asynchronous and event-based, whereas Apache tries to make new processes, new threads for every request in every connection - Nginx is lightweight, scalable, and easy to configure. On the other hand, Apache is great but has a higher barrier to learning Docker-Compose Let’s install docker-compose as we will need it - Download the current stable release of Docker Compose - sudo curl -L “httpsgithub.com/docker/compose/releases/download/1.29.2/docker-composeuname -suname -m)” -o /usr/local/bin/docker-compose - Apply executable permissions to the docker-compose binary we just downloaded in the above step - sudo chmod +x /usr/local/bin/docker-compose - Test if the installation was successful by checking the docker-compose version - docker-compose –version - Create a docker-compose.yaml file, alternatively you can copy the content from here as well. This will be used to spin the docker containers of our application tech stack that we have - cd /home/ubuntu/Nodejs-docker - vim docker-compose.yml version: '3' services: Nodejs: build: context: dockerfile: Dockerfile image: Nodejs container_name: Nodejs restart: unless-stopped networks: - app-network webserver: image: nginx:mainline-alpine container_name: webserver restart: unless-stopped ports: - "80:80" - "443:443" volumes: - web-root:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt - certbot-var:/var/lib/letsencrypt - dhparam:/etc/ssl/certs depends_on: - Nodejs networks: - app-network certbot: image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - certbot-var:/var/lib/letsencrypt - web-root:/var/www/html depends_on: - webserver command: certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --staging -d Nodejs.devopslee.com -d www.Nodejs.devopslee.com #command: certonly --webroot --webroot-path=/var/www/html --email [email protected] --agree-tos --no-eff-email --force-renewal -d Nodejs.devopslee.com -d www.Nodejs.devopslee.com volumes: certbot-etc: certbot-var: web-root: driver: local driver_opts: type: none device: /home/ubuntu/Nodejs-docker/views/ o: bind dhparam: driver: local driver_opts: type: none device: /home/ubuntu/Nodejs-docker/dhparam/ o: bind networks: app-network: driver: bridge In the above file make changes in the line mentioned below. Replace my subdomain.domain, i.e. Nodejs.devopslee, with the one that you want and have. Change IP for your personal Email –email EMAIL, Email used for registration and recovery contact - command: certonly –webroot –webroot-path=/var/www/html –email [email protected] –agree-tos –no-eff-email –staging -d Nodejs.devopslee.com -d www.Nodejs.devopslee.com Update the AWS security groups This time, expose ports 80 and 443 in the security group attached to the EC2 instance. Also, remove 3000 since it is not necessary, because the application works through port 443 Include the DNS change Here, I have created a sub-domain “Nodejs.devopslee.com” that will be used to access the sample Nodejs application using the domain name rather than accessing using an IP You can create your sub-domain on AWS if you already have your domain Create 2 “Type A Recordsets” in the hosted zone with a value as EC2 instances’ public IP One Recordset will be subdomain.domain.com and the other will be www.subdomain.domain.com Here, I have created Nodejs.devopslee.com and www.Nodejs.devopslee.com, both pointing to the Public IP of the EC2 instance **Note: **I have not assigned any Elastic IP to the EC2 instance. It is recommended to assign an Elastic IP and then use it in the Recordset so that when you restart your EC2 instance, you don’t need to update the IP in the Recordset because public IPs change after the EC2 instance is restarted Now, copy values of the “Type NS Recordset”, we will need these in the next steps Go to the Hosted zone of your domain and create a new “Record” with your subdomain.domain.com adding the NS values you copied in the previous step Now, you have a sub-domain that you can use to access your application In my case, I can use Nodejs.devopslee.com to access the Nodejs application. We are not done yet, now the next step is to secure our Nodejs web application Include the SSL certificate Let’s generate our key that will be used in Nginx - cd /home/ubuntu/Nodejs-docker - mkdir views - mkdir dhparam - sudo openssl dhparam -out /home/ubuntu/Nodejs-docker/dhparam/dhparam-2048.pem 2048 Deploy Nodejs app to EC2 instance We are all set to start our Nodejs app using docker-compose This will start our Nodejs app on port 3000, Nginx with SSL on port 80 and 443. Nginx will redirect requests to the Nodejs app when accessed using the domain. It will also have a Certbot client that will enable us to obtain our certificates - docker-compose up After you hit the above command, you will see some output as follows. You must see a message as “Successfully received certificates” **Note The above docker-compose command will start containers and will stay attached to the terminal. We have not used the -d option to detach it from the terminal You are all set, now hit the URL in the browser and you should have your Nodejs application available on HTTPS You can also try to hit the application using the curl command - List the data from the application - Insert an entry in the application - Again list the data to verify if the data has been inserted or not - Check the status of the application - Hit the URL in the browser to get a list of entries in the database - httpsNodejs.devopslee.com/list Auto-Renewal of SSL Certificates Certificates we generate using Let’s Encrypt are valid for 90 days, hence we need to have a way to renew our certificates automatically so that we don’t end up with expired certificates To automate this process, let’s create a script that will renew certificates for us and a cronjob to schedule the execution of this script - Create a script with –dry-run to test our script - vim renew-cert. bin/bash COMPOSEusr/local/bin/docker-compose --no-ansi" DOCKERusr/bin/docker" cd /home/ubuntu/Nodejs-docker/ $COMPOSE run certbot renew --dry-run && $COMPOSE-s SIGHUP webserver $DOCKER system prune -af - Change permissions of the script to make it executable - chmod 774 renew-cert. - Create a cronjob - sudo crontab -e */5 /home/ubuntu/Nodejs-docker/renew-cert.>> /var/log/cron.log 2>&1 - List the cronjobs - sudo crontab -l - Check logs of the cronjob after 5 mins, as we have set a cronjob to be executed on every 5th minute - tail -f /var/log/cron.lo In the above screenshot, you can see a “Simulating renewal of an existing certificate message. This is because we have specified the “–dry-run” option in the script - Let’s remove the “–dry-run” option from the script - vim renew-cert. bin/bash COMPOSEusr/local/bin/docker-compose --no-ansi" DOCKERusr/bin/docker" cd /home/ubuntu/Nodejs-docker/ $COMPOSE run certbot renew && $COMPOSE-s SIGHUP webserver $DOCKER system prune -af This time you won’t see such a “Simulating renewal of an existing certificate message. This time the script will check if there is any need to renew the certificates, and if required will renew the certificates else will ignore and say “Certificates not yet due for renewal” == What is next on how to deploy the Nodejs app to AWS? == We are done with setting up our Nodejs application using Docker on AWS EC2 instance; however, there are other things that come into the picture when you want to deploy a highly available application for production and other environments. The next step is to use an Orchestrator like ECS or EKS to manage our Nodejs application at the production level. Replication, Auto-scaling, Load Balancing, Traffic Routing, Monitoring container health does not come out of the box with Docker and Docker-Compose. For managing containers and microservices architecture at scale, you need a Container Orchestration tool like ECS or EKS Also, we did not use any Docker Repository to store our Nodejs app Docker Image. You can use AWS ECR, a fully managed AWS container registry offering high-performance hosting If you want to create a cloud-native architecture, check out our video What is a Cloud-Native Architecture and how to adopt it? == Conclusion == To deploy Nodejs app to AWS does not mean just creating a Nodejs application and deploying it on the AWS EC2 Instance with a self-managed database. There are various aspects like Containerizing the Nodejs App, SSL Termination, Domain for the app that come into the picture when you want to speed up your Software Development, Deployment, Security, Reliability, Data Redundancy In this article, we saw the steps to dockerize the sample Nodejs application, use AWS RDS Amazon Aurora and deploy Nodejs app to ec2 instance using Docker and Docker-Compose. We enabled SSL termination to our sub-domain to be used to access the Nodejs application. We saw the steps to automate domain validation and SSL certificate creation using Certbot along with a way to automate certificate renewal that is valid for 90 days This is enough to get started with a sample Nodejs application; however, when it comes to managing your real-time applications, 100s of microservices, 1000s of containers, volumes, networking, secrets, egress-ingress, you need a Container Orchestration tool. There are various tools like self-hosted Kubernetes, AWS ECS, AWS EKS that you can leverage to manage the container life cycle in your real-world applications == FAQs == **Why do we need to deploy Nodejs app to AWS using Nginx To deploy Nodejs app to AWS with SSL Termination requires changes in the code of the Nodejs. So, rather than making HTTPS configuration in the code and managing it on our own and being worried about it, it is better to use Nginx that can be used for the SSL termination and can act as a Reverse proxy to redirect requests to our Nodejs application **Why do we need to use the SSL Termination for our Nodejs application When communication takes place between a client and a server, i.e. between the browser and the Nodejs application, over theconnection, there are high chances of data theft, attacks on the server. To overcome such risks, it is always recommended to enable SSL Termination and communicate over a secured connection **Why do we need to use a Container Orchestration Tool to manage our containers Managing a few containers using docker CLI, or managing 10s of containers using docker-compose is fine. This does stand true when you have 100s and 1000s of micro-services, containers on multiple environments like Dev, QA, Staging, Prod. To not only manage containers but log management, monitoring, networking, load balancing, testing, and secrets management you need some kind of tool called a Container Orchestrator. There are various Container Orchestration tools like ECS or EKS that can help you manage your containers and other moving parts **Can I deploy a Nodejs application on any other Cloud than AWS or Do I need to deploy Nodejs app to AWS Yes, of course. You can deploy your Nodejs app on any Cloud. However, while choosing a Cloud provider there are a few areas of consideration as follows that one must think of Certifications & Standards Global Infrastructure Data redundancy: Low Latency Content Delivery: Affordable Compute, Network and Storage solutions Pricing model Technologies & Service Roadmap Contracts,& SLAs