We will take the Run GitLab on Kubernetes journey and show, step by step, how you can run a containerized GitLab not just on Kubernetes but on any system with Docker enabled. As well as demonstrating the commands to run, we will also attempt to describe the various settings and configs we can modify to make the most out of GitLab. GitLab is a fully open source version-control system that hosts source-code repositories via the Git protocols up as well as ad-hoc pages, wikis, issue tracking, and integrated CI. While a fully hosted and managed Git service is often preferable, there are plenty of reasons to run and host one yourself. For the sake of this post, we will concentrate on GitLab CE (Community Edition), and we will use the official Docker images provided by them. To run GitLab, you need GitLab itself, as well as a PostgreSQL database and a Redis in-memory data structure store. The GitLab CE Docker image allows you run it in an all-in-one mode, where GitLab and both data stores are run in a single container. It also allows you to connect to external data services. For more information about the architecture of GitLab, or to skip straight to running Gitlab on Kubernetes, check out our Run GitLab on Kubernetes journey.

1. Install Docker CLI

If you don’t already have Docker installed on your machine, your first step will be to install it by following the instructions for your preferred operating system. Note: This guide was developed on a Linux laptop, so when we access Docker or running containers, we use 127.0.0.1; for some operating systems that run Docker in a VM, you may need to replace instances of 127.0.0.1 with the contents of your $DOCKER_HOST environment variable.

2. Run GitLab CE

You can run it in an all-in-one mode via Docker directly or with external data services using Docker Compose. If you’re new to Docker, start with just running GitLab CE with Docker below (2.1); if you are already comfortable with Docker, you might want to skip straight to running it with Docker Compose (2.2).

2.1 Single-container deployment via Docker

The easiest, but least versatile way to deploy GitLab CE is to launch it directly on your laptop already running Docker. By default, GitLab includes Postgres and Redis in the container to make it easy to run as just a single container. To launch GitLab, run the following Docker command:
$ sudo docker run --detach --name gitlab \
	--hostname gitlab.example.com \
	--publish 30080:30080 \
         --publish 30022:22 \
	--env GITLAB_OMNIBUS_CONFIG="external_url 'http://gitlab.example.com:30080'; gitlab_rails['gitlab_shell_ssh_port']=30022;" \
	gitlab/gitlab-ce:9.1.0-ce.0




Let’s break down that docker command a bit to show exactly how it’s working:
  • In the first line, we’re setting --detach --name gitlab, which simply tells Docker to run it in the background and give the running container the name “gitlab.” Next, we’re setting --hostname gitlab.example.com, which sets the hostname inside the container that GitLab will use to try and determine the Git URLs to provide back to the user.
  • The next two publish lines tell Docker to expose the HTTP and SSH ports from GitLab on ports 30080 and 30022, respectively.
  • Next, we’re setting an environment variable GITLAB_OMNIBUS_CONFIG, which is passing GitLab config options into GitLab. The two we’re setting are to let GitLab know the ports to use and to expose to the users when accessing the GitLab web interface. Otherwise, when somebody creates a Git repo, it may provide the wrong URL or port for them to interact with it via Git. See the available config options that can be set this way.
  • Finally, we’re giving the GitLab Docker image and version to use.
Wait a few minutes to let GitLab start inside the container (you can view progress with docker logs -f gitlab), then access it via http://127.0.0.1:30080 (or use your $DOCKER_HOST IP if it’s not localhost). Skip down to the Using GitLab section for the next steps, and once you’re done, you can kill it off using docker rm -f gitlab. Since we’re not mapping any volumes in, there is no extra data to clean up on your host.

2.2 Multiple-container deployment via Docker Compose

Before you begin, download Docker Compose if you don’t already have it installed. In the basic Docker example, we demonstrated how to run GitLab CE in an all-on-one Docker container. However, this is not representative of how you should run it in production. If you were going to run it in production, you’d want to use external data services for PostgreSQL and Redis, as well as store the GitLab filesystem somewhere that will persist. Thankfully, the GitLab CE Docker image makes it easy to do these things. And by utilizing Docker Compose, we can demonstrate this quite easily by creating extra Docker containers for them to run in, then set the GITLAB_OMNIBUS_CONFIG environment variable to tell GitLab to utilize these services instead. We have already prepared a docker-compose.yml file in our example Git repo for running GitLab, which we will utilize for this example. The Docker Compose file calls for three Docker containers (GitLab, Postgres, Redis) to be run and linked together utilizing their upstream official Docker images. Let go through them one at a time:

Redis

Gitlab CE uses Redis to store user sessions and a task queue. In production, you would want it to be a bit more resilient than we show here, but for the most part, the data stored in Redis is not critical, so we’re opting to not persist any data for it for this demo. So its entry in our docker-compose manifest is fairly simple:
redis:
  restart: always
image: redis:3.0.7-alpine


PostgreSQL

GitLab CE uses PostgreSQL as its database back end, where it stores users, Git repo information, and more. In a production environment, you would want this database to persist its data on a persistent data store and perform backups (and perhaps even database replication). In our docker-compose manifest, we have the option to persist the data to the local machine’s disks by uncommenting out the volumes: section. You can also see where we specify the username, password, and database name to be created for GitLab to use:
postgresql:
  restart: always
  image: postgres:9.6.2-alpine
  environment:
	- POSTGRES_USER=gitlab
	- POSTGRES_PASSWORD=gitlab
	- POSTGRES_DB=gitlabhq_production
# the following are hints on what volumes to mount if you want to persist data
#  volumes:
#	- data/postgresql:/var/lib/postgresql:rw


GitLab CE

Finally, we have the GitLab image itself. This is the same image we used above for the plain Docker example, except we’re setting a few more configuration settings to tell it how to connect to Redis and Postgres. Like in the Docker example, we are setting the hostname and port settings. However, we are also setting GitLab configuration settings to tell it to disable its own internal Postgres/Redis services and instead are passing in the configuration options to use the external containers and using Docker links to make the GitLab container aware of the other two by name. Like the Postgres example above, you can uncomment out the volumes section to persist the data locally:

gitlab:
  image: 'gitlab/gitlab-ce:9.1.0-ce.0'
  restart: always
  hostname: 'gitlab.example.com'
  links:
	- postgresql:postgresql
	- redis:redis
  environment:
	GITLAB_OMNIBUS_CONFIG: |
  	postgresql['enable'] = false
  	gitlab_rails['db_username'] = "gitlab"
  	gitlab_rails['db_password'] = "gitlab"
  	gitlab_rails['db_host'] = "postgresql"
  	gitlab_rails['db_port'] = "5432"
  	gitlab_rails['db_database'] = "gitlabhq_production"
  	gitlab_rails['db_adapter'] = 'postgresql'
  	gitlab_rails['db_encoding'] = 'utf8'
  	redis['enable'] = false
  	gitlab_rails['redis_host'] = 'redis'
  	gitlab_rails['redis_port'] = '6379'
  	external_url 'http://gitlab.example.com:30080'
  	gitlab_rails['gitlab_shell_ssh_port'] = 30022
  ports:
# both ports must match the port from external_url above
	- "30080:30080"
# the mapped port must match ssh_port specified above.
	- "30022:22"
# the following are hints on what volumes to mount if you want to persist data
#  volumes:
#	- data/gitlab/config:/etc/gitlab:rw
#	- data/gitlab/logs:/var/log/gitlab:rw
#	- data/gitlab/data:/var/opt/gitlab:rw


Start by cloning our example Git repo for running GitLab locally, or just download the docker-compose file directly. Make the appropriate changes to it to enable volumes or change ports and start it:
$ git clone https://github.com/IBM/Kubernetes-container-service-GitLab-sample.git gitlab
$ cd gitlab
$ docker-compose up -d
Starting kubernetescontainerservicegitlabsample_redis_1
Starting kubernetescontainerservicegitlabsample_postgresql_1
Recreating kubernetescontainerservicegitlabsample_gitlab_1


