How to Configure GitLab Runner with Docker Executor on Ubuntu 24.04 EC2
In this tutorial, we will configure a self-hosted GitLab Runner with Docker Executor on an AWS EC2 Ubuntu 24.04 instance.
With the Docker executor, each GitLab CI/CD job runs inside an isolated Docker container. This allows the same runner to execute pipelines using different environments such as Maven, Python, Node.js, or Ubuntu without installing all of those tools directly on the EC2 instance.
Architecture
Developer → GitLab Repository → GitLab CI/CD Pipeline → Self-Hosted GitLab Runner → Docker Executor → Docker Container → Execute CI/CD Job
Prerequisites
Before starting, make sure you have:
- AWS account
- Ubuntu 24.04 EC2 instance
- GitLab account
- GitLab project
- SSH access to the EC2 instance
sudoprivileges
For a learning environment, an EC2 instance with at least 2 GB RAM is recommended.
Step 1 — Connect to Ubuntu EC2
SSH into the EC2 instance:
ssh -i your-key.pem ubuntu@<EC2-PUBLIC-IP>Verify the operating system:
cat /etc/os-releaseYou should see Ubuntu 24.04 LTS.
Step 2 — Update Ubuntu
Update the package information:
sudo apt updateStep 3 — Install Docker
Install Docker:
sudo apt install docker.io -yStart Docker:
sudo systemctl start dockerEnable Docker during system startup:
sudo systemctl enable dockerVerify:
sudo systemctl status dockerCheck the Docker version:
docker --versionStep 4 — Test Docker
Run:
sudo docker run hello-worldIf Docker is configured correctly, Docker downloads the test image and starts a container.
Step 5 — Install GitLab Runner
Add the official GitLab Runner repository:
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bashInstall GitLab Runner:
sudo apt install gitlab-runner -yVerify:
gitlab-runner --versionCheck the service:
sudo systemctl status gitlab-runnerStep 6 — Allow GitLab Runner to Access Docker
The GitLab Runner service normally runs using the gitlab-runner Linux account.
Add that account to the docker group:
sudo usermod -aG docker gitlab-runnerRestart Docker:
sudo systemctl restart dockerRestart GitLab Runner:
sudo systemctl restart gitlab-runnerNow verify that the GitLab Runner account can communicate with Docker:
sudo -u gitlab-runner docker infoIf this command works successfully, the runner should be able to use the Docker executor.
Step 7 — Create a Runner in GitLab
Open your GitLab project.
Navigate to:
Settings → CI/CD → Runners
Create a new project runner.
You can configure a runner tag such as:
dockerGitLab will provide a runner authentication token.
Keep this token secure.
Step 8 — Register the GitLab Runner
On your Ubuntu EC2 instance, run:
sudo gitlab-runner registerEnter the GitLab URL:
https://gitlab.com/Enter the runner authentication token provided by GitLab.
When prompted for the executor, enter:
dockerWhen prompted for the default Docker image, enter:
ubuntu:24.04The runner should now be registered.
Step 9 — Verify the Runner
List configured runners:
sudo gitlab-runner listVerify connectivity with GitLab:
sudo gitlab-runner verifyCheck the service:
sudo systemctl status gitlab-runnerGo back to:
GitLab → Project → Settings → CI/CD → Runners
The runner should appear online.
Step 10 — Review GitLab Runner Configuration
The system-mode GitLab Runner configuration is normally stored here:
sudo cat /etc/gitlab-runner/config.tomlYou should see configuration similar to:
[[runners]]
name = "ubuntu-docker-runner"
executor = "docker"
[runners.docker]
image = "ubuntu:24.04"The exact configuration generated by your GitLab Runner version can contain additional settings.
Step 11 — Create a Simple GitLab CI/CD Pipeline
Create a file in the root of your GitLab repository:
.gitlab-ci.ymlAdd:
stages:
- test
test-docker-runner:
stage: test
tags:
- docker
image: ubuntu:24.04
script:
- echo "GitLab Docker Runner is working!"
- hostname
- whoami
- cat /etc/os-releaseCommit and push the file.
GitLab should automatically start a pipeline.
Step 12 — Verify the Pipeline
The pipeline flow is:
↓
GitLab CI/CD Pipeline
↓
Self-Hosted GitLab Runner
↓
Docker Executor
↓
Pull
ubuntu:24.04 Docker Image↓
Create Temporary Container
↓
Execute CI/CD Commands
↓
Job Completes
The job container is temporary. GitLab Runner creates the container for the job and removes it after the job finishes.
Understanding Docker Executor
One of the major advantages of Docker executor is that the EC2 instance does not need every development tool installed directly on the host.
For example, a Maven job can use:
build:
image: maven:3.9-eclipse-temurin-17
script:
- mvn clean packageAnother job on the same runner could use:
test:
image: ubuntu:24.04
script:
- echo "Running Ubuntu container"Therefore, a single Docker executor can support many different CI/CD workloads.
Common Error 1 — Docker Socket Permission Denied
You may encounter:
permission denied while trying to connect to the Docker daemon socket
unix:///var/run/docker.sockCheck Docker access:
sudo -u gitlab-runner docker infoIf access is denied, make sure the runner account belongs to the Docker group:
sudo usermod -aG docker gitlab-runner
sudo systemctl restart docker
sudo systemctl restart gitlab-runnerTest again:
sudo -u gitlab-runner docker infoCommon Error 2 — ubuntu-latest Image Cannot Be Pulled
You may see:
Failed to pull image "ubuntu-latest"
pull access denied for ubuntu-latest,
repository does not existDo not use:
ubuntu-latestThat naming is commonly seen with GitHub Actions runners:
runs-on: ubuntu-latestFor a Docker image, specify the repository and tag:
ubuntu:24.04For example:
image: ubuntu:24.04If the default image is configured incorrectly, edit:
sudo nano /etc/gitlab-runner/config.tomlChange:
image = "ubuntu-latest"to:
image = "ubuntu:24.04"Then restart:
sudo systemctl restart gitlab-runnerCommon Error 3 — Job Stuck in Pending
If you see:
This job is in pending state and is waiting to be picked by a runnerCheck whether the runner is online:
sudo gitlab-runner verifyCheck the service:
sudo systemctl status gitlab-runnerAlso verify that the tags in .gitlab-ci.yml match the tags assigned to the GitLab Runner.
For example:
tags:
- dockerrequires a runner capable of accepting jobs with the docker tag.
Common Error 4 — Runner Started in User Mode
If you run:
gitlab-runner runwithout sudo, you may see:
WARNING: Running in user-mode.
Starting multi-runner from /home/ubuntu/.gitlab-runner/config.tomlFor a server-based self-hosted runner, it is generally better to install and operate GitLab Runner as a system service.
Register using:
sudo gitlab-runner registerThe system configuration is then normally maintained under:
/etc/gitlab-runner/config.tomlManage the runner using:
sudo systemctl start gitlab-runner
sudo systemctl stop gitlab-runner
sudo systemctl restart gitlab-runner
sudo systemctl status gitlab-runnerUseful Troubleshooting Commands
Check GitLab Runner:
sudo gitlab-runner listVerify registered runners:
sudo gitlab-runner verifyCheck Runner service:
sudo systemctl status gitlab-runnerCheck Runner logs:
sudo journalctl -u gitlab-runner -fCheck Docker:
sudo systemctl status dockerCheck Docker access for the runner:
sudo -u gitlab-runner docker infoList running containers:
docker psList all containers:
docker ps -aConclusion
We successfully configured a self-hosted GitLab Runner using Docker Executor on an Ubuntu 24.04 AWS EC2 instance.
The architecture is:
Developer → GitLab → GitLab CI/CD → Self-Hosted Runner → Docker Executor → Job Container
Using Docker executor provides isolation and flexibility because different CI/CD jobs can use different container images without requiring every build tool to be installed directly on the runner EC2 instance.
You can now extend this setup to build real CI/CD pipelines using:
- Maven and Java
- SonarQube
- Trivy
- Docker
- Terraform
- Python
- Node.js
- Other DevSecOps tools


