GitLab is a web-based DevOps lifecycle tool that provides a Git repository manager providing wiki, issue-tracking and continuous integration and deployment pipeline features, using an open-source license, developed by GitLab Inc. The main benefit of using GitLab is that it allows all the team members to collaborate in every phase of the project. GitLab offers tracking from planning to creation to help developers automate the entire DevOps lifecycle and achieve the best possible results.

Gitlab can be installed as an external package, but if you have been following my articles, I am an avid fan of containerization. I can’t talk enough about how containerization has revolutionized the way we package our applications. In this article, I will explain how you can setup a secure private Gitlab server. The summary of the steps are :

  • Install Docker
  • Setup Docker container with a persistent volume
  • Use Nginx reverse proxy and LetsEncrypt to secure gitlab server.


Since I only talk about setting up Gitlab as a container in this article. We will start by setting up docker.

1.) Install Docker on your machine. You can check my previous article for the steps to install docker on Ubuntu.

2.) After setting up Docker you can run below script to create Gitlab container. Please note I am using persistent volume and storing all the data in /repo/gitlab. We don’t really care about 444 port here, since we are going to use Nginx reverse proxy and LetsEncrypt to secure our Gitlab Instance.

mkdir /repo/gitlab
export GITLAB_HOME=/repo/gitlab

sudo docker run --detach \
  --hostname \
  --publish 444:443 --publish 81:80 --publish 23:22 \
  --name gitlab \
  --restart always \
  --volume $GITLAB_HOME/config:/etc/gitlab \
  --volume $GITLAB_HOME/logs:/var/log/gitlab \
  --volume $GITLAB_HOME/data:/var/opt/gitlab \

3.) Check container status using “docker ps” command. Gitlab container can take up to 5 minutes to be healthy.

4.) After configuring Gitlab container, you can follow my previous article to get LetsEncrypt certificate. Since we have mapped port 81 on the host for Gitlab container we need to modify “proxy_redirect” in the config file under /etc/nginx/sites-available/ to port 81. You can customize this accordingly. Refer to point 9 in this article.

server { 
listen 8444 http2 ssl; 
access_log /var/log/nginx/; 
error_log /var/log/nginx/; 
location /.well-known/acme-challenge/ { 
root /var/www/html/grafana; # Temp for generating letsencrypt 
default_type text/plain; 

location / { 
proxy_set_header Host $host:$server_port; 
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; 

#Fix the “It appears that your reverse proxy set up is broken” error. 

proxy_read_timeout 90; 

#Required for new HTTP-based CLI 

proxy_http_version 1.1; 
proxy_request_buffering off; 

ssl_certificate /etc/letsencrypt/live/; # managed by Certbot 
ssl_certificate_key /etc/letsencrypt/live/; # managed by Certbot 
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot 
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot 

server { 
if ($host = { 
return 301 https://$host$request_uri; 
} # managed by Certbot 

listen 80; 
return 404; # managed by Certbot 

5.) If you notice I am using 8444 as my SSL port but you can customize this based on your requirement.