This site contains affiliate links — we may earn a commission if you sign up through them.

GitLab Self-hosting Guide on DigitalOcean Droplet 2026

ระบบเก็บซอร์สโค้ดแบบ self-host บน Droplet จากเลือกสเปก ติดตั้ง ตั้งค่า SSL ไปจนถึง backup และข้อควรระวังเรื่องทรัพยากร

GitLab Self-hosting Guide on DigitalOcean Droplet 2026

GitLab Community Edition is an alternative for teams wanting to keep source code and CI/CD pipelines on their own infrastructure instead of relying on GitLab.com or GitHub. Running GitLab on a DigitalOcean Droplet can be done via either the Marketplace 1-Click App or Docker, but you must first understand GitLab's resource constraints before choosing a spec, since it combines Postgres, Redis, Sidekiq, and Gitaly all on a single machine.

Minimum Droplet Specs for GitLab CE

GitLab's official documentation specifies a minimum of 4 GB RAM and 2 CPU cores for an Omnibus installation, suited for small teams with up to roughly 20 users. However, GitLab itself is clear that this number represents "the bare minimum to run"—not a recommended spec for actual production use. The gitlab-ctl reconfigure process and running Puma, Sidekiq, PostgreSQL, Redis, and Gitaly concurrently on a single machine consume far more memory than expected. Especially during initial reconfiguration or when running heavy CI jobs, GitLab recommends at least 8 GB RAM as the safer standard for a single-node instance meant for real-world use, not just testing. Comparing this to DigitalOcean's Droplet tiers, the 4 GiB RAM / 2 vCPU / 80 GB SSD / 4,000 GiB transfer plan at $24/month exactly matches GitLab's stated minimum, but feels constrained with concurrent users or CI runners. The 8 GiB RAM / 4 vCPU / 160 GB SSD / 5,000 GiB transfer plan at $48/month strikes a better balance for teams of 10–20 actively using it daily, giving Sidekiq and PostgreSQL enough headroom to avoid constant swapping. For storage, beyond the SSD included with the Droplet, repositories, CI artifacts, and Container Registry images grow faster than anticipated. Provisioning DigitalOcean Volumes at $0.10 per GiB per month and moving /var/opt/gitlab/git-data there lets you resize independently without migrating the entire Droplet.

Installation via Marketplace 1-Click App or Docker

One thing that surprised us: digitalOcean includes GitLab CE in its Marketplace, ready to select when creating a Droplet. The system automatically installs the Omnibus package on Ubuntu. The advantage: no manual installation commands—power on and GitLab is ready immediately after cloud-init finishes, typically 5–10 minutes. On first SSH, you'll find instructions to set your external URL via /etc/gitlab/gitlab.rb, then run gitlab-ctl reconfigure to apply changes. The alternative is Docker, better for those wanting full control over volumes, networking, and resource limits. A docker-compose.yml service named gitlab uses the official gitlab/gitlab-ce:latest image, with hostname set to your real domain upfront. Map ports '80:80', '443:443', and '22:22' (or change the host SSH port if port 22 is already in use), then mount three volumes: /etc/gitlab, /var/log/gitlab, and /var/opt/gitlab to host paths so data persists when the container is recreated. Both methods ultimately run the same Omnibus GitLab software; Marketplace installs on bare OS while Docker runs in a container, making the latter easier to move or backup via volume copies. Once the container is ready, set the root password via the web UI or check the temporary password GitLab generates in /etc/gitlab/initial_root_password, which is auto-deleted within 24 hours.

Domain and SSL Configuration

