Skip to content

Instantly share code, notes, and snippets.

@alexcdot
Last active January 18, 2023 04:30
Show Gist options
  • Save alexcdot/c489390a31ba05f4d14d8ecad75f1fe8 to your computer and use it in GitHub Desktop.
Save alexcdot/c489390a31ba05f4d14d8ecad75f1fe8 to your computer and use it in GitHub Desktop.
Web server setup

Setting up your cloud server:

  1. Start an aws account, and start up an EC2 instance. Guide here
  2. Add HTTP to your inbound rules in your ec2 instance's security group. Guide here
  3. Connect to your ec2 instance with ssh with a command like this:

ssh -i <path to ssh key given to you from amazon> ubuntu@<public ip address of your server>

Set up nginx

(based on the guide here):

sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install nginx -y
sudo systemctl status nginx    # To check the status of nginx
sudo systemctl start nginx     # To start nginx
sudo systemctl enable nginx
sudo rm /etc/nginx/sites-available/default
sudo vim /etc/nginx/sites-available/default

Then, copy and paste this into the file you opened in vim, and replace "<your IP address>" with either a domain you own if you have one, or just your public IP address (we'll talk about getting a domain below)

server {
    listen 80;
    server_name <your IP address> <your domain>;
    location / {
        proxy_pass http://localhost:8080;
        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;
     }
}

Check it works, and load the new config:

sudo nginx -t
sudo systemctl reload nginx

Install node version manager, node.js and node package manager:

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

Then, copy and paste this into your terminal as a command:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

Then, run this to install node and npm:

nvm install node

Then create a project with:

mkdir myapp
cd myapp
npm install express
vim app.js

and copy and paste this into the file you opened with vim:

var express = require('express');
var app = express();
app.get('/', function(req, res){
   res.send("Hello World!");
});
console.log("I'm listening for requests!");
app.listen(8080, 'localhost');

Now run:

node app.js

and your app is running! You won't see any output, but you'll notice you won't exit from the program until you do ctrl+C and stop the server. You should be able to see the words "Hello World" when you visit your server's public IP.

You will need to keep the server running in the background. pm2 is a very popular tool for monitoring and managing servers - I've used it to keep some of my backend servers up for years (docs here). To install it, just run:

nvm install pm2 --global
pm2 start app.js

and now your app will be running in the background. To see a list of all your servers on pm2, run: pm2 list

Whenever you make changes and want to reload your "app.js" server for them to take effect, run: pm2 restart app

Now, to link your public IP to an actual domain, you will need to go to a domain provider, like namecheap.com or domain.com and buy one. They can cost under $10 a year, and you only ever need to buy one to actually get infinite subdomains (like, if you buy alex.com, you can make websites like meet.alex.com or whos.alex.com).

Assuming you used namecheap, you should now follow this guide to add an A name record to your domain. A name records basically direct a request to your domain to go to an IP address you specific. Set an A name record from "@" (which represents when people visit your website with no subdomain, so like, "alex.com"), that goes to your public IP address. Set the TTL to be as short as possible, so it updates more frequently. Make sure you use your PUBLIC ip address for your AWS instance, not your private one, as web domains can only access your public one.

Now, go back to your nginx config with: sudo vim /etc/nginx/sites-available/default

and change it so you include your URL in the "server_names" argument list if you didn't already:

server {
    listen 80;
    server_name <your IP address> <your domain>;  # REMEMBER TO REPLACE WITH YOUR DOMAIN. DO NOT INCLUDE http:// or https://
    location / {
        proxy_pass http://localhost:8080;
        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;
     }
}

Now run the steps you should run every time you want to deploy new nginx config changes:

sudo nginx -t
sudo systemctl reload nginx

and if you visit your website at your domain, you should be able to see "Hello World" instead of a 404 error. If it doesn't work initially, try using "ctrl+shift+R" (basically a hard refresh to avoid reviewing a cached version of your website) to reload the page.

Now that you have a basic HTTP website, let's add HTTPS.

We will be following this guide:

Install certbot: https://certbot.eff.org/instructions

Run the certifying process! (This will allow Let's Encrypt to know that you control this server). Replace "my domain url" with your domain url.

sudo certbot --nginx -d <my domain url>

If the process asks if you'd like to redict HTTP traffic to HTTPS, I would generally say yes, you should, just so your users don't accidentally use HTTP.

If that succeeded, now when people visit your website, they will have encryption! Awesome!! You're a top web developer now. Go make something cool!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment