All Guides

Self-Host GitLab CE: Your Own Git Server with AI Assistance

Set up GitLab Community Edition (CE) with Docker Compose on a VPS – with AI prompts, runner, backup and hardening.

Dirk Hesse
January 22, 2026
12 min read

A self-run GitLab instance lives on your own server. The user limit for private namespaces on GitLab.com does not apply to GitLab Self-Managed (GitLab docs, as of Nov 8, 2026), and compute quotas are disabled there by default (GitLab docs, as of Nov 8, 2026). Server prices are in the GitLab calculator.

The AI part: The prompts help prepare commands for your server. Check every AI output against the GitLab docs before running it.

This guide covers a GitLab CE installation with Docker – with copy-paste AI prompts for every step.


Hardware requirements

GitLab is resource-hungry. For a single instance, GitLab names 8 vCPU and 16 GB RAM as a baseline, and 8 GB as the floor in memory-constrained environments; plus 40 GB of storage for the application and room for all repos and the database (GitLab docs, as of Nov 8, 2026).

A separate page on low-memory operation names 2 GB RAM plus 1 GB swap for up to five developers with small repos (GitLab docs, as of Nov 8, 2026). The docs are inconsistent here; plan generously. For comparison: Gitea names 2 CPU cores and 1 GB RAM as typically enough for small teams (Gitea docs, as of Nov 8, 2026) and also ships CI/CD and a container registry (Gitea docs, as of Nov 8, 2026).

Tip: GitLab advises against burstable instances and recommends disabling swap where possible and providing enough RAM (GitLab docs, as of Nov 8, 2026).

Looking for a server for GitLab?

Our calculator works out your requirements based on team size and CI/CD usage.

GitLab server calculator

Step 1: Prepare the server

Here is the first AI prompt. Copy it, replace the placeholders and let it suggest a setup script:

Prompt: Prepare Server for GitLab
I want to install GitLab CE on an Ubuntu 24.04 VPS. The server has [X] GB RAM and [Y] CPU cores. Please create: 1. A server preparation script (updates, firewall) 2. Docker installation from the official apt repository 3. A check that ports 80, 443 and Git SSH port 2222 are available Explain each step briefly.

Manual basic preparation

If you want to do it yourself:

# Update the system
apt update && apt upgrade -y

# Configure the firewall
ufw allow 22/tcp    # SSH
ufw allow 80/tcp    # HTTP
ufw allow 443/tcp   # HTTPS
ufw allow 2222/tcp  # Git over SSH (container)
ufw enable

Install Docker from the official apt repository (docker-ce, docker-compose-plugin) as the Docker docs describe; Docker does not recommend the convenience script for production systems (Docker docs, as of Nov 8, 2026).

Caution: Ports published by Docker bypass ufw (Docker docs, as of Nov 8, 2026). Publish only 80, 443 and 2222, or also use your host's firewall.


Step 2: GitLab with Docker Compose

Create the directory and configuration:

mkdir -p /opt/gitlab && cd /opt/gitlab
nano docker-compose.yml

Docker Compose configuration:

services:
  gitlab:
    image: gitlab/gitlab-ce:<version>-ce.0
    container_name: gitlab
    restart: always
    hostname: 'gitlab.your-domain.com'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://gitlab.your-domain.com'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
    ports:
      - '80:80'
      - '443:443'
      - '2222:22'
    volumes:
      - gitlab_config:/etc/gitlab
      - gitlab_logs:/var/log/gitlab
      - gitlab_data:/var/opt/gitlab
    shm_size: '256m'

volumes:
  gitlab_config:
  gitlab_logs:
  gitlab_data:

For production, pin the image to a fixed version instead of latest (GitLab docs, as of Nov 8, 2026). You no longer need a version: line; it is obsolete (Docker docs, as of Nov 8, 2026).

Start:

docker compose up -d

Note: The first start can take a while. Follow the progress with docker logs -f gitlab (GitLab docs, as of Nov 8, 2026).

Low RAM

For memory-constrained environments, the GitLab docs name puma['worker_processes'] = 0, sidekiq['concurrency'] = 10 and prometheus_monitoring['enable'] = false, among others (GitLab docs, as of Nov 8, 2026). Puma single mode has limits, e.g. no phased restarts (GitLab docs, as of Nov 8, 2026).


Step 3: First login

After starting, read the initial root password:

docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password

Then in the browser: https://gitlab.your-domain.com

  • Username: root
  • Password: from the command above

Important: The password file is deleted automatically on the first container restart after 24 hours (GitLab docs, as of Nov 8, 2026). Change it right away in your user settings.


Troubleshooting with AI

GitLab errors can be cryptic. This prompt helps you make sense of them:

Prompt: Solve GitLab Problems
My GitLab CE container shows the following error: [PASTE ERROR HERE] Server info: - OS: Ubuntu 24.04 - RAM: [X] GB (of which [Y] GB available) - Docker version: [X] - GitLab version: [X] Logs from 'docker logs gitlab --tail 50': [PASTE LOGS HERE] What is the cause and how do I fix it?

Privacy: Remove passwords, tokens and email and IP addresses from the logs before pasting.

Common problems

Container does not start (OOM):

# Check RAM usage
docker stats gitlab

Plan more RAM (calculator at /en/use-case/gitlab). Swap is only a stopgap and can lower performance considerably (GitLab docs, as of Nov 8, 2026).

502 Bad Gateway: GitLab needs time to start. Follow docker logs -f gitlab or check:

docker exec -it gitlab gitlab-ctl status

SSL certificate does not work: Let's Encrypt needs reachable ports 80/443. Check the firewall!


CI/CD pipeline basics

On GitLab Self-Managed, compute quotas are disabled by default; the limit is your runners' capacity (GitLab docs, as of Nov 8, 2026).

Install GitLab Runner

The runner executes your pipelines. GitLab recommends running the runner on a separate machine (GitLab docs, as of Nov 8, 2026). To get started, it can run in the same Compose project:

# Add to docker-compose.yml under services
  gitlab-runner:
    image: gitlab/gitlab-runner:<version>
    container_name: gitlab-runner
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - gitlab_runner_config:/etc/gitlab-runner

# and add to the top-level volumes block:
#   gitlab_runner_config:

Caution: The mounted Docker socket defeats container isolation; privilege escalation to the host is possible (GitLab docs, as of Nov 8, 2026).

Register the runner: first create it in the GitLab UI (the token starts with glrt-), then register it (GitLab docs, as of Nov 8, 2026):

docker exec -it gitlab-runner gitlab-runner register --url https://gitlab.your-domain.com --token <glrt-token>

Create your first pipeline

Let the AI suggest a pipeline:

Prompt: Generate GitLab CI Pipeline
Create a .gitlab-ci.yml for a [LANGUAGE/FRAMEWORK] project. Requirements: - Build stage: [e.g. npm ci, go build] - Check stage: [e.g. npm run lint, pytest] - Deploy stage: [e.g. SSH to server, Docker push] The project uses [PACKAGE MANAGER]. Deployment target: [e.g. own VPS, Kubernetes, Docker Hub] Please explain with comments.

Example for a Node.js project:

stages:
  - build
  - check
  - deploy

default:
  image: node:24
  cache:
    key: npm
    paths:
      - .npm/

build:
  stage: build
  script:
    - npm ci --cache .npm
    - npm run build

check:
  stage: check
  script:
    - npm ci --cache .npm
    - npm run lint

deploy:
  stage: deploy
  image: alpine
  before_script:
    - apk add openssh-client
    - eval $(ssh-agent -s)
    - chmod 400 "$SSH_PRIVATE_KEY"
    - ssh-add "$SSH_PRIVATE_KEY"
    - mkdir -p ~/.ssh && chmod 700 ~/.ssh
    - cp "$SSH_KNOWN_HOSTS" ~/.ssh/known_hosts
  script:
    - ssh user@server "cd /app && git pull && docker compose up -d --build"
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

Each job runs npm ci itself, because the cache is an optimization without guarantee of presence (GitLab docs, as of Nov 8, 2026). Node.js 24 is an LTS line (nodejs.org, as of Nov 8, 2026). Use rules instead of only (GitLab docs, as of Nov 8, 2026). For the deploy job, store the key as a file variable SSH_PRIVATE_KEY with ssh-agent and the host keys as SSH_KNOWN_HOSTS (GitLab docs, as of Nov 8, 2026).


Set up backups

Prompt: GitLab Backup Strategy
Create a backup concept for my self-hosted GitLab installation. Setup: - GitLab CE in Docker - Data in Docker volumes - [X] GB of repos in total - Backup target: [e.g. external storage via SFTP, S3-compatible object storage, second disk] I need: 1. Daily automatic backup 2. Retention of the last 7 backups 3. Restore guide for emergencies

Manual backup:

docker exec -t gitlab gitlab-backup create

Backup files are in /var/opt/gitlab/backups/ (inside the container). Configuration files are not in the backup: save /etc/gitlab/gitlab-secrets.json and gitlab.rb (in the gitlab_config volume) separately from the application backup, somewhere safe off the server (GitLab docs, as of Nov 8, 2026).


GitLab.com vs self-hosted

Table as of Nov 8, 2026, sources in the paragraph below.

