Part 6 - Setting Up Reverse Proxy (Nginx)

This is the sixth post in the series of how to host your own git server on a Raspberry Pi

You have successfully configured GitLab and set runners for your projects in the previous post. We will now look into setting up a reverse proxy on our Raspberry Pi. This will allow us to host multiple web pages and services via sub-domains, and access GitLab through git.<HOSTNAME>.<DOMAIN>.

1. Install Nginx

Start by installing Nginx with the following command:

sudo apt install -y nginx

Before starting your Nginx server, stop the running GitLab instance so it does not interfere with the setup:

sudo gitlab-ctl stop

You can then start Nginx with default configuration as follows:

sudo /etc/init.d/nginx start

Test if Nginx is accessible by accessing your Pi through a browser (http://192.168.X.X or http://<HOSTNAME>.<DOMAIN>). You will see the welcome screen for Nginx:

Nginx Welcome Screen

2. Create Web Pages

We will create two sample web pages to be hosted by Nginx:
- Home Page, served at: http://<HOSTNAME>.<DOMAIN>
- Hello Page, served at: http://hello.<HOSTNAME>.<DOMAIN>
This should give us a good sense of the reverse proxy capabilities of the Nginx.

We will place our the static web content under /var/www/. Start by creating a directory for the home page:

sudo mkdir /var/www/home/

You can then create an index file for this page and start editing the content:

sudo nano /var/www/home/index.html

Write a welcome message as page content:

Welcome to Homepage!

Once you are done, make sure to save the file (CTRL+X).

You can follow the same steps to create a hello page as well:

sudo mkdir /var/www/hello/

sudo nano /var/www/hello/index.html

Welcome to Hello page!

3. Create Page Configurations

Now that we have some web pages we want to host, the next step is to create configuration files for sites under /etc/nginx/sites-available.

sudo nano /etc/nginx/sites-available/home

server {
listen 80;
listen [::]:80;
root /var/www/home;
index index.html;
server_name <HOSTNAME>.<DOMAIN>;
}

sudo nano /etc/nginx/sites-available/hello

server {
listen 80;
listen [::]:80;
root /var/www/hello;
index index.html;
server_name hello.<HOSTNAME>.<DOMAIN>;
}

We will also create a configuration file to handle not found (HTTP 400) requests. If a user would access any non-existing address in our system, this configuration will handle:

sudo nano /etc/nginx/sites-available/404

server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/404;
index index.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}

4. Enable Page Configurations

For configurations to take into effect, they have to exist in /etc/nginx/sites-enabled. We can create symbolic links to mirror our configurations from sites-available into sites-enabled as follows:

sudo ln -s /etc/nginx/sites-available/home /etc/nginx/sites-enabled/home
sudo ln -s /etc/nginx/sites-available/hello /etc/nginx/sites-enabled/hello
sudo ln -s /etc/nginx/sites-available/404 /etc/nginx/sites-enabled/404

Nginx comes with a default configuration file, which you should remove from both folders below:

sudo rm -f /etc/nginx/sites-available/default

sudo rm -f /etc/nginx/sites-enabled/default

Once you are done, restart Nginx for configurations to take into effect.

sudo systemctl restart nginx

Your pages should now be available under these links:

http://<HOSTNAME>.<DOMAIN> -> Home Page

http://hello.<HOSTNAME>.<DOMAIN> -> Hello Page

<Any other address> -> 404 Page

If your page requests including subdomains (eg. the Hello Page), you may need to configure your router to direct those requests to your Raspberry Pi. Follow the next step to set a dnsmasq in your router for this purpose.

5. Configure dnsmasq in Router (Optional)

To configure a dnsmasq in the Asus Router, start by establising an ssh connection into the router. Create a file named dnsmasq.conf.add and place it in /jffs/configs . Write following line into this file, where the <HOSTNAME>, <DOMAIN> and the IP address belongs to your Pi:

address=/<HOSTNAME>.<DOMAIN>/192.168.X.X

Once you are done, give the router a restart. Your sub-domain requests (*.<HOSTNAME>.<DOMAIN>) should be routed to your Raspberry Pi now.

6. Configure GitLab

GitLab needs to be configured to run with the external Nginx setup. Start by editing the configuration file.

sudo nano /etc/gitlab/gitlab.rb

Make sure that your external url is specified as

external_url “http://git.<HOSTNAME>.<DOMAIN>"

Append the following anywhere in the file:

gitlab_rails['internal_api_url'] = 'http://git.<HOSTNAME>.<DOMAIN>'

Find and change these values in the file:

web_server['external_users'] = ['www-data']
unicorn['enable'] = false
nginx['enable'] = false

7. Create GitLab Nginx Configuration

Similar to other pages, GitLab also needs a configuration file to be served through Nginx. Start by creating a config for GitLab:

sudo nano /etc/nginx/sites-available/gitlab

The contents of the file should look like as follows:

upstream gitlab-workhorse {
server unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket;
}

server {
listen 0.0.0.0:80;
listen [::]:80;
server_name git.<HOSTNAME>.<DOMAIN>;
server_tokens off;
root /opt/gitlab/embedded/service/gitlab-rails/public;

access_log /var/log/nginx/gitlab_access.log;
error_log /var/log/nginx/gitlab_error.log;

location / {
client_max_body_size 0;
gzip off;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://gitlab-workhorse;
}
}

Mirror this file to sites-enabled:

sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab

Once the changes are done, restart GitLab:

sudo gitlab-ctl reconfigure

You should then restart Nginx as well for above configurations:

sudo service nginx restart

And finally, your GitLab instance should be accessible at:

http://git.<HOSTNAME>.<DOMAIN>

Congratulations — You have set up reverse proxy and got static web pages up and running! Next post is going to talk about bringing HTTPs support for these pages.

Systems Engineer, specialized in building Internet of Things (IoT) devices and applications. Harvesting crops at Google. 💻

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store