Before setting up SSL, point your domain or subdomain's A record (e.g., git.example.com) to the Droplet IP and wait for propagation, since the Let's Encrypt certificate request relies on HTTP challenge validation from that IP. For Omnibus installations (Marketplace or Docker), edit /etc/gitlab/gitlab.rb to set external_url 'https://git.example.com' and enable built-in Let's Encrypt with letsencrypt['enable'] = true. Then run gitlab-ctl reconfigure again. The system automatically requests and installs the certificate, plus sets up a cron job to renew it. You won't need a separate Certbot installation like regular websites. One caveat: if your Droplet sits behind Cloudflare with proxy enabled (orange cloud), the HTTP challenge may fail because Let's Encrypt sees Cloudflare's IP, not your Droplet's real one. Either temporarily disable the proxy during the first certificate request, or use DNS challenge instead. For Docker deployments with Nginx or another reverse proxy in front already, disable SSL management inside GitLab and let the proxy terminate SSL instead to avoid conflicting dual-layer configs. After setup, test pushing and pulling over HTTPS and SSH to verify port 22 (or whatever you assigned for git over SSH) still works, since changing external_url and SSH ports simultaneously sometimes breaks existing client connections.

Key takeaway: Point the domain A record to the Droplet IP and wait for propagation before requesting certificates.

Backup and Restore GitLab

GitLab includes a built-in backup tool via Rake tasks. The main command, gitlab-rake gitlab:backup:create, bundles repositories, databases, uploads, CI artifacts, and registry images (if configured) into a single tar file stored at /var/opt/gitlab/backups by default. Important: this backup does not include configuration files or secret keys. You must separately back up /etc/gitlab/gitlab.rb and /etc/gitlab/gitlab-secrets.json because without the secrets file, you cannot decrypt credentials stored in the original database even if the restore succeeds. Restore via gitlab-rake gitlab:backup:restore BACKUP=timestamp, specifying the timestamp from the backup filename. Critical: the GitLab version must match exactly between backup creation and restore; schema changes vary per version, and restoring across versions often fails. For production, set up a cron job to run backups daily and immediately copy the backup files and secrets outside the Droplet—never keep them on the same disk as production. Use DigitalOcean Spaces with s3cmd or rclone to sync backups, or take Droplet Snapshots at $0.06 per GiB per month, especially before major upgrades, since snapshots let you roll back the entire system faster than piecing it back together with Rake restore.

Resource Constraints to Watch For

Most people underestimate that Omnibus bundles multiple services on one machine: PostgreSQL, Redis, Sidekiq for background jobs, Gitaly for repository management, Puma for web serving, and Container Registry if enabled. They all compete for memory and CPU on a single Droplet. On a 4 GB Droplet, running heavy CI/CD jobs alongside active users often leaves Sidekiq queues backed up or the web interface sluggish. The most common symptom is the system swapping hard, turning page loads from milliseconds into seconds, or gitlab-ctl reconfigure hanging mid-step. If using a GitLab Runner for CI/CD, run it on a separate Droplet, never on the main server, because heavy CI jobs can saturate CPU and disrupt concurrent users pushing or pulling code. Disk space is another trap—not just repositories but CI artifacts, logs, and Container Registry images accumulate far faster than expected. Without a retention policy to clean old artifacts automatically, the disk fills silently and GitLab halts without warning. Finally, upgrading versions comes with constraints: GitLab enforces a specific upgrade path you must follow sequentially; skipping multiple versions in one jump risks database migration failure. Always read release notes and plan incremental upgrades rather than leaving it months and then jumping all at once.

When to Use Self-Hosted GitLab (Real Use Cases)

Self-hosting GitLab on a Droplet makes sense for teams with clear reasons to keep code and data on their own infrastructure. Examples: data residency regulations requiring source code to stay in a specific geographic region, or corporate security policies forbidding code storage on third-party SaaS. Another common case is CI/CD runners needing hardware or network access only available internally—easier to manage when GitLab runs on the same private network. Small-to-mid teams seeking premium features like approval rules or advanced CI/CD, without paying per-seat SaaS licensing, can use CE self-hosted and skip the monthly subscription, trading operational overhead for feature access. Conversely, teams with 20–30+ active users and true high-availability needs outgrow a single Droplet. They need the reference architecture spreading Gitaly, PostgreSQL, and Redis across separate machines, or they should consider GitLab.com SaaS if no compliance requirement forces self-hosting. For startups or small dev teams with one or two ops people, starting with a single Droplet per this guide, then scaling incrementally as needed, beats over-engineering complex infrastructure from day one.

