Self-Host GitLab on Gozunga Cloud
Run your own GitLab CE instance on Gozunga Cloud for a fully self-hosted Git platform — repositories, CI/CD, container registry, and more, entirely under your control
GitHub outages happen. When they do, teams that self-host keep shipping. GitLab CE is a complete DevOps platform — Git hosting, merge requests, CI/CD pipelines, a container registry, and more — and it runs beautifully on a single Gozunga Cloud instance.
- Overview
- Create Your Gozunga Account - First, Sign Up to get started.
- Launch an Instance - GitLab needs a bit of headroom — we'll pick the right size.
- Secure Your Instance - Open the necessary ports and harden SSH.
- Deploy GitLab CE - Configure and bring up your GitLab instance.
- First Login & Initial Setup - Set your root password and configure essentials.
- (Optional) Add a GitLab Runner - Enable CI/CD pipelines on your own infrastructure.
- Next Steps and More Information
1. Overview
GitLab Community Edition is a fully open-source, self-hostable Git platform. It ships with everything you'd expect from a modern DevSecOps tool: merge requests, protected branches, issue tracking, CI/CD pipelines, a built-in container registry, and a package registry — all without a monthly SaaS fee.
This guide deploys GitLab CE using Docker Compose on a single Gozunga Cloud instance. Docker keeps the setup clean, upgrades straightforward, and the data volumes portable. We'll also walk through opening the right ports, configuring SSL via Let's Encrypt, and optionally registering a GitLab Runner so your pipelines have somewhere to run.
Why self-host instead of GitHub or GitLab.com?
- No vendor lock-in — your code lives on infrastructure you own
- No outage dependency — GitHub's status page doesn't affect your deploy pipeline
- Private by default — all repositories and CI artifacts stay on your server
- No seat fees — GitLab CE is fully free with unlimited users and repositories
2. Create your Gozunga Account
If you haven't yet done so, Create an Account. You can sign up for free and get $100 in credits to get started — more than enough to run GitLab for months while you evaluate the setup.
Why choose Gozunga Cloud for GitLab?
- High-performance NVMe storage — fast clone and push operations
- 99.99% uptime SLA — your Git host stays online when it matters
- Flexible resizing — start with a comfortable size and scale up as your team grows
- Bare-metal performance tiers — available when you need maximum throughput for large repositories
3. Launch an Instance
GitLab CE is a full-featured platform and benefits from dedicated resources. We recommend at minimum 4 vCPUs and 8 GB RAM for a team installation.
💡 Pro Tip: An instance with 4 vCPUs and 8 GB RAM is a solid starting point for most small-to-medium teams. For heavier CI/CD workloads or larger repositories, step up to 8 vCPUs / 16 GB — or consider a dedicated bare-metal server for maximum throughput.
- Log in to the Cloud Management Portal and create a Project to house your GitLab instance.
- From the Servers pane, click Create a Cloud Server
- Select Ubuntu 24.04 as your distribution and choose an instance with at least 4 vCPUs and 8 GB RAM
- Choose your network settings (Public Network → Internet) and attach your SSH key
- Under Cloud configuration, paste the following cloud-init to pre-install Docker at boot time:
#cloud-config
package_update: true
package_upgrade: true
packages:
- ca-certificates
- curl
- gnupg
runcmd:
- install -m 0755 -d /etc/apt/keyrings
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
- chmod a+r /etc/apt/keyrings/docker.gpg
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" > /etc/apt/sources.list.d/docker.list
- apt-get update -y
- apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- systemctl enable docker
- systemctl start docker
final_message: "Docker installation complete. System ready after $UPTIME seconds."
- Click Create Server and wait for the instance to reach Active status (typically 2–3 minutes)
4. Secure Your Instance
Before deploying GitLab, open the ports it needs. GitLab requires three:
| Port | Protocol | Purpose |
|---|---|---|
| 80 | TCP | HTTP (redirects to HTTPS) |
| 443 | TCP | HTTPS web UI |
| 2222 | TCP | Git over SSH (we map it to avoid conflicts with your server's SSH on 22) |
- In the portal, navigate to your instance's Security Groups (or Firewall Rules)
- Add inbound rules for TCP 80, TCP 443, and TCP 2222 from any source (0.0.0.0/0)
- Keep port 22 restricted to your own IP for server administration
💡 Pro Tip: We use port 2222 for GitLab SSH so that port 22 stays reserved for your server's own SSH access. You'll configure GitLab to advertise 2222 to users, so
git cloneover SSH will use that port.
5. Deploy GitLab CE
SSH into your instance, then create a directory for GitLab and write your Docker Compose configuration.
mkdir -p /opt/gitlab && cd /opt/gitlab
Create a .env file with your hostname:
# Replace with your actual domain
cat > /opt/gitlab/.env <<'EOF'
GITLAB_HOSTNAME=gitlab.yourdomain.com
EOF
Note: GitLab's Let's Encrypt integration requires a real domain pointing to your server's IP. Update your DNS A record before continuing. If you don't have a domain yet, you can use your server's public IP for initial testing — just leave
external_urlashttp://<your-ip>and skip the SSL lines.
Now create the Compose file:
cat > /opt/gitlab/docker-compose.yml <<'EOF'
services:
gitlab:
image: gitlab/gitlab-ce:latest
container_name: gitlab
restart: always
hostname: '${GITLAB_HOSTNAME}'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://${GITLAB_HOSTNAME}'
gitlab_rails['gitlab_shell_ssh_port'] = 2222
letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['[email protected]']
# Tune for your instance size (adjust to ~25% of total RAM)
puma['worker_processes'] = 2
sidekiq['concurrency'] = 10
postgresql['shared_buffers'] = "256MB"
prometheus_monitoring['enable'] = false
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:
EOF
Start GitLab:
docker compose up -d
GitLab takes 3–5 minutes to fully initialize on first boot. You can watch the startup progress:
docker logs -f gitlab
Wait until you see a line like gitlab Reconfigured! before proceeding.
6. First Login & Initial Setup
Retrieve the initial root password:
GitLab generates a temporary root password on first run. Fetch it with:
docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
Important: This file is automatically deleted after 24 hours. Change your root password immediately after logging in.
Log in:
- Open
https://gitlab.yourdomain.comin your browser - Sign in with username
rootand the password from above - Navigate to Edit Profile → Password and set a strong permanent password
Recommended initial settings:
- Restrict sign-ups (unless you want open registration): Go to Admin Area → Settings → General → Sign-up restrictions → uncheck Sign-up enabled
- Set your instance name and logo: Admin Area → Settings → General → Account and limit
- Configure email (optional but recommended): Edit the Omnibus config in your Compose file to add SMTP settings, then run
docker compose restart gitlab
Configure SSH Clone URL
Since GitLab SSH runs on port 2222, users will clone with:
git clone ssh://[email protected]:2222/group/repo.git
GitLab will automatically display this URL in the repository UI once gitlab_shell_ssh_port is set correctly (which we configured in Step 5).
7. (Optional) Add a GitLab Runner
A GitLab Runner executes your CI/CD pipelines. You can run it on the same server as a second container, or on a separate instance for better isolation.
Add a runner on the same server:
# Add runner service to your Compose file
cat >> /opt/gitlab/docker-compose.yml <<'EOF'
gitlab-runner:
image: gitlab/gitlab-runner:latest
container_name: gitlab-runner
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- gitlab_runner_config:/etc/gitlab-runner
depends_on:
- gitlab
EOF
# Add the volume declaration
# (Edit docker-compose.yml to add `gitlab_runner_config:` under the volumes: section)
docker compose up -d gitlab-runner
Register the runner with your GitLab instance:
- In GitLab, go to Admin Area → CI/CD → Runners → New instance runner
- Copy the registration token
- Run the interactive registration:
docker exec -it gitlab-runner gitlab-runner register
When prompted:
- GitLab instance URL:
https://gitlab.yourdomain.com - Registration token: (paste from above)
- Description:
docker-runner - Tags: leave blank for a shared runner
- Executor:
docker - Default image:
docker:latest
Once registered, the runner will appear as Online in the Runners admin page and will automatically pick up pipeline jobs.
8. Next Steps and More Information
Your GitLab instance is up and running. Here are a few things worth exploring next:
- Enable the Container Registry — GitLab includes a built-in registry. Add
registry_external_url 'https://registry.yourdomain.com'to your Omnibus config to activate it. - Set up backups — Configure
gitlab_rails['backup_upload_connection']to push nightly backups to S3-compatible object storage. Gozunga's Ceph RGW object storage is a good fit here. - Upgrade GitLab — Pull the latest image with
docker compose pull && docker compose up -d. GitLab follows a monthly release cadence; check the upgrade path tool before jumping multiple major versions. - Migrate from GitHub — GitLab's built-in importer can pull repositories, issues, pull requests, and wikis from GitHub. Go to New Project → Import project → GitHub.
- Need more disk space? GitLab's storage grows mostly from CI/CD artifacts and the container registry — not repositories themselves. When you need to scale, attach a Gozunga Block Storage volume to your instance, move
/var/lib/dockerto it, and point Docker'sdata-rootthere. No reinstall required, and your GitLab data moves with it since it all lives in Docker-managed volumes.
Resources: