-
Go to the google console cloud and create a new project.
-
Under this project, navigate to
Compute engine
>>VM instance
usually on the left sidebar of cloud console. -
Create a new VM instance and select zone nearby to your location.
-
Once the instance is created, you will see External IP address like
xx.xxx.xxx.xxx
. Save it. -
Now go to your terminal and create ssh keys for the connection.
ssh-keygen -t rsa -b 4096 -C "your_google_username@gmail.com"
-
Generate and locate the ssh private key and public key pair
/User/kapil/.ssh/key-name
and/User/kapil/.ssh/key-name.pub
. -
Copy the content of the ssh public key (key-name.pub) and paste it in the ssh keys settings of the instance.Try to make a ssh connection to remote from the browser.
-
Go to the VS code and open a remote window and
Connect to host
>>Add new host
.ssh your_google_username@xx.xxx.xxx.xxx // xx.xxx.xxx.xxx is the External IP
-
If the connection establishes, well and good otherwise check the ssh config file
/Users/xx/.ssh/config_
Host xx.xxx.xxx.xxx HostName xx.xxx.xxx.xxx User your-google-username IdentityFile ~/.ssh/key-name
-
Sometimes we get a complaint of publicaly accesible private key so we need to hide the private key using chmod command as well.
chmod 400 ~/.ssh/key-name
-
Once the ssh connection establishes, open a new terminal window.
-
Remove the apache2 files if any left.
sudo apt-get purge apache2* sudo apt-get remove apache2* sudo apt update && sudo apt upgrade -y
-
Install Nodejs and Npm
sudo apt install -y nodejs node -v sudo apt install -y npm npm -v sudo apt update && sudo apt upgrade -y
-
Install nginx
sudo apt install nginx
-
Installing
ufw
and create a firewall, Make sure to allow ssh port otherwise you will be locked out.sudo apt install ufw sudo ufw enable # enabling firewall sudo ufw status # status of ufw firewall sudo ufw allow 22 # open ssh port 22 sudo ufw allow 'NGinx HTTPS' # open 443 port for ssl/tls sudo ufw allow 'Nginx HTTP' # open 80 port for http sudo ufw allow PORT_NUMBER # open custom PORT_NUMBER
-
Create a new Nginx configuration file for your Next.js application. (name anything you want, i have named it
nextjs.conf
)sudo nano /etc/nginx/sites-available/nextjs.conf
-
Paste the following configuration file in this. Save and close.
server { listen 80; server_name xx.xxx.xxx.xxx; location / { proxy_pass http://localhost:3000; 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; } }
- You can replace external-ip
xx.xxx.xxx.xxx
with your subdomain/domain if you have pointed the domain in the DNS configuration to this ip address. - As NextJS app runs on 3000 port on
localhost
. So, we are using reverse proxy to listen http port 80 to this.
-
Make a symbolic link between site-enabled and site-available configuration files. In case if there is some default or other configuration file then remove these files using rm command. If symbolic link does not establish due to existing file, force overwriting file using
-sf
flag instad of-s
flag.sudo ln -s /etc/nginx/sites-available/nextjs.conf /etc/nginx/sites-enabled/ sudo rm /etc/nginx/sites-enabled/default.conf
-
Test the configuration files and restart the Nginx server.
sudo systemctl start nginx // Start nginx server sudo systemctl enable nginx // Enable nginx server sudo service nginx restart // for restart sudo service nginx status // for status sudo service nginx stop // for stopping server sudo service nginx start // for starting nginx server sudo systemctl reload nginx // for reload nginx server sudo nginx -t // for testing config files
-
Source code of the app. Name of the directory can be anything(of your choice) i'm making folder named
nextjs
cd ~ cd /var/www/ mkdir nextjs cd nextjs
-
Install
git
and clone the source code of the application from the repository inside the folder/var/www/nextjs
.sudo apt install git git --version cd /var/www/nextjs sudo git clone https://github.com/github-username/github-repo.git .
Warning: Make sure you place dot (.) after in the git clone command otherwise it will make a new folder named github-repo
inside the folder /var/www/nextjs
-
Install dependencies, check if the app builds in the remote. Do not forget to add or edit your environment variables if used.
sudo npm install sudo npm run build
-
If build is successful, run the npm server on 3000 port.
sudo npm start
-
Visit the ip address
xx.xxx.xxx.xxx
or your domain / subdomain. If the site is running, well and good otherwise make changes in nginx configuration files. -
Install pm2 which keeps our localhost server running in background.
cd ~ sudo npm install -g pm2
-
Change directory to root of source code and create a pm2 process.
cd /var/www/nextjs sudo pm2 start npm --name "nextjs" -- start sudo pm2 startup sudo pm2 save
-
List process running on the port (3000 here)!
sudo lsof -i:3000 sudo kill -9 PID # Kill port sudo kill -9 $(lsof -i:3000 -t)
-
Installing SSL/HTTPS certificates with certbot. It will issue Letsencrypt free certificate to your domain name (ip-address are not supported). Dry run will simulate the auto-renew process.
sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d yourdomain.com -d www.your-domain.com sudo systemctl status certbot.timer sudo certbot renew --dry-run
-
Cerbot will overwrite the nginx configuration files by redirecting traffic to 443 port and defining certificate paths.
-
Enabling http2 is very simple, just add
http2
in the listen line under the sever of the configuration file.sudo nano /etc/nginx/sites-available/nextjs.conf
\\ conf:nextjs.conf server { listen 443 ssl http2; server_name example.com ... }
Using custom acme clients like google public certificates.
-
Create a google cloud account and enable the Public certificate API.
-
Follow this guide to get
EAB_KID
andEAB_HMAC_KEY
-
Register an account with public CA using the following certbot command
certbot register \ --email "EMAIL_ADDRESS" \ --no-eff-email \ --server "https://dv.acme-v02.api.pki.goog/directory" \ --eab-kid "EAB_KID" \ --eab-hmac-key "EAB_HMAC_KEY"
-
Now, we need to prove the ownership of the domain through various acme challanges to make sure CA can issue the certificate to us. For this, we will use dns method. Create a token with the dns provider of domain with read and write access of your dns records.
-
In case of cloudflare, create a token.
-
Install plugin of certbot to automate this process of validating dns records for dns provider (here cloudflare)
sudo apt install python3-cloudflare python3-certbot-dns-cloudflare
-
Create Cloudflare crenditial file with the created token
cd ~ sudo mkdir /etc/cloudflare cd /etc/cloudflare sudo touch credential.ini sudo nano credential.ini
with following details dns_cloudflare_api_token = YOUR TOKEN
-
Protect this file
cd ~ sudo chmod 0600 /etc/cloudflare/credential.ini
-
Issuance of certificate and installation
# only issues certificate sudo certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /etc/cloudflare/credential.ini -d mydomain.com,*.mydomain.com --server 'https://dv.acme-v02.api.pki.goog/directory' # changes nginx config file to use the issued certificate sudo cerbot install
-
Test, Reload and restart the nginx
-
View and delete the certificate
sudo certbot certificates sudo certbot delete -d domain.tld
Warning: After deleting certificate make sure to modify nginx config file (if using that deleted certificate), otherwise test will fail.
sudo nginx -t
Planned in next post that will discuss about:
- Caching static content and Gzip compression
- Nginx load balancer