Setting Up My On-Premise Server with a Go Application !


Link to my on-premise server


Most people I meet love building apps, websites, services with infrastructure managed by someone else. You ask them about their infrastructure and it's all AWS Lambdas and AzureCloud Functions with a Cosmos Db for storage, nobody really needs to do anything with bare metal themselves anymore. This is great, we have increased the level of abstraction where I as an engineer can be so far away from bare metal that I will don't need to learn what firewalls and networks are and can spend the rest of my life on the application level code.


This is great but there's a pattern I have noticed, all the great 10x engineers I meet know the ins and outs of infrastructure as well. Heck, one of the engineers who shall remain nameless was a top contributor to Docker at one point... I find this inspiring. The abstraction makes our life easier, but if we don't have an understanding of the "why" behind our abstraction we will never learn the right way to use it.


So with all this inspiration behind my back this Friday I decided to spin up my Raspberry-Pi as an on-premise server. This article is a small document for the steps I took to get my on-premise server onto the cloud.


Let's start with a 10,000 foot above approach to our problem: We want to run a server written in Go-lang that returns a simple straightforward html page when we hit the root route. We know how to get a server up and running locally but we also need to also expose it the outside world.


Now with a rough idea of the 10,000 foot view we can do the following steps to get our server up and running:

  1. My raspberry-pi needed a static IP address so that every time it reboots it does not have a different IP address. The OS on my rPi being run is Raspbian. Raspbian is a unix-like OS and for it's IP address it uses a file called dhcpd.conf that is used by the DHCP client running on the Raspberry Pi board is configured to obtain an IP address from the DHCP server. You can configure a static IP address for your Raspberry Pi board by updating the dhcpcd. conf file. I had to configure a static IP for my raspberry pi here. The IP I added here is not exposed to the world but will be used by my router to forward requests on a particular port to my raspberry pi. I also had to add my router's IP to this config file.
  2. Now in-order to expose the raspberry pi to the world outside I needed to configure my router to forward requests on the port 3000 to my raspberry pi. This is where I used the static ip from the previous step. Now any requests to my router on the port 3000 will be forwarded to my raspberry-pi, this is called port-forwarding.
  3. Now ideally I would have been able to expose port 80 which is the default port for http requests, but my internet provider blocks me from doing so, so for that reason I chose the route of forwarding from port 3000. Now I wanted to have some control over the traffic entering my server. For this reason I chose to run Nginx as a reverse proxy with the port for it to bind to set as port 3000. From this port I configured my Nginx server to forward requests to the route 127.0.0.1/3001, for those that don't know this just means that Nginx will take traffic from port 3000 and to the application process running on port 3001 on the raspberry-pi.
  4. I wrote a Go-lang based server that exposed a single route on port 3001 and would return an html template with the link to my personal website. You could write this in whichever language you like. I chose Go-lang because well... I wanted to. As for what it returns, you could make an actual app but I just chose to go with a dummy static page.
  5. After this I had to expose the port by adding a rule to my firewall to allow incoming traffic from port 3000. I also added a rule to deny connections from an IP address that has attempted to initiate 6 or more connections in the last 30 seconds. This UFW feature is very useful against brute force attacks.


Now with my Go server running on port 3001 in the background, my Nginx proxy running on port 3000, with traffic being forwarded to the raspberry-pi from my wifi router, my server was visible to traffic on port 3000 to the public. Now by accessing the public ip for my wifi router on port 3000 I can access my own on-premise web server running a Go-lang server!


This wasn't my usual conventional programming project. But something about removing the idea of a hosting service and managed infrastructure felt very satisfying, and I felt there was value in learning about and managing my own server. Here it is live and in action: Link to my on-premise server



Comments

Commenter: Hamdaan khalid

Also I forgot to mention I used systemd to create services that will restart on their own for nginx and go server

Commenter: Hamdaan Khalid

So I updated the go server to run a tic tac tow game I wrote!

Add a comment: