# How to use Docker to build a Self-Host GitLab and GitLab Runner


Recently, due to the team demand to replace Gerrit, I used docker to build a self-host GitLab and GitLab Runner for the company. One of the points mentioned here is GitLab Runner is a plug-in to help GitLab run CI, a bit like Jenkins Slave Node, used to cascade GitLab CI.

This is mainly divided into three parts

1. Build GitLab

1. Build and connect GitLab Runner

1. Set up auto backup and restore

## Build GitLab

### Step 1：Pull official image

```
docker pull gitlab/gitlab-ce
```


### Step 2：Create docker-compose.yml

Create a `docker-compose.yml` and replace `{host_ip}` to the actual IP address of the server.

```
version: "3.6" 
services:
  web:
    image: 'gitlab/gitlab-ce'
    container_name: 'gitlab'
    restart: always
    hostname: {host_ip}
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://{host_ip}:9090'
        gitlab_rails['gitlab_shell_ssh_port'] = 2224
    networks:
      - gitlab-network
    ports:
      - '80:80'
      - '443:443'
      - '9090:9090'
      - '2224:22'
    volumes:
      - '/srv/gitlab/config:/etc/gitlab'
      - '/srv/gitlab/logs:/var/log/gitlab'
      - '/srv/gitlab/data:/var/opt/gitlab'

networks:
  gitlab-network:
    name: gitlab-network
```


### Step 3：Start GitLab

```
docker-compose up --build --abort-on-container-exit
```


At first time to start GitLab, you need to wait 3 or 5 mins. After that, you could open browser and typing `{host_ip}:9090` to connect to your GitLab to reset the password. The default username is `root` .

## Build and connect GitLab Runner

At this step, you need to prepare another server for GitLab Runner. Because when GitLab Runner clone your repo that will parse issue for localhost. I am not sure how to fix this, it may due to I used dind（docker in docker） with GitLab Runner. By the way, GitLab could connect to multiple Runner and Runners could host at same server. Just remember to name different container name and mount a different volume.

### Step 1：start GitLab Runner

Replace `{runner-name}` to your container name.

```
docker pull gitlab/gitlab-runner
docker run -d --name {runner-name} -v /var/run/docker.sock:/var/run/docker.sock -v /srv/{runner-name}/config:/etc/gitlab-runner --rm gitlab/gitlab-runner
```


### Step 2：Find registration token

After step 1, you could go to GitLab website to find Runner Registration Token which locate at **Admin Area** &gt; **Overview** &gt; **Runners** .

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1615084532046/dU7xFs6Jf.png)

### Step 3：

Get the token from step2 to replace `{registration-token}` below and run. `{gitlab-ip}` replace to GitLab Server IP address. `{runner-name}` replace to the container name which Runner want to be connected.

```
docker exec -it {runner-name} gitlab-runner register -n --url http://{gitlab-ip}:9090 --registration-token {registration-token} --clone-url http://{gitlab-ip}:9090 --executor docker --docker-image "docker:latest" --docker-privileged
```


## Setup auto backup and restore

### Backup

Edit `/srv/gitlab/config/gitlab.rb` and add some setting. Here is my configuration to backup to AWS S3. If you want another backup place like GCP or Local, you could refer [official website](https://docs.gitlab.com/ce/raketasks/backup_restore.html#uploading-backups-to-a-remote-cloud-storage).

```
gitlab_rails['backup_keep_time'] = 86400

gitlab_rails['backup_upload_connection'] = {
  'provider' => 'AWS',
  'region' => 'us-west-1',
  'aws_access_key_id' => {access key id},
  'aws_secret_access_key' => {secret access key}
}
gitlab_rails['backup_upload_remote_directory'] = 'gitlab'
```


When you finish, it needs to let GitLab reload the new configuration.

```
docker exec -t gitlab-master gitlab-ctl reconfigure
```


This command will generate backup files and upload to AWS S3.

```
docker exec -t gitlab-master gitlab-rake gitlab:backup:create
```


### Restore

1. According to the `docker-compose.yml` at the first step to restart GitLab

1. While GitLab is ready, you could download backup files from S3 to `/srv/gitlab/data/backups` . `aws s3 cp {s3 backup file url} {backup file name}`

1. Finally, operate restore command.
`docker exec -it gitlab-master gitlab-rake gitlab:backup:restore`
If you have multiple backup files at the folder then you need to specify which backup file you want to use to restore.
`docker exec -it gitlab-master gitlab-rake gitlab:backup:restore BACKUP={prefix backup file name before gitlab_backup.tar}`

### Cron

The last thing you need to do is create a cron job to auto backup your GitLab. I use the Linux cron to handle this. I set a job to execute backup instruction at every midnight on Friday.

```
$ crontab -e
0 0 * * FRI docker exec -t gitlab-master gitlab-rake gitlab:backup:create
```


