GitLab
gitlab self-hosted
Prerequisites
- Docker and Docker Compose installed.
- A basic understanding of Docker and GitLab.
Directory Structure First, create the directory structure where GitLab’s configuration, data, and logs will reside:
1
2
3
4
5
6
./gitlab
├── config
│ └── gitlab.rb
├── data
├── logs
└── docker-compose.yaml
Step 1: Create docker-compose.yaml
Create a docker-compose.yaml
file to define the GitLab service. Here’s a simple configuration:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
services:
gitlab:
image: gitlab/gitlab-ce:latest
container_name: gitlab
networks:
- proxy
ports:
- 80:80
- 2222:22
- 5005:5005
volumes:
- ./config:/etc/gitlab
- ./logs:/var/log/gitlab
- ./data:/var/opt/gitlab
shm_size: '256m'
restart: unless-stopped
labels:
# traefik_gitlab
- "traefik.enable=true"
- "traefik.http.routers.gitlab.rule=Host(`gitlab.example.com`)"
- "traefik.http.routers.gitlab.entrypoints=websecure"
- "traefik.http.routers.gitlab.tls=true"
- "traefik.http.routers.gitlab.tls.certresolver=cloudflare"
- "traefik.http.services.gitlab.loadbalancer.server.port=80"
# traefik_registry
- "traefik.http.routers.registry.rule=Host(`registry.gitlab.example.com`)"
- "traefik.http.routers.registry.entrypoints=websecure"
- "traefik.http.routers.registry.tls=true"
- "traefik.http.routers.registry.tls.certresolver=cloudflare"
- "traefik.http.services.registry.loadbalancer.server.port=5005"
# network traefik
networks:
proxy:
external: true
- Explanation:
- The gitlab service is using the gitlab/gitlab-ce image.
- The volumes section ensures that GitLab’s configuration, logs, and data are persistent.
- Traefik labels are used for reverse proxy configurations.
Step 2: Edit gitlab.rb Configuration
GitLab’s configuration is stored in the gitlab.rb
file. Edit it to set GitLab-specific settings:
1
2
3
4
5
6
7
8
9
10
11
12
13
# Add any other gitlab.rb configuration here, each on its own line
gitlab_rails['gitlab_shell_ssh_port'] = 2222
external_url 'https://gitlab.example.com'
letsencrypt['enable'] = false
nginx['listen_port'] = 80
nginx['listen_https'] = false
# registry
registry['enable'] = true
gitlab_rails['registry_enabled'] = true
registry_external_url 'https://registry.gitlab.example.com'
registry_nginx['listen_port'] = 5005
registry_nginx['listen_https'] = false
registry_nginx['proxy_set_headers'] = {"X-Forwarded-Proto" => "https","X-Forwarded-Ssl" => "on"}
Step 3: Run GitLab with Docker Compose
Now, start the GitLab container:
1
sudo docker-compose up -d
Explanation: This command will run GitLab in detached mode using Docker Compose.
Step 4: Get Default Root Password
To get the default root password for GitLab, run the following command:
1
sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
Step 5: Troubleshoot with Logs
If you encounter issues, you can view the logs using:
1
sudo docker logs -f gitlab
Step 6: Apply GitLab Configuration
To apply any changes made in gitlab.rb, run:
1
sudo docker exec -it gitlab gitlab-ctl reconfigure
Install GitLab Runner
Step 1: Add GitLab Runner Repository
To install GitLab Runner, first, add the official GitLab repository:
1
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
Step 2: Install GitLab Runner
Next, install GitLab Runner:
1
sudo apt install gitlab-runner
Step 3: Register GitLab Runner
To register a GitLab Runner, generate a registration token from GitLab’s Settings > CI/CD > Runners page.
Then, run the following command to register the runner:
1
2
3
4
5
6
7
sudo gitlab-runner register \
--non-interactive \
--url "https://gitlab.example.com" \
--token "$RUNNER_TOKEN" \
--executor "docker" \
--docker-image alpine:latest \
--description "docker-runner" \
Explanation: This command registers a new GitLab Runner using Docker as the executor and the specified token.
— access-level creates a protected runner.
- For a protected runner, use the –access-level=”ref_protected” parameter.
- For an unprotected runner, use –access-level=”not_protected” or leave the value undefined.
— maintenance-note allows adding information you might find helpful for runner maintenance. The maximum length is 255 characters.
Backup and Restore
To back up your GitLab data, you can use the following command
1
sudo docker exec -t gitlab gitlab-rake gitlab:backup:create
To restore from a backup, use
1
sudo docker exec -t gitlab gitlab-rake gitlab:backup:restore BACKUP=<backup_file_name>
Outgoing Email (SMTP) with Gmail
Gmail’s SMTP server can be used to send emails from GitLab (e.g., notifications, password resets).
Steps to Configure SMTP with Gmail
you need to generate an App Password.
Update GitLab Configuration:
Edit the GitLab configuration file gitlab.rb
and add the following SMTP settings:
1
2
3
4
5
6
7
8
9
10
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.gmail.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "[email protected]"
gitlab_rails['smtp_password'] = "my-gmail-password"
gitlab_rails['smtp_domain'] = "smtp.gmail.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'peer' # Can be: 'none', 'peer', 'client_once', 'fail_if_no_peer_cert', see http://api.rubyonrails.org/classes/ActionMailer/Base.html
Test SMTP
Send a test email from GitLab to verify the SMTP configuration:
1
2
sudo docker exec -it gitlab gitlab-rails console
Notify.test_email('[email protected]', 'Test Subject', 'Test Body').deliver_now
Incoming Email (IMAP) with Gmail
Gmail’s IMAP server can be used to enable features like Reply by Email and Service Desk.
Steps to Configure IMAP with Gmail Enable IMAP in Gmail:
Go to your Gmail settings → Forwarding and POP/IMAP.
Enable IMAP access.
Update GitLab Configuration:
Edit the GitLab configuration file gitlab.rb
and add the following IMAP settings:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
gitlab_rails['incoming_email_enabled'] = true
# The email address including the %{key} placeholder that will be replaced to reference the
# item being replied to. This %{key} should be included in its entirety within the email
# address and not replaced by another value.
# For example: emailaddress+%{key}@gmail.com.
# The placeholder must appear in the "user" part of the address (before the `@`).
gitlab_rails['incoming_email_address'] = "gitlab-incoming+%{key}@gmail.com"
# Email account username
# With third party providers, this is usually the full email address.
# With self-hosted email servers, this is usually the user part of the email address.
gitlab_rails['incoming_email_email'] = "[email protected]"
# Email account password
gitlab_rails['incoming_email_password'] = "[REDACTED]"
# IMAP server host
gitlab_rails['incoming_email_host'] = "imap.gmail.com"
# IMAP server port
gitlab_rails['incoming_email_port'] = 993
# Whether the IMAP server uses SSL
gitlab_rails['incoming_email_ssl'] = true
# Whether the IMAP server uses StartTLS
gitlab_rails['incoming_email_start_tls'] = false
# The mailbox where incoming mail will end up. Usually "inbox".
gitlab_rails['incoming_email_mailbox_name'] = "inbox"
# The IDLE command timeout.
gitlab_rails['incoming_email_idle_timeout'] = 60
# If you are using Microsoft Graph instead of IMAP, set this to false if you want to retain
# messages in the inbox because deleted messages are auto-expunged after some time.
gitlab_rails['incoming_email_delete_after_delivery'] = true
# Whether to expunge (permanently remove) messages from the mailbox when they are marked as deleted after delivery
# Only applies to IMAP. Microsoft Graph will auto-expunge any deleted messages.
gitlab_rails['incoming_email_expunge_deleted'] = true
Conclusion
By following these optimized steps, you’ll have a well-configured GitLab instance running on Docker with added features like GitLab Runner, and email configurations.