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 calculatorStep 1: Prepare the server
Here is the first AI prompt. Copy it, replace the placeholders and let it suggest a setup script:
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:
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:
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
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.
| Aspect | GitLab.com (entry tier) | GitLab Self-Managed |
|---|---|---|
| Costs | per GitLab.com | server costs, GitLab calculator |
| Users in private namespaces | up to five | no such limit |
| Compute minutes | 400 per month for instance runners | quotas disabled by default |
| Updates | by GitLab | by 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_urltohttps://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), thendocker 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?
Can I migrate from GitHub to GitLab?
How do I update GitLab?
GitLab vs Gitea – which is better for self-hosting?
Do I need a GitLab runner on a separate server?
More Self-Hosting Guides
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



