Lightweight Dockerized GitLab Setup with CI/CD on Ubuntu

Robin Steiner
06/03/2025

Setting up a full-fledged GitLab instance can sometimes feel like a daunting task, especially when you just need a streamlined environment for your development workflow. In this blog post, I'll walk you through how I set up a lightweight, Dockerized GitLab instance on an Ubuntu server, complete with CI/CD capabilities, using Nginx, Certbot, and Docker Compose. This setup includes a GitLab Runner, which is an agent that handles your automated builds, tests, and deployments.

Why Docker?

Docker simplifies deployment by encapsulating applications and their dependencies into containers. This ensures consistency across different environments and makes scaling and managing applications much easier.

Prerequisites

  • An Ubuntu server with Docker and Docker Compose installed.
  • A domain name (e.g., gitlab.example.com and registry.gitlab.example.com).
  • Nginx and Certbot installed for reverse proxying and SSL certificate management.

Docker Compose Configuration (docker-compose.yaml)

Here's the core of our setup, defined in docker-compose.yaml:

version: '3.8'
services:
   gitlab:
      image: gitlab/gitlab-ee
      container_name: gitlab
      restart: always
      hostname: 'gitlab.example.com'
      environment:
         GITLAB_OMNIBUS_CONFIG: |
            gitlab_rails['gitlab_shell_ssh_port'] = 2422
            gitlab_rails['registry_enabled'] = true
            registry['enable'] = true
            registry['registry_http_addr'] = "0.0.0.0:5050"
            registry_nginx['enable'] = false
            registry_external_url 'https://registry.gitlab.example.com'
            external_url 'http://gitlab.example.com'
      ports:
         - '4431:443'
         - '8929:80'
         - '2422:22'
         - '5050:5050'
      volumes:
           - '$GITLAB_HOME/config:/etc/gitlab'
           - '$GITLAB_HOME/logs:/var/log/gitlab'
           - '$GITLAB_HOME/data:/var/opt/gitlab'
      shm_size: '256m'
      networks:
           - gitlab
   gitlab-runner:
      image: gitlab/gitlab-runner
      container_name: gitlab-runner
      restart: always
      depends_on:
           - gitlab
      volumes:
           - ./config/gitlab-runner:/etc/gitlab-runner
           - /var/run/docker.sock:/var/run/docker.sock
      networks:
           - gitlab

networks:
   gitlab:
      name: gitlab

Key Points

  • GitLab Service:
    • We use the gitlab/gitlab-ee image.
    • GITLAB_OMNIBUS_CONFIG configures GitLab, including SSH port, registry settings, and external URLs.
    • Ports are mapped for HTTP, HTTPS, SSH, and the registry.
    • Volumes are mounted for persistent data.
  • GitLab Runner Service:
    • The gitlab/gitlab-runner image is used for CI/CD.
    • It's linked to the GitLab service and mounts the Docker socket for running Docker commands within CI/CD jobs.
  • Network:
    • A custom Docker network (gitlab) ensures communication between services.

Nginx Configuration

We use Nginx as a reverse proxy to handle incoming requests and SSL termination.

Registry Nginx Configuration (/etc/nginx/sites-available/registry.gitlab.example.com)

server {
    listen 81;
    server_name registry.gitlab.example.com;

    server_tokens off;

    client_max_body_size 0;
    chunked_transfer_encoding on;

    location /
    {
        proxy_pass http://127.0.0.1:5050;
        proxy_set_header Host $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;
    }
}

GitLab Nginx Configuration (/etc/nginx/sites-available/gitlab.example.com)

upstream gitlab {
    server 127.0.0.1:8929 weight=1 fail_timeout=300s;
}

server {
    add_header 'Content-Security-Policy' 'upgrade-insecure-requests';

    server_name gitlab.example.com;

    location / {
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_redirect off;
        proxy_pass http://gitlab;

        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
    }

    location ~* /web/static/ {
        proxy_cache_valid 200 60m;
        proxy_buffering on;
        expires 864000;
        proxy_pass http://gitlab;
    }

    client_max_body_size 200M;
}

Certbot for SSL

Use Certbot to generate and install SSL certificates for your domain:

sudo certbot --nginx -d gitlab.example.com -d registry.gitlab.example.com

Starting GitLab and its Gitlab-Runner

docker-compose up -d

Once the containers are up, GitLab should be accessible under gitlab.example.com. Now you can go ahead and create your first project.

GitLab Runner Registration

Next, you can register the GitLab Runner. Obtain the registration token by going to your project and selecting Settings → CI/CD → Runners and creating a new project runner. blog-gitlab2.png

For now we want to run untagged jobs, so select this option an create the runner. blog-gitlab1.png

Now you can copy the token and finally, execute the following command:

docker exec -it gitlab-runner gitlab-runner register --non-interactive --registration-token <your-token> --locked=false --description docker-stable --url http://gitlab:80/ --clone-url https://gitlab.example.com --executor docker --docker-image docker:stable --docker-volumes "/var/run/docker.sock:/var/run/docker.sock" --docker-network-mode gitlab

Replace <your-token> with the actual registration token.

CI/CD Workflow

With the runner registered, you can define your CI/CD pipelines using .gitlab-ci.yml in your repositories.

Conclusion

This setup provides a lightweight and efficient GitLab environment with core CI/CD capabilities, perfect for small teams or individual developers. By leveraging Docker and Nginx, we've simplified deployment and ensured a secure and reliable workflow. The next blog entry "Streamlining Updates with Watchtower and GitLab CI/CD" will discuss how to extend this setup to enable automatic artifact building and subsequent deployment.

Überzeugt? Kontaktieren Sie uns!

Schicken Sie uns einfach eine Email an office@vorstieg.eu oder füllen Sie das folgende Kontakt-Formular aus: