Put your GitLab on HTTPS

For this article I will use the following configuration:

GitLab Docker image by sameersbn – Since the rise of Docker LXC I prefer to encapsulate all of my apps in production with it.

Docker is really easy to install. Just follow the instructions from here: https://docs.docker.com/installation or directly for Ubuntu users here: https://docs.docker.com/installation/ubuntulinux/.

Then follow the installation instructions of the Docker image here: https://github.com/sameersbn/docker-gitlab#installation.

Of course you can just install GitLab for you OS using their instructions here: https://about.gitlab.com/installation/.

My specific configuration is to put the Docker GitLab container behind a main nginx which becomes a reverse proxy for the container. Only the GitLab SSH console’s port is mapped directly to the host.

You may decide to map the GitLab ports directly to the host’s external IP and use it that way. The instructions on the Docker GitLab image are given with this in mind.

Now let’s say you have a running GitLab server behind or not an nginx reverse proxy. It’s working with ssh:// and http:// access for git clone/pull/push. You are getting used to it and now you want to make it the professional way: using HTTPS!

The first thing is to consider where will you get an SSL certificate from?

There are many companies out there selling good certificates for web sites, mail servers, etc. Some of them are expensive, others are very cheap. It depends on that whether you need to use it for multiple subdomains, will it be recognizable by all browsers and other software and so on. The third type are free. They are limited but they are recognized by the browsers and in our case by git/curl/OS too. Since they are free we don’t need to create self signed certificates and force everybody using our site to install certificates locally or to accept the warnings.

My personal choice is StartSSL. They give you a free certificate, it’s CA authorized and it’s working with a subdomain. I haven’t checked yet StartSSL’s other alternatives which are paid and also other providers of free certificates but for our case we only need the certificate for one thing and one place. In my case: https://gitlab.iliyan-trifonov.com and git clone https://gitlab.iliyan-trifonov.com/..project-name.git.

Now go to the free certificate page on StartSSL and sign up. Create a backup of the certificate you will install on your browser because without it you will have to pay to recover your account access. When you’re ready and you’re in the Control Panel of the site, authorize your email and domain. Also for a subdomain I picked gitlab as in gitlab.iliyan-trifonov.com.

From StartSSL you will get a .key file and a .crt file. Back them up.

There is a little more work to make the certificate compatible with git. Before that you can already use the key and crt files in your web server and make your site using https. But this is not enough for us so let’s continue.

First decrypt the key file using the following command and the password you provided while generating it on StartSSL:

openssl rsa -in ssl.key -out ssl-decrypted.key

This will prevent your web server to ask you for the password every time it is started. Imagine the downtime if the server was restarted automatically and it is waiting for a human to continue its work.

We need 2 more files freely available from StartSSL to make our certificate combined with their Root CA and Intermediate CA:

wget http://www.startssl.com/certs/ca-sha2.pem
wget http://www.startssl.com/certs/sub.class1.server.sha2.ca.pem

Combine the 3 certificate files you have:

cat ssl.crt sub.class1.server.sha2.ca.pem ca-sha2.pem > ssl-unified.crt

There is a possibility that the concatenated crt file will have some BEGIN/END lines on the same line. If your web server is not happy with that and says bad end of file in its logs, do this: open ssl-unified.crt with a text editor like nano and search for a line like this:

-----END CERTIFICATE----------BEGIN CERTIFICATE-----

or

-----BEGIN CERTIFICATE----------END CERTIFICATE-----

Make sure BEGIN and END are on a separate files and also that the B of the BEGIN and E of the END are on the same column, like this:

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

Not like this or similar:

-----BEGIN CERTIFICATE----
------END CERTIFICATE-----

Dashes on the left/right should be equal.

Now the only 2 files you need to use in your web server are ssl-unified.crt and ssl-decrypted.key.

It’s time to go to Nginx and make the configuration:

server {
    server_name gitlab.yourdomain.com;
    listen 80;
    
    return 301 https://$server_name$request_uri;

    access_log /var/log/gitlab.access.log;
    error_log /var/log/gitlab.error.log;
}

server {
    server_name gitlab.yourdomain.com;
    listen 443 ssl;

    ssl_certificate /.../certs/ssl-unified.crt;
    ssl_certificate_key /.../certs/ssl-decrypted.key;

    access_log /var/log/gitlab.ssl.access.log;
    error_log /var/log/gitlab.ssl.error.log;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-Forwarded-Proto $scheme;
         proxy_redirect off;
         proxy_read_timeout 300;
         proxy_pass http://INTERNAL_IP:INTERNAL_PORT; #the docker gitlab container's address
     }
}

