Back to resources
// guide · self-hosting

Self-hosting GitLab

Your own GitLab, on your server: the code stays with you, no per-user subscription. Here's how I deploy it cleanly — Docker, HTTPS, backups, CI runners — and the sizing you shouldn't underestimate.

GuideJul 30, 2026~9 min · intermediate
GitLab CEDockerLet’s Encryptrunnersbackups
01

Why self-host

Two reasons dominate: sovereignty (source code never leaves your infra, useful for compliance) and cost at large team size (no per-seat license). The flip side: you’re the admin — backups, updates, availability.

i

The deployment principle (Docker, reverse proxy, HTTPS) is the same as in my Langfuse on EC2 guide.

02

The deployment

GitLab CE fits in a single Docker container, with config, logs and data in persisted volumes. The Omnibus image even handles the Let’s Encrypt certificate on its own.

docker-compose.ymlcopy
# docker-compose.yml — GitLab CE en un conteneur
services:
gitlab:
image: gitlab/gitlab-ce:latest
hostname: gitlab.mondomaine.com
restart: always
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.mondomaine.com'
# Let's Encrypt automatique
letsencrypt['enable'] = true
ports: ["80:80", "443:443", "22:22"]
volumes:
- ./config:/etc/gitlab
- ./logs:/var/log/gitlab
- ./data:/var/opt/gitlab
shm_size: "256m"
!

GitLab is hungry: count 4 GB RAM minimum, 8 GB comfortable. Below that, the first boot fails or crawls — don’t skimp on the instance.

03

The CI runners

GitLab without a runner runs no pipeline. A runner is a separate process that executes your CI jobs; you register it against the instance with a token.

shellcopy
# enregistrer un runner CI pour executer les pipelines
$ docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
gitlab/gitlab-runner:latest
$ docker exec -it gitlab-runner gitlab-runner register
i

Once runners are in place, you write your pipelines as in using GitLab CI/CD well.

04

Backups & maintenance

The point that separates a serious self-host from a time bomb. GitLab has a built-in backup command — but it doesn’t include the config and secrets, which you must back up separately.

shellcopy
# sauvegarde complete (repos + base) + la config a part
$ docker exec gitlab gitlab-backup create
# la config et les secrets ne sont PAS dans le backup principal :
$ docker cp gitlab:/etc/gitlab ./gitlab-config-backup
!

A backup never restored isn’t a backup. Test a full restore on a separate VM — that’s the whole point of backups that actually work.

05

Sources & further reading

01GitLab Docs — Install GitLab in a Docker containerThe official Docker-image install page: setup, config, backup, upgrades.02GitLab Docs — GitLab installation requirementsReference sizing: 8 vCPU and 16 GB RAM as the single-node baseline.03GitLab Docs — Configure SSL for a Linux package installationLet’s Encrypt is on by default when external_url uses HTTPS; automatic renewal included.04GitLab Docs — Back up GitLabStates plainly that gitlab.rb and gitlab-secrets.json are not in the backup.05GitLab Docs — Back up and restore overviewThe backup/restore overview — read it before testing your first restore.06GitLab Docs — Run GitLab Runner in a containerRun the runner in a container, mount the config volume, and upgrade it without losing it.07GitLab Docs — Registering runnersThe runner authentication token replaces the old registration token, removed in GitLab 20.0.08GitLab Docs — Upgrade GitLabUpgrade paths and required stops: the part you shouldn’t improvise.

Self-hosting GitLab means taking back control of your code and CI, in exchange for the admin responsibility. A Docker container, a well-sized instance, runners, and above all tested backups: with that, your GitLab is as reliable as the SaaS, and it's yours.