Part II of Building a Web Server Awesomely: Host a single server (custom domain edition)

Sunday, December 17, 2017

Part II of Building a Web Server Awesomely: Host a single server (custom domain edition)

This is the second part in a series of how to turn a Raspberry Pi into a fully-functional Web server, serving multiple custom domains. Want more context? Read the introductory post.

OK. In Part I, we set up our Pi and our router. Now, if you hit up your router's IP address from the wide Web, traffic will be passed through to your Pi.

Unfortunately, right now, your Pi is dropping that on the floor.

But we can fix that. It's time to install nodejs on your Pi.

Installing node

  1. Open up your SSH client (ex. Bitvise) and ssh into your Pi. The host value is the IP of your Pi; this is the static internal IP we reserved in Part I. Your username is the one you created in Part I. Use the default port 22 and log in. Enter the password for the account that you created in Part I.
  2. If you're using Bitvise, it should have opened an SFTP window and an SSH window. For now, focus on the SSH window (the terminal).
  3. Follow these instructions to install node on your Pi, then come back.

Create your node project

  1. Make yourself a directory to host your site. I created a web directory, and within that, one for my first site, e.g. whatareheirloomtomatoes
  2. In that leaf directory, initialize your node project with npm init. Fill in the configuration values you want, or leave the defaults.
  3. Put some stuff in there that you want to serve up. Create a public sub-directory; now you can throw in some html pages, client-side javascript, css -- whatever you want. You can test it out by creating an index.html file with <html><body>Hello world</body></html> in it.

Run your node project

Install http-server

To start, we're going to use a node package that can serve up your static files with a simple, premade http server. Later, we can customize this if we want to write our own server code (which, honestly, is where node shines). But let's get this working end-to-end first.

We want to be able to use this package globally, since it's not project-specific, so we use the -g flag:

sudo npm install http-server -g

Check out the documentation if you're curious how it works or what the parameters are.

Run it!

Try running your new server. Within your main directory (ex. whatareheirloomtomatoes), run:


It defaults to serving up the public sub-directory and the port 8080. So let's navigate to:


Again, the IP is the one we reserved with your router and logged into the Pi with. You should now see your Hello World page!

However, the other great folks on the Web can't. The above address is your internal IP, so you can only hit it from machines on your LAN. If others try putting in your router's IP address, they're getting warmer, but we still have a disconnect: Your Pi doesn't know to pass through the requests it receives on its port 80 to your new node server running on 8080.

Letting the world see your beautiful site

Everyone should get to see the amazing Hello World page that you made. Everyone. So we're going to make sure that requests to port 80 on your Pi get forwarded to your Web server running on 8080.

We're going to use nginx as a reverse proxy. It will be listening for requests on port 80, sent from your router; then it will proxy the requests to your node server running on 8080.

Follow these instructions to install nginx, up until they mention php; then panic, close that tab, and come back to this one, where we are all javascript, all the time.

Then follow these instructions to set up the reverse proxy configuration ("Configure nginx reverse proxy" section only).