AspectGitLab.com (entry tier)GitLab Self-Managed
Costsper GitLab.comserver costs, GitLab calculator
Users in private namespacesup to fiveno such limit
Compute minutes400 per month for instance runnersquotas disabled by default
Updatesby GitLabby you (image tag per upgrade path)

The GitLab docs describe the user limit (GitLab docs, as of Nov 8, 2026) and the compute minutes (GitLab docs, as of Nov 8, 2026). On GitLab.com the entry-tier limit applies from the sixth user in a private namespace. For moving from GitHub there is a built-in importer; on Self-Managed an admin must enable the import source (GitLab docs, as of Nov 8, 2026).

Privacy: Data on your server, location selectable; if you process other people's data, you remain responsible for GDPR compliance, usually with a data processing agreement with the host.


Use the container & package registry

GitLab ships a container registry and a package registry (GitLab docs, as of Nov 8, 2026). Instead of running Docker Hub or a separate artifact server, you push images straight into GitLab.

You enable the registry via registry_external_url. Two variants: with the built-in Let's Encrypt integration it runs on port 5050 of the GitLab domain, which you publish in the Docker setup; or it gets its own subdomain with a valid certificate (GitLab docs, as of Nov 8, 2026). Example with its own subdomain:

docker login registry.your-domain.com
docker build -t registry.your-domain.com/team/project:latest .
docker push registry.your-domain.com/team/project:latest

The package registry supports npm, Maven, PyPI and Composer, among others (GitLab docs, as of Nov 8, 2026) – handy when your team shares internal libraries without publishing them.

Harden GitLab

A self-hosted GitLab server is an attractive target because it holds all your source code. Key measures:

  • Enforce HTTPS: Set external_url to https:// and use the built-in Let's Encrypt integration (see the registry section) or a reverse proxy.
  • Enforce 2FA for everyone: Under Admin → Settings → General → Sign-in restrictions → Enforce two-factor authentication (GitLab docs, as of Nov 8, 2026).
  • Disable sign-up: Sign-up is on by default; under Admin → Settings → General → New user account restrictions, turn off "Allow new user accounts" (GitLab docs, as of Nov 8, 2026). Invite users instead.
  • SSH keys instead of passwords: For Git operations and server access.
  • Regular updates: GitLab publishes patch releases twice a month (GitLab docs, as of Nov 8, 2026). Before every update, back up incl. /etc/gitlab, set the image tag to the next version on the upgrade path (GitLab docs, as of Nov 8, 2026), then docker compose pull && docker compose up -d.
  • Rate limits: Check the built-in rate limits in the admin area (GitLab docs, as of Nov 8, 2026); Fail2Ban can be added on top.

Conclusion

You now have your own GitLab server:

  • without the GitLab.com entry-tier user limit
  • with compute quotas disabled by default
  • with data on your server, location of your choice

The AI workflow: The prompts help interpret error messages; they do not replace the GitLab docs.

Costs: Current GitLab server prices: GitLab calculator and VPS comparison.


Frequently Asked Questions

How much RAM does GitLab really need?
For a single instance, GitLab names 8 vCPU and 16 GB RAM as a baseline, 8 GB as the floor in memory-constrained environments (GitLab docs, as of Nov 8, 2026). The calculator at /en/use-case/gitlab estimates your needs.
Can I migrate from GitHub to GitLab?
Yes. GitLab has a GitHub importer: New project → Import project → GitHub. Pull requests become merge requests; on Self-Managed an admin must enable GitHub as an import source (GitLab docs, as of Nov 8, 2026).
How do I update GitLab?
Back up incl. /etc/gitlab, raise the image tag to the next version on the upgrade path, then 'docker compose pull && docker compose up -d'. Do not skip upgrade stops (GitLab docs, as of Nov 8, 2026).
GitLab vs Gitea – which is better for self-hosting?
Gitea names 2 CPU cores and 1 GB RAM as typically enough for small teams (Gitea docs, as of Nov 8, 2026), GitLab 8 GB as the floor (GitLab docs, as of Nov 8, 2026). Both ship CI/CD and a container registry; pick by the features you need.
Do I need a GitLab runner on a separate server?
GitLab recommends a separate runner machine for security and performance (GitLab docs, as of Nov 8, 2026). Suitable servers are at /en/use-case/gitlab.

Find a GitLab server with the calculator

Work out your requirements based on team size and CI/CD usage. Price comparison of the providers RackDiff tracks.

To the GitLab server finder

Matching VPS Calculator

GitLab CE Self-Hosting: Die besten VPS 2026

Git-Server, CI/CD und Container Registry auf eigenem Server.

Go to Calculator

Related Articles