Common Mistakes and How to Fix Them

The most frequent issue is gitlab-ctl reconfigure hanging or failing on Droplets with less than 4 GB RAM, usually because PostgreSQL migration runs out of memory. A quick fix: add temporary swap space, then retry reconfigure. Long-term: upgrade the Droplet to 4–8 GB RAM. Another common trap is forgetting to open required ports in DigitalOcean's Cloud Firewall; default rules often allow only SSH, blocking HTTP/HTTPS access. Add rules for ports 80 and 443 (and 5050 for Container Registry if enabled). SSL certificate requests frequently fail when DNS hasn't fully propagated or Cloudflare proxy masks the real IP. Verify with dig or nslookup that your domain resolves to the Droplet's IP before retrying reconfigure. Backup restores fail when the installed GitLab version doesn't match the backup's creation version; always install the original version first, restore, then upgrade afterward—never restore across versions. Finally, disk fills silently from CI artifact accumulation. Fix by setting artifact expiration policies in each project's CI/CD settings or periodically running Rake tasks to clean expired artifacts.

Best Practices

Start with a Droplet spec that leaves headroom for future growth rather than the bare minimum, since resizing requires a reboot that impacts all active users. Set up daily automated backups via gitlab-rake gitlab:backup:create in cron and immediately sync the backup files along with gitlab-secrets.json and gitlab.rb to an external location like DigitalOcean Spaces using s3cmd or rclone. Never leave backups on the same disk as production. Take a Droplet Snapshot before every major version upgrade for fast rollback if something breaks—much quicker than Rake restore, which takes longer to reassemble. Enable DigitalOcean's Cloud Firewall and restrict SSH access to known IPs only, not the entire internet. Turn on 2FA for GitLab's root and admin accounts. Use DigitalOcean Monitoring to set alerts that notify you when RAM or disk usage exceeds thresholds, so you know before the system crashes. As the team grows and CI/CD jobs intensify, spin up a separate GitLab Runner Droplet early, before the main server's CPU becomes the bottleneck. Finally, monitor GitLab's release notes regularly and plan incremental upgrades on a consistent schedule rather than skipping versions for months then attempting a massive jump—the latter is far riskier.

Get $200 Free Credit →

Frequently Asked Questions

Is GitLab Community Edition really free? How does it differ from GitLab.com?
GitLab CE is open-source software you can install and use free with no user limits. GitLab.com, by contrast, is a managed SaaS where GitLab handles the servers and charges per-seat. Self-hosting CE costs only the Droplet and ops labor; you won't get premium features like advanced approval rules or epics that require a paid plan.
What Droplet size do I need for a team of 10–15?
For active daily use with some CI/CD, start with 8 GiB RAM / 4 vCPU / 160 GB SSD at $48/month so Sidekiq and PostgreSQL have breathing room. If running heavy CI jobs too, put the runner on a separate Droplet instead of the main server.
Can I back up automatically every day? How?
Yes—set up a cron job running gitlab-rake gitlab:backup:create at your preferred time (e.g., nightly), then add a step in the same script to copy the backup and gitlab-secrets.json to external storage like DigitalOcean Spaces via s3cmd or rclone so backups don't sit only on the production disk.
How do I upgrade GitLab safely to a new version?
Before any major upgrade, take a Droplet Snapshot or full backup. Then upgrade following the upgrade path GitLab documents; never skip multiple versions in one jump because database migrations fail. Always read the release notes for that version first.
Can I run a GitLab Runner on the same Droplet as the GitLab server?
Technically yes, and it works for testing. But it's not recommended for production because heavy CI/CD jobs will starve CPU and RAM, slowing down the web interface for concurrent users. Run the Runner on a separate Droplet instead.
Can I migrate from self-hosted back to GitLab.com SaaS later?
Yes—GitLab provides import/export tools for projects and groups between self-hosted and GitLab.com, and you can import backups from self-hosted into GitLab.com in some cases. Check GitLab's latest migration docs first, as steps vary by version.