Once you've configured it all and reloaded your nginx config, try hitting your external IP address (i.e. your router's IP) from your browser. (Don't know your external IP? Google "what's my IP address.") Hopefully, it shows you the same thing as when you hit your Pi's local IP and port.

Pointing your domain to your Web server

We could still stand to make this easier for people to get to, and you didn't spend $12 on a custom domain for nothing. Let's configure that fancy domain to point to your external IP.

  1. Log in to your domain's DNS management. I used Google Domains, but this should work with any provider.
  2. Add a custom resource record. We want an 'A' record. (Want to know why? Read about it.) The name value should be @ (the root). You can leave the TTL at 60; the value of the data field should be your router's IP address. It should look something like: @ | a | 60 | 12.345.678.90
  3. Save that biz.
  4. It might take a bit to propagate, but not long. In a few minutes, try accessing your domain. You should see the same thing as when you type in your fully-qualified external IP address.

Making a custom Web server, not this http-server nonsense

If you just wanted to serve up a static site, you're golden. Keep dropping stuff in your public folder and go to town. If, however, you wanted to write some of your own server code, this is your chance.

I'm going to leave most of this as an exercise you, dear reader, since there are many guides out there to help, but I'll leave some hints here:

  1. Express: The http module is low-level and would force you to write a lot of boilerplate. Express abstracts that away. Install it in each of your projects.
  2. Nodemon: This listens for changes in your server and dynamically rebuilds, so it's quick to iterate and test changes. Instead of running node server.js, you'd run nodemon server.js. As with http-server, globally install this one with -g.
  3. Forever: It keeps your server running... forever. It will restart after failures and background your task so it doesn't die when you close your terminal, etc. Instead of running node server.js, you'd run forever start server.js. Install this one globally, too.
  4. Crontab time: I recommend adding a forever command to start your server to your crontab. That way, if your power goes out, or your Pi otherwise reboots, so will your server. Something like this: @reboot /usr/local/bin/forever start /home/<username>/web/whatareheirloomtomatoes/server.js >> /home/<username>/web/whatareheirloomtomatoes/server.out 2>&1
  5. The power of SFTP: Write your code on your local machine, not your Pi. I write it on my Windows box using, as I mentioned, Atom. I then upload it with my SFTP client, Bitvise, onto my Pi. It is good and wonderful and I never need to look at my Pi's GUI ever.

Now that you have your beautiful, publicly-available Web server, we will next make it resilient to router IP address changes in Part III: Set up DDNS to deal with your dynamic IP – for free!


  1. The more hosting accounts a private-label reseller can sell, the higher the profit for them. Private-label hosting allows you to host many more websites than if you were using shared hosting for each. minecraft server hosting

  2. Many business owners like me are not familiar with these sort of technical aspects involved in developing a website. When I needed a website for my business, I simply hired a design agency to do the work. Now I’m trying to attract more visitors to my website mainly through PPC advertising. For this purpose, I’ve hired one of the best Google Adwords Campaign Management agency.

  3. I like your post. It is good to see you verbalize from the heart and clarity on this important subject can be easily observed... hospedaje web

  4. This blog was amazingly useful. I truly value your benevolence in offering this to me and every other person! SEO in New York

  5. This can be attributed to the trust level, business reputation as well as relationships build during the offline campaigns. Niche

  6. Thanks for a very interesting blog. What else may I get that kind of info written in such a perfect approach? I’ve a undertaking that I am simply now operating on, and I have been at the look out for such info. Zerteck Digital Marketing agency in Karachi

  7. Great write-up, I am a big believer in commenting on blogs to inform the blog writers know that they’ve added something worthwhile to the world wide web!.. Web Designing

  8. I’m going to read this. I’ll be sure to come back. thanks for sharing. and also This article gives the light in which we can observe the reality. this is very nice one and gives indepth information. thanks for this nice article... top web series

  9. Nice information, valuable and excellent design, as share good stuff with good ideas and concepts, lots of great information and inspiration, both of which I need, thanks to offer such a helpful information here. best web hosting

  10. Interesting topic for a blog. I have been searching the Internet for fun and came upon your website. Fabulous post. Thanks a ton for sharing your knowledge! It is great to see that some people still put in an effort into managing their websites. I'll be sure to check back again real soon. website design company

  11. I have read all the comments and suggestions posted by the visitors for this article are very fine,We will wait for your next article so only.Thanks! ecommerce hosting

  12. It is my first visit to your blog, and I am very impressed with the articles that you serve. Give adequate knowledge for me. Thank you for sharing useful material. I will be back for the more great post. ecommerce hosting online shop

  13. Nonetheless, much of the time, these sorts of administrations are restricted and having one of those pages doesn't imply that you totally claim them,Best Website Hosting since another website is really hosting it.

  14. To begin with precisely what are game server providers, GSPs, and why do I require one? If, as i am, you cherish winning contests along with your other online gaming buddies you generally play together online. ark server hosting