GitLab CE gives you a full self-hosted Git platform with repositories, CI/CD pipelines, issue tracking, merge requests, and a container registry, all running on your own hardware. This tutorial sets it up on Unraid as a LAN-only service with no ports exposed to the internet.
Executive Summary#
GitLab runs as a Docker container managed by Compose Manager on Unraid. Access it at home directly over your LAN, or remotely over WireGuard VPN. No open ports required. First start takes 3 to 5 minutes while GitLab configures itself.
Prerequisites#
- Unraid with Docker and Compose Manager installed
- An existing
core_netDocker network shared with your other stacks - At least 4 GB RAM available (GitLab is resource-heavy)
- SSH or terminal access to your Unraid server
Implementation#
Step 1: Create the Data Directories#
GitLab needs three persistent directories. Create them before starting the container:
mkdir -p /mnt/docker/appdata/gitlab/config
mkdir -p /mnt/docker/appdata/gitlab/logs
mkdir -p /mnt/docker/appdata/gitlab/dataStep 2: Add the Compose File#
Add the GitLab service to your stack at /mnt/user/compose/dev/docker-compose.yml:
gitlab:
image: gitlab/gitlab-ce:latest
container_name: gitlab
restart: unless-stopped
environment:
TZ: ${TZ}
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://${HOST_IP}:${GITLAB_PORT:-8929}'
gitlab_rails['smtp_enable'] = false
gitlab_rails['gitlab_email_enabled'] = false
gitlab_rails['gitlab_shell_ssh_port'] = ${GITLAB_SSH_PORT:-2222}
ports:
- "${HOST_IP}:${GITLAB_PORT:-8929}:8929"
- "${HOST_IP}:${GITLAB_SSH_PORT:-2222}:22"
volumes:
- ${APPDATA_ROOT}/gitlab/config:/etc/gitlab
- ${APPDATA_ROOT}/gitlab/logs:/var/log/gitlab
- ${APPDATA_ROOT}/gitlab/data:/var/opt/gitlab
shm_size: '256m'
networks: [core_net]
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:80/-/health >/dev/null 2>&1 || exit 1"]
interval: 60s
timeout: 10s
retries: 5
start_period: 180s
labels:
net.unraid.docker.icon: ${GITLAB_ICON:-}
net.unraid.docker.webui: http://${WEB_HOST:-${HOST_IP}}:${GITLAB_PORT:-8929}Step 3: Create the Environment Variables File#
Create a .env file in the same directory as your docker-compose.yml:
# General
TZ=America/Phoenix
HOST_IP=192.168.1.100
APPDATA_ROOT=/mnt/docker/appdata
# GitLab
GITLAB_PORT=8929
GITLAB_SSH_PORT=2222
GITLAB_ICON=https://about.gitlab.com/images/press/logo/png/gitlab-icon-rgb.pngSet TZ to your local timezone, HOST_IP to your Unraid server’s LAN IP, and APPDATA_ROOT to wherever your container data lives.
Step 4: Start GitLab#
Via Compose Manager in the Unraid UI, or over SSH:
cd /mnt/user/compose/dev
docker compose up -d gitlabFirst start takes 3 to 5 minutes. GitLab runs a full Omnibus reconfiguration on every cold start. The healthcheck has a start_period of 180s so do not restart the container if it shows unhealthy right away. Watch progress with:
docker logs -f gitlabYou are ready when the logs settle and show gitlab Reconfigured!.
Step 5: First Login#
Open a browser on your LAN and go to:
http://YOUR_UNRAID_IP:8929Retrieve the auto-generated root password:
docker exec gitlab cat /etc/gitlab/initial_root_passwordThis file is automatically deleted 24 hours after first start. Save the password somewhere secure before then. Log in with username root and the password from above, then immediately go to root avatar > Edit Profile > Password and set a strong password.
Step 6: Recommended First-Time Configuration#
Disable public registration. Since this is a private LAN instance, go to Admin Area > Settings > General > Sign-up restrictions, uncheck Sign-up enabled, and save.
Create your personal account. Avoid doing day-to-day work as root. Go to Admin Area > Users > New user, fill in your details, and assign the Admin role. Log out of root and use your personal account going forward.
Step 7: Configure SSH Git Access#
The compose file maps GITLAB_SSH_PORT (2222) on the host to port 22 inside the container. Add this block to ~/.ssh/config on any machine you clone from:
Host YOUR_UNRAID_IP
Port 2222
User git
IdentityFile ~/.ssh/id_ed25519Add your public key in GitLab under User Settings > SSH Keys > Add new key, then test:
ssh -T git@YOUR_UNRAID_IP -p 2222
# Welcome to GitLab, @yourusername!Step 8: Set Up Automated Backups#
Manual backup:
docker exec gitlab gitlab-backup createBackups land at /mnt/docker/appdata/gitlab/data/backups on the host. For automated daily backups, go to Settings > User Scripts > Add New Script, name it gitlab_backup, set a daily schedule, and paste:
#!/bin/bash
docker exec gitlab gitlab-backup create SKIP=registry
find /mnt/docker/appdata/gitlab/data/backups -name "*.tar" -mtime +7 -deleteThis creates a daily backup and prunes anything older than 7 days.
Lab Notes & Troubleshooting#
Container stays unhealthy on first start. This is normal. Give it the full 3-minute start period and watch docker logs gitlab for progress.
502 Bad Gateway in the web UI. GitLab’s internal services are still initializing. Wait another minute and refresh.
external_url mismatch errors. The external_url in GITLAB_OMNIBUS_CONFIG must exactly match the host and port you are accessing. If you change GITLAB_PORT in .env, restart the container and GitLab will reconfigure automatically.
Forgot the root password.
docker exec -it gitlab gitlab-rails console
user = User.find_by_username('root')
user.password = 'yournewpassword'
user.password_confirmation = 'yournewpassword'
user.save!Updating GitLab. Check the GitLab upgrade path before jumping major versions. GitLab requires sequential major version upgrades. Check your current version first:
docker exec gitlab gitlab-rake gitlab:env:info | grep "GitLab version"Then pull and restart:
cd /mnt/user/compose/dev
docker compose pull gitlab
docker compose up -d gitlabSummary#
You now have a private GitLab CE instance running on Unraid, accessible on your LAN and over WireGuard VPN with no ports open to the internet. Daily backups are automated and pruned after 7 days. Use your personal account for day-to-day work and keep the root account only for admin tasks.