Gitlab CE Docker and external Nginx Reverse Proxy#
Gitlab provides official Docker images. The following config shows the integration in nginx of an out of the box gitlab container with docker-compose.yml.
docker-compose#
version "2"
services:
gitlab:
image: 'gitlab/gitlab-ce:latest'
restart: always
ports:
- '80:80'
- '443:443'
- '22:22'
volumes:
- '/srv/gitlab/config:/etc/gitlab'
- '/srv/gitlab/logs:/var/log/gitlab'
- '/srv/gitlab/data:/var/opt/gitlab'
Gitlab#
In /etc/gitlab/gitlab.rb
(from within the container) or in /srv/gitlab/config/gitlab.rb
from within the host:
external_url 'https://domain.tld/gitlab/'
nginx['listen_port'] = 80
nginx['listen_https'] = false
nginx['proxy_set_headers'] = {
"X-Forwarded-Proto" => "https",
"X-Forwarded-Ssl" => "on"
}
After changing the config reconfigure gitlab:
# open a bash in the gitlab container
docker exec -it gitlab bash
# reconfigure gitlab
gitlab-ctl reconfigure
Nginx Settings#
server {
listen 443 ssl;
server_name domain.tld;
index index.html index.htm;
error_log /var/log/nginx/error.log error;
location /gitlab {
client_max_body_size 0;
gzip off;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
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;
proxy_pass http://<gitlab>:80;
}
ssl_certificate /etc/nginx/cert.pem;
ssl_certificate_key /etc/nginx/cert.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# intermediate configuration. tweak to your needs.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
}
Reload nginx:
# check config syntx
nginx -t
# reload
nginx -s reload
CI/CD#
Install gitlab-runner#
docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest
More install options are available
Register gitlab-runner#
Run in your runner host (here in the docker container)
sudo gitlab-runner register
- Get your token from
/admin/runners
of your Gitlab instance - Set your executioner (here docker)
- No tags, allow untagged jobs, no shared runner (without those settings the runner stuck)
Basic maven build#
add and push .gitlab-ci.yml
in your project root
image: maven:latest
verify:
stage: build
script:
- mvn verify
build:
stage: build
script:
- mvn compile
Gitlab Pages#
Recommended: wildcard domain and corresponding SSL certificate
- Assign a runner to a group of projects in Gitlab runner
- Start runner
docker run -d --name gitlab-runner-public --restart always -v /srv/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest
- Register runner
The docker image used can be overwritten in the .gitlab-ci.yml of your pipeline
- interactive:
docker exec -it gitlab-runner-public bash
- gitlab-runner register
- docker as default executioner
- alpine as default image
- or non interactive
docker run --rm -t -i -v /path/to/config:/etc/gitlab-runner --name gitlab-runner gitlab/gitlab-runner register \ --non-interactive \ --executor "docker" \ --docker-image alpine:3 \ --url "https://gitlab.com/" \ --registration-token "PROJECT_REGISTRATION_TOKEN" \ --description "docker-runner" \ --tag-list "docker,aws" \ --run-untagged \ --locked="false"
- interactive:
1. Setup [Pages](https://gitlab.com/pages) (wildcard domain with TLS support)
gitlab.rb
```ruby
pages_external_url "https://pages.rootknecht.net/"
gitlab_pages['enable'] = true
gitlab_pages['inplace_chroot'] = true # in case of gitlab-pages daemon not starting due to bind mount permission error
pages_nginx['redirect_http_to_https'] = true
pages_nginx['ssl_certificate'] = "/etc/gitlab/ssl/pages-nginx.crt"
pages_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/pages-nginx.key"
```
Reconfigure and restart
```bash
gitlab-ctl reconfigure
gitlab-ctl restart gitlab-pages
```
Debugging
```bash
# get logs (run in container)
gitlab-ctl tail gitlab-pages
# path of your pages (in container)
ls /var/opt/gitlab/gitlab-rails/shared/pages
# error log of bundled nginx
/var/log/gitlab/nginx/gitlab_pages_error.log
```
### Basic Pages Pipeline
Publish static html content with following `.gitlab-ci.yml`
```yaml
image: alpine:latest
pages:
stage: deploy
script:
- echo 'Nothing to do...'
artifacts:
paths:
- public # this is the path in your repo to publish
only:
- master
LDAP and Mail integration#
In gitlab.rb
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "<SMTP Host>"
gitlab_rails['smtp_port'] = "587"
gitlab_rails['smtp_user_name'] = "<user>"
gitlab_rails['smtp_password'] = "<password>"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_openssl_verify_mode'] = 'none' # change if there are valid certificates
gitlab_rails['gitlab_email_from'] = "<MAIL FROM>"
gitlab_rails['gitlab_email_reply_to'] = "<REPLY TO>"
gitlab_rails['ldap_enabled'] = true
gitlab_rails['ldap_servers'] = {
'main' => {
'label' => 'Description',
'host' => '<LDAP-HOST',
'port' => 389, # 636 for secured connection
'uid' => 'sAMAccountName',
'verify_certificates' => true,
'bind_dn' => '<can be full bind or username>',
'password' => '<password>',
'method' => 'plain', # change for enrypted connections
'base' => '<BASE DN>',
'active_directory' => true, # true only for Microsoft AD
'allow_username_or_email_login' => true,
'user_filter' => '(&(objectCategory=Person)(sAMAccountName=*))'
}
}
Deploy Gitlab with Docker on NixOS#
Install docker service#
Add virtualisation.docker.enable = true;
and optionally extraGroups= [ "docker" ]
to a user who needs to control docker to your configuration.nix file.
Install docker-compose#
Add python36Packages.docker_compose
to environment.systemPackages
Open firewall ports#
networking.firewall.allowedTCPPorts = [ 80 443 ]
Create docker-compose.yml#
version: '2'
services:
web:
image: 'gitlab/gitlab-ce:latest'
restart: always
hostname: 'gitlab'
ports:
- '80:80'
- '443:443'
- '50222:22'
volumes:
- '/srv/gitlab/config:/etc/gitlab'
- '/srv/gitlab/logs:/var/log/gitlab'
- '/srv/gitlab/data:/var/opt/gitlab'
Run docker-compose up -d
to start the service in the background. You should now be able to access gitlab with your machine’s IP
Install openssl and generate certificates#
Add openssl
to environment.systemPackages
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
Gitlab configuration#
The main configuration file is /srv/gitlab/config/gitlab.rb
(adjust your path according to your docker-compose file)
Enable https#
In gitlab.rb put ’external_url “
https://gitlab.example.com”’. Gitlab will look after your certificates according to your hostname - here /etc/gitlab/ssl/gitlab.example.com.key
and /etc/gitlab/ssl/gitlab.example.com.crt
.
/srv/gitlab/config/ssl/
cert.pem
and cert.key
to this folder and rename them. The cert.pem file is the .crt file and the key.pem the .key file.Now connect to your container with docker exec -it gitlab_web_1
and run gitlab-ctl reconfigure
inside your container.
Redirect http#
After enabling https gitlab does not listen to http anymore. To redirect incoming http traffic to https put nginx['redirect_http_to_https'] = true
in your gitlab.rb file.