Remember that this example Nginx configuration is for Nginx running as a reverse proxy to the container. In your case you may have decided to not have a reverse proxy and then you have to use the really easy configuration of the Dockerized GitLab from the link above or change the GitLab’s server configuration in a similar way. Still the preparation of the good .crt and .key files and the server configuration will give you a good start.

For better security read Optimizing HTTPS on NginxConfiguring HTTPS servers and Enabling Perfect Forward Secrecy.

At the end you will have your GitLab pages loaded with HTTPS and everybody can git clone https://yourgitlabserver.com/..project.git like a pro!

How to install and configure GitLab inside a Docker container: The Ready-Made Edition

Update: Please check the best Gitlab Docker container that I’ve found already a long time ago: https://github.com/sameersbn/docker-gitlab
Everything you need to set it up is on the page. I am using it and it does exactly what you expect it to do. You should read only the updates of this post. The alternative image from the original post is too old and we don’t need it anymore. Enjoy!

Update 2: And don’t forget to secure it with free HTTPS!

Update3: To help you start faster I’ve created an example configuration with the Docker image from the Update 1 link:

docker run –name=gitlab -d \
-e ‘DB_TYPE=mysql’ \
-e “DB_HOST=172.17.42.1”
-e “DB_NAME=gitlabhq_production”
-e “DB_USER=gitlab” -e “DB_PASS=yourpass” \
–link redis:redisio \
-v /home/yourusername/gitlab/data:/home/git/data \
-e “GITLAB_HOST=gitlab.yourdomain.com” \
-e [email protected]
-e [email protected] \
-e [email protected] -e “SMTP_PASS=yoursmtppass” \
-e “GITLAB_BACKUPS=daily” \
-e “GITLAB_SHELL_SSH_PORT=2222” \
-e “GITLAB_HTTPS=true” \
-e “GOOGLE_ANALYTICS_ID=UA-xxxxxx-xx” \
-p 172.17.42.1:8080:80 -p 2222:22 \
sameersbn/gitlab:7.8.1

The IP used is the internal Docker network address. I assume that you want to put Gitlab behind a reverse proxy on the same host. You may change it to another internal IP for the DB connection option and also remove it from the port forwarding to have the web port(8080) visible from the outside on your domain.

This configuration needs a `redis` named container running and the Gitlab container will link to it. Also the HTTPS is enabled, google tracking added and at the end port 2222(used by git+ssh) is open for your domain.

You may decide to dedicate a host for Gitlab only. Then you will set it to use port 22 for SSH and 80/443 for web. Check Update 2 above to see a sample nginx configuration for HTTPS.


The original post:

For this we are going to use a ready-made configuration for building the image and easy configuring it from https://github.com/crashsystems/gitlab-docker

We will follow these procedures: https://github.com/crashsystems/gitlab-docker/tree/master with some additions for our specific example.

You have a couple of things to do. First download the configuration and use the Dockerfile inside to build the base image:

git clone https://github.com/crashsystems/gitlab-docker.git
cd gitlab-docker
docker build -t crashsystems/gitlab-docker .

Wait until it’s done and now it’s time to configure hostnames and passwords using the .yml and .sh files that came with the Dockerfile from the git clone:

nano config/gitlab.yml

Change the hostname with something like: mygit.yourdomain.com. I will also change the standard port number 22 of the gitlab shell to one non standard and available on the host: 22222. Later we’ll use this port in docker run to redirect incoming requests for gitlab from the host.

Next is the database password for the gitlab MySQL user:

nano config/database.yml

change:

password: "secure password"

with a good one.

Finally, change the server name in the nginx config file:

nano config/nginx

It should be mygit.yourdomain.com as the gitlab.yml configuration above.

Now you are going to start the container:

docker run -d -v /your/path/to/gitlab-docker:/srv/gitlab --name gitlab -p 172.17.42.1:82:80 -p 22222:22 crashsystems/gitlab-docker

This will use your local host’s directory for storing the gitlab files and the gitlab container will respond on ports 22222 for ssh git operations and the internal 82 which we are going to use with a proxy from a nginx server already running on port 80 on the host:

nano /etc/nano/sites-enabled/yourdomain.com
server {
    server_name mygit.yourdomain.com;
    location / {
        #you may like to have a basic auth on top of the gitlab's one:
        #auth_basic "Restricted";
        #auth_basic_user_file /your/path/to/.htpasswd;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_read_timeout 300;
        proxy_pass http://172.17.42.1:82;
    }
}

Restart/reload nginx’s configuration:

/etc/init.d/nginx reload

Now go to mygit.yourdomain.com and the login page should be shown. Use these defaults:

user: [email protected]
pass: 5iveL!fe

Create a new project and you’ll see the url to the gitlab repo you’re going to use from now on is like:

git remote add origin ssh:[email protected]:22222/root/test-project.git

Add one or more public ssh keys in gitlab’s interface and start using it! 🙂