It will take a few minutes to start. You can watch progress with docker-compose logs -f if you want. Once it’s ready, you can access it via http://127.0.0.1:30080 (or use your $DOCKER_HOST IP if it’s not localhost). Skip down to the using GitLab section for next steps. Once you’re done, you can kill it off using docker-compose stop followed by docker-compose rm. If you uncommented out the volumes sections, you also may want to clean up the volumes that you passed in.

3. Using GitLab CE

In both deployment scenarios above, we set our GitLab CE hostname to gitlab.example.com. The first thing we’ll do is update our local DNS to use that URL. In Linux or OSX, this can be done by adding the following to your /etc/hosts file:

127.0.0.1 gitlab.example.com
Note: If your DOCKER_HOST is not localhost, you will want to replace 127.0.0.1 with the IP of your docker host.

With this set and GitLab CE running from either of the above scenarios, you should be able to access GitLab at http://gitlab.example.com:30080. You should see the following screen. The first time you access your GitLab CE install, it will prompt you to change your password. This is for your admin user with the username root. Set a password and click the Change your password button:

You can use this password to sign in as the root user:

Once logged in, you can scroll down and click the new project button and create a new project called test:

GitLab will create the new project and give you a screen showing you how to use the new repo:

We’ll follow the those instructions:
$ cd /tmp
$ mkdir test_repo
$ cd test_repo
$ git init
$ git config user.name "Administrator"
$ git config user.email "admin@example.com"
$ echo "# hello world" >  README.md
$ git add .
$ git commit -m 'hello world'
$ git remote add origin http://root@gitlab.example.com:30080/root/test.git
$ git push -u origin master
Password for 'http://root@gitlab.example.com:30080':
Counting objects: 3, done.
Writing objects: 100% (3/3), 233 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://root@gitlab.example.com:30080/root/test.git
 * [new branch]  	master -> master
Branch master set up to track remote branch master from origin.
If you refresh your browser, you will now see your newly created Git repo with a README.md:

4. What’s next?

Now that GitLab is installed, there are plenty of things you can do with it. If you have used GitHub, GitLab, or any Git tooling before, it should be fairly easy and intuitive from here. If you’re new to it, GitLab has some excellent documentation. If you’re interested in going further with this, you can look at our Run GitLab on Kubernetes journey and its accompanying code repo, where we have even more deployment scenarios and show you how to deploy it on Kubernetes, or to IBM Bluemix® using the Bluemix DevOps toolchain and a Compose PostgreSQL database via Bluemix. You can also reach out to our Developer Advocate team to learn more about utilizing Bluemix services or if you’re interested in setting up a demo or a workshop for any of these tools or techniques.

9 comments on"A step-by-step guide to running GitLab CE in Docker"

  1. Thanks for great tutorial. I’m wondering where is the gitlab data stored?
    I want to backup all of my git project to a new container, is it possible?

  2. Hi Paul,
    I am facing issue.
    Below is the description:
    If my container exist then all my images got lost and their respective data as well.
    Could you please answer how to save the data (Here in this case of gitlab,we have multiple branches).How to save those branches even if container exist and next time when we restart that branch I shoul get all my branches?
    Thanks,
    Rahul

  3. Hello,
    Please advise how to update GitLab to a new version if it is running in Docker?

  4. Thanks for the tutorial. It’s a good place to start using a dockerized gitlab.

  5. Hi Paul,

    when i do docker-compose up -d and try to call gitlab in the browser i get Error 500.
    Can you help me to find my mistake?

    Thx

  6. Hello !

    Can you explain me why the port binding is “30080:30080” and not “30080:80” ?

  7. Great article, I had struggled for several hours trying to get gitlab-ce / docker up and running on my macbook.

Join The Discussion

Your email address will not be published. Required fields are marked *