{"id":85247,"date":"2026-07-07T07:00:00","date_gmt":"2026-07-07T14:00:00","guid":{"rendered":"https:\/\/dhblog.dream.press\/blog\/?p=85247"},"modified":"2026-07-07T07:46:51","modified_gmt":"2026-07-07T14:46:51","slug":"self-host-gitlab-ce-on-vps","status":"publish","type":"post","link":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/","title":{"rendered":"How To Self-Host GitLab CE on a VPS"},"content":{"rendered":"<div class=\"tldr-block\" style=\"display: none;\">\n\t<div class=\"svg\">\n\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 119.25 37.8\">\n\t<g>\n\t\t<g>\n\t\t\t<path fill=\"#ffffff\" d=\"M23.4,6.93h-8.1v24.57h-7.2V6.93H0V0h23.4v6.93Z\" \/>\n\t\t\t<path fill=\"#ffffff\" d=\"M45,24.57v6.93h-18.45V0h7.2v24.57h11.25Z\" \/>\n\t\t\t<path fill=\"#ffffff\"\n\t\t\t\td=\"M90.9,15.75c0,8.91-6.61,15.75-15.3,15.75h-12.6V0h12.6c8.68,0,15.3,6.84,15.3,15.75ZM83.97,15.75c0-5.4-3.42-8.82-8.37-8.82h-5.4v17.64h5.4c4.95,0,8.37-3.42,8.37-8.82Z\" \/>\n\t\t\t<path fill=\"#ffffff\"\n\t\t\t\td=\"M105.57,21.15h-3.42v10.35h-7.2V0h12.6c5.98,0,10.8,4.81,10.8,10.8,0,3.87-2.34,7.38-5.81,9.13l6.71,11.56h-7.74l-5.94-10.35ZM102.15,14.85h5.4c1.98,0,3.6-1.75,3.6-4.05s-1.62-4.05-3.6-4.05h-5.4v8.1Z\" \/>\n\t\t<\/g>\n\t\t<path\n\t\t\tfill=\"#0173ec\"\n\t\t\td=\"M53.97,37.8h-5.4l1.8-13.27h7.2l-3.6,13.27ZM49.02,12.55c0-2.34,1.93-4.27,4.27-4.27s4.27,1.94,4.27,4.27-1.93,4.27-4.27,4.27-4.27-1.94-4.27-4.27Z\"\n\t\t \/>\n\t<\/g>\n<\/svg>\n\t<\/div>\n\t<div class=\"tldr-wrap\">\n\t\t\n\n<p class=\"wp-block-paragraph\">Self-hosting GitLab Community Edition (CE) on a VPS gives you full ownership of your source code, CI\/CD pipeline, and project data with no per-user pricing or third-party data exposure.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>GitLab CE<\/strong>, the free, open-source edition of GitLab, installs on Ubuntu in 10 to 15 minutes using the official Omnibus package (most of that is the automatic reconfigure step), plus about an hour for DNS, prep, and hardening. You&#8217;ll want a VPS with at least 8 GB of RAM (the practical floor for a real team, though GitLab can technically run on less) and a domain name.<\/p>\n\n\n\t<\/div>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s a Friday afternoon, your team&#8217;s pull request is sitting in review, and your laptop pings with a familiar message: GitHub is having issues again.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Maybe Actions are stuck.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Maybe `git push` returns a 500 error for the third time this month.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>The thread in your team chat already has eight messages.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first time this happens, you laugh about it. The second time, somebody links the <a target=\"_blank\" href=\"https:\/\/www.githubstatus.com\">GitHub status page<\/a>, and you all go get coffee. The third time, usually right before a release window, somebody finally types the question out loud: <em>&#8220;Should we just run our own?&#8221;<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For most teams, the honest answer is no. GitLab.com Free covers small teams comfortably, and the operational tax of running your own version-control server is not zero.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>It&#8217;s the kind of trade you only make for a real reason.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your team has one of those reasons, such as a customer contract that forbids third-party SaaS, a compliance boundary, or a seat-license bill that&#8217;s starting to look ridiculous, self-hosting GitLab CE is the cleanest move you can make. It\u2019s open source, runs on a single VPS, and, once tuned, maintenance takes about an hour a month.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At DreamHost, we&#8217;ve hosted countless self-managed servers, and we keep seeing a pattern: developers who succeed with self-hosted GitLab pick the right plan up front, get the <a target=\"_blank\" href=\"https:\/\/www.dreamhost.com\/glossary\/hosting\/ssh\/\">Secure Shell Protocol (SSH)<\/a> and Domain Name System (DNS) prep right, and then resist the urge to keep tinkering once it&#8217;s stable.<\/p>\n\n\n\n<h2 id=\"h-why-would-you-self-host-gitlab-instead-of-using-gitlab-com\" class=\"wp-block-heading\">Why Would You Self-Host GitLab Instead of Using GitLab.com?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You self-host GitLab when GitLab.com or GitHub.com can&#8217;t meet your privacy, compliance, or cost-control needs. For most other teams, the hosted option is a better trade.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Three real reasons hold up under scrutiny:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Privacy and data sovereignty:<\/strong> Your source code lives on infrastructure you manage and patch on your own schedule. No third-party access, no shared platform, no breach blast radius beyond your own server.<\/li>\n\n\n\n<li><strong>Compliance:<\/strong> Regulated industries like healthcare, finance, and government often need data-residency control. Self-hosted GitLab CE is the simplest way to keep code inside a controlled boundary.&nbsp;<\/li>\n\n\n\n<li><strong>Cost control at scale:<\/strong> GitLab.com charges per active user. According to <a target=\"_blank\" href=\"https:\/\/about.gitlab.com\/pricing\/\">GitLab&#8217;s pricing page<\/a>, Premium costs $29 per user per month, while Ultimate pricing is available only on request. A 50-person team on Premium runs $17,400 per year before add-ons. A self-managed VPS plus an hour of monthly maintenance often costs less.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;re a two-person team with no privacy or compliance reasons, the right answer is GitLab\u2019s free tier. (<em>Yes, we know that sounds funny coming from a hosting company<\/em>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With self-hosting, you&#8217;re trading a monthly SaaS bill for ongoing operational time. That&#8217;s a worthwhile swap only if you have a good reason to make the switch.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s where this option makes sense and where it doesn&#8217;t:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th><strong>Scenario<\/strong><\/th><th><strong>Best fit<\/strong><\/th><\/tr><\/thead><tbody><tr><td>Privacy or compliance requirement<\/td><td>Self-hosted GitLab CE<\/td><\/tr><tr><td>Team larger than ~30 active users<\/td><td>Self-hosted is often cheaper<\/td><\/tr><tr><td>Code is your IP, and you want it local<\/td><td>Self-hosted GitLab CE<\/td><\/tr><tr><td>2-5 person team, no compliance needs<\/td><td>GitLab.com (free)<\/td><\/tr><tr><td>You don&#8217;t want to patch a server<\/td><td>GitLab.com<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">GitLab Community Edition is free under an MIT-style open-source license. There&#8217;s no user limit, no feature gate on the basics, and no upsell prompts. The whole platform is yours to run.<\/p>\n\n\n\n<h2 id=\"h-what-are-the-hardware-requirements-for-gitlab-ce\" class=\"wp-block-heading\">What Are the Hardware Requirements for GitLab CE?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">GitLab CE has clear hardware thresholds, and getting them right is the difference between a snappy install and one that thrashes through swap memory (disk space your operating system uses when RAM fills up).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">According to GitLab&#8217;s <a target=\"_blank\" href=\"https:\/\/docs.gitlab.com\/install\/requirements\/\">official installation requirements<\/a>, sizing is expressed in requests per second rather than fixed per-user tiers. The published baseline is 8 vCPU and 16 GB of RAM for up to 1,000 users (about 20 requests per second). Smaller teams can run on less, down to a documented floor of 2 GB of RAM plus 1 GB of swap for evaluation, though performance suffers below 4 GB.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A fresh GitLab install consumes around 4-6 GB at idle. Once CI\/CD jobs start running, memory spikes fast. So plan for headroom \u2014 or plan for slowness.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As far as storage goes, GitLab\u2019s official baseline is\u202f40\u202fGB\u202fplus\u202frepository\u202fsize, but\u202f50\u202fGB\u202fis\u202fa\u202fsafer\u202fstarting\u202fpoint\u202fin\u202fpractice.\u202fRepositories\u202fgrow,\u202fand\u202fbuild\u202fartifacts\u202fpile\u202fup. NVMe, a\u202ffaster\u202ftype\u202fof\u202fsolid\u2011state\u202fstorage, makes a noticeable difference on Git operations and CI cache reads.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s how those thresholds map to <a target=\"_blank\" href=\"https:\/\/www.dreamhost.com\/hosting\/self-managed-vps\">DreamHost&#8217;s VPS hosting tiers<\/a>:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th><strong>Use Case<\/strong><\/th><th><strong>Recommended RAM<\/strong><\/th><th><strong>DreamHost VPS tier<\/strong><\/th><\/tr><\/thead><tbody><tr><td>Evaluation \/ personal<\/td><td>4 GB RAM<\/td><td>Stack 4<\/td><\/tr><tr><td>Small team, light usage<\/td><td>8 GB RAM<\/td><td>Stack 8<\/td><\/tr><tr><td>Up to ~1,000 users (GitLab&#8217;s published baseline)<\/td><td>16 GB RAM<\/td><td>Stack 16<\/td><\/tr><tr><td>Running CI\/CD runners on the same box<\/td><td>+ 2-8 GB RAM on top of your tier<\/td><td>Size up (e.g. Stack 16 \u2192 Stack 32)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The right starting point for most teams running real CI\/CD pipelines is Stack 16. That sounds like overkill until you watch the first build kick off and Sidekiq, Postgres, and a runner all spike at once<em>.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">16 GB of RAM gives you enough headroom for GitLab&#8217;s stack of services (roughly 4 to 6 GB at idle on a default install) and a couple of CI workers (1-2 GB each) to run hot at the same time without anyone in the team chat noticing.<\/p>\n\n\n\n<div class=\"article-newsletter article-newsletter--gradient\">\n\n\n<h2>Get Content Delivered Straight to Your Inbox<\/h2><p>Subscribe now to receive all the latest updates, delivered directly to your inbox.<\/p><form class=\"nwsl-form\" id=\"newsletter_block_\" novalidate><div class=\"messages\"><\/div><div class=\"form-group\"><label for=\"input_newsletter_block_\"><input type=\"email\"name=\"email\"id=\"input_newsletter_block_\"placeholder=\"Enter your email address\"novalidatedisabled=\"disabled\"\/><\/label><button type=\"submit\"class=\"btn btn--brand\"disabled=\"disabled\"><span>Sign Me Up!<\/span><svg width=\"21\" height=\"14\" viewBox=\"0 0 21 14\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n<path d=\"M13.8523 0.42524L12.9323 1.34521C12.7095 1.56801 12.7132 1.9304 12.9404 2.14865L16.7241 5.7823H0.5625C0.251859 5.7823 0 6.03416 0 6.3448V7.6573C0 7.96794 0.251859 8.2198 0.5625 8.2198H16.7241L12.9405 11.8535C12.7132 12.0717 12.7095 12.4341 12.9323 12.6569L13.8523 13.5769C14.072 13.7965 14.4281 13.7965 14.6478 13.5769L20.8259 7.39879C21.0456 7.17913 21.0456 6.82298 20.8259 6.60327L14.6477 0.42524C14.4281 0.205584 14.0719 0.205584 13.8523 0.42524Z\" fill=\"white\"\/>\n<\/svg>\n<\/button><\/div><\/form><\/div>\n\n\n<h2 id=\"h-how-do-you-prepare-your-vps-before-installing-gitlab\" class=\"wp-block-heading\">How Do You Prepare Your VPS Before Installing GitLab?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Spend 10 minutes on prep \u2014 it pays off the first time you reboot. Simply follow these steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Provision the VPS: <\/strong>Pick Ubuntu 22.04 LTS or 24.04 LTS. Both are supported by GitLab&#8217;s official Omnibus packages (the bundled all-in-one installer GitLab ships) and have years of free security updates ahead of them.<br><\/li>\n\n\n\n<li><strong>Point a domain to the server&#8217;s IP: <\/strong>Create an A record (the type of DNS record that maps a domain to an IP address) and let it propagate for at least 15-30 minutes before installing. Without it, the automatic SSL setup will fail because the certificate authority has nowhere to validate.<br><\/li>\n\n\n\n<li><strong>Update packages: <\/strong>Connect to the VPS using `ssh root@your-server-ip` and run `sudo apt update &amp;&amp; sudo apt upgrade -y`.<br><\/li>\n\n\n\n<li><strong>Install dependencies: <\/strong>Run `sudo apt install -y curl openssh-server ca-certificates perl postfix`. The `postfix` package is a mail server that handles outgoing email so GitLab can send merge-request notifications and password resets.<br>When the installer asks about mail configuration, choose <em>Internet Site<\/em> and use your domain. This gets GitLab sending mail immediately.<br><strong>For production:<\/strong> skip local postfix and configure an SMTP relay in <a href=\"http:\/\/gitlab.rb\" target=\"_blank\">gitlab.rb<\/a> instead. VPS IPs are frequently on spam blocklists, and password-reset emails routed through local postfix will often land in spam. SendGrid, Mailgun, and DreamHost\u2019s outbound relay all work \u2014 see GitLab\u2019s <a href=\"https:\/\/docs.gitlab.com\/omnibus\/settings\/smtp\/\" target=\"_blank\">SMTP configuration docs<\/a>.<br><\/li>\n\n\n\n<li><strong>Open the right ports: <\/strong><a href=\"https:\/\/www.dreamhost.com\/glossary\/hosting\/firewall\/\" target=\"_blank\">Configure a firewall<\/a> using UFW (Ubuntu&#8217;s built-in firewall tool) and allow ports 80, 443, and 22.<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ufw allow http\nsudo ufw allow https\nsudo ufw allow ssh\nsudo ufw enable<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 id=\"h-how-do-you-install-gitlab-ce-on-ubuntu-using-the-omnibus-package\" class=\"wp-block-heading\">How Do You Install GitLab CE on Ubuntu Using the Omnibus Package?<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1600\" height=\"1161\" data-src=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE.webp\" alt=\"GitLab Community Edition login form with username, password, sign-in button, and account recovery option.\" class=\"wp-image-85250 lazyload\" data-srcset=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE.webp 1600w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-300x218.webp 300w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-1024x743.webp 1024w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-768x557.webp 768w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-1536x1115.webp 1536w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-600x435.webp 600w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-1200x871.webp 1200w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-730x530.webp 730w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-1460x1059.webp 1460w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-784x569.webp 784w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-1568x1138.webp 1568w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/01-GitLab-CE-877x636.webp 877w\" data-sizes=\"(max-width: 1600px) 100vw, 1600px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1600px; --smush-placeholder-aspect-ratio: 1600\/1161;\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Add the GitLab CE repository:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -sSL https:\/\/packages.gitlab.com\/install\/repositories\/gitlab\/gitlab-ce\/script.deb.sh | sudo bash<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Then, install GitLab CE with your domain set as the external URL:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo EXTERNAL_URL=\"https:\/\/gitlab.example.com\" apt install gitlab-ce<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Setting `https:\/\/` here tells GitLab to automatically request a Let&#8217;s Encrypt certificate during installation, as long as ports 80 and 443 are open and DNS is pointed correctly. If either of those isn&#8217;t ready, the install completes but SSL fails \u2014 and you spend the next thirty minutes troubleshooting something that isn&#8217;t actually broken.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Next, wait for the reconfigure step.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">GitLab runs `gitlab-ctl reconfigure` (the command that applies any changes to GitLab&#8217;s configuration) automatically at the end of install. It takes five to 10 minutes. <em>And yes, the reconfigure step really does take that long.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Get the initial root password:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo cat \/etc\/gitlab\/initial_root_password<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This file is auto-generated and gets deleted in 24 hours, so grab the password and log in. Visit your domain in a browser, sign in as `root`, and change the password immediately.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Finally, verify the install.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">From the GitLab welcome screen, create a test project. Push a commit to it from your local machine. If the push succeeds and the file shows up in the web UI, the install is healthy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the reconfigure step hangs, check `tail -f \/var\/log\/gitlab\/reconfigure\/*.log`. That&#8217;s where the actual error lives.<\/p>\n\n\n\n<h2 id=\"h-how-do-you-lock-down-a-self-hosted-gitlab-instance\" class=\"wp-block-heading\">How Do You Lock Down a Self-Hosted GitLab Instance?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">GitLab ships with reasonable defaults, but they\u2019re tuned for an open community server, not your private team instance. Spend an hour here.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1600\" height=\"975\" data-src=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_.webp\" alt=\"GitLab CE settings showing security options for diff limits, sign-up restrictions, and sign-in authentication methods.\" class=\"wp-image-85251 lazyload\" data-srcset=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_.webp 1600w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-300x183.webp 300w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-1024x624.webp 1024w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-768x468.webp 768w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-1536x936.webp 1536w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-600x366.webp 600w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-1200x731.webp 1200w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-730x445.webp 730w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-1460x890.webp 1460w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-784x478.webp 784w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-1568x956.webp 1568w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/02-How-Do-You-Lock-Down-a-Self-Hosted-GitLab-Instance_-877x534.webp 877w\" data-sizes=\"(max-width: 1600px) 100vw, 1600px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1600px; --smush-placeholder-aspect-ratio: 1600\/975;\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Disable open sign-up.<\/strong> <em>Open sign-up is on by default.<\/em> In the Admin Area, navigate to <em>Settings<\/em> &gt; <em>General<\/em> &gt; <em>Sign-up restrictions<\/em> and turn off the &#8220;Sign-up enabled&#8221; checkbox. Otherwise, anyone with the URL can create an account.<\/li>\n\n\n\n<li><strong>Enable two-factor authentication.<\/strong> Go to <em>Admin Area<\/em> &gt; <em>Settings<\/em> &gt; <em>General<\/em> &gt; <em>Sign-in restrictions<\/em> and enforce 2FA for all users. Lower the grace period from the default 48 hours to 8 hours.<\/li>\n\n\n\n<li><strong>Restrict project creation.<\/strong> Set <em>Default Project Creation<\/em> to <em>Maintainers<\/em> or <em>No one<\/em>, depending on how locked down you want it.<\/li>\n\n\n\n<li><strong>Verify SSL renewal.<\/strong> GitLab auto-renews Let&#8217;s Encrypt certificates by default. To confirm, run `sudo gitlab-ctl renew-le-certs` once and check the output.<\/li>\n\n\n\n<li><strong>Lock down SSH on the VPS itself.<\/strong> Disable root password login, allow only SSH key authentication, and (if you can swing it) move SSH off port 22. A self-hosted Git server is only as secure as the box underneath it.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">For an in-depth version, GitLab published a <a target=\"_blank\" href=\"https:\/\/about.gitlab.com\/security\/hardening\/\">Hardening Guide<\/a> covering authentication, encryption, and instance settings. Read it once, apply what matches your threat model, and move on.<\/p>\n\n\n\n<h2 id=\"h-how-do-you-back-up-and-restore-a-self-hosted-gitlab-instance\" class=\"wp-block-heading\">How Do You Back Up and Restore a Self-Hosted GitLab Instance?<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1600\" height=\"1272\" data-src=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data.webp\" alt=\"Database, repositories, and uploads back up to \/var\/opt\/gitlab\/backups, with config and secret files copied separately.\" class=\"wp-image-85252 lazyload\" data-srcset=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data.webp 1600w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-300x239.webp 300w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-1024x814.webp 1024w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-768x611.webp 768w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-1536x1221.webp 1536w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-600x477.webp 600w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-1200x954.webp 1200w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-730x580.webp 730w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-1460x1161.webp 1460w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-784x623.webp 784w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-1568x1247.webp 1568w, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/03-How-GitLab-Backs-Up-Your-Data-877x697.webp 877w\" data-sizes=\"(max-width: 1600px) 100vw, 1600px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1600px; --smush-placeholder-aspect-ratio: 1600\/1272;\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">GitLab includes a built-in backup tool. The first time you need it, you&#8217;ll be glad you set it up.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Create a backup:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo gitlab-backup create<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This drops a tarball into `\/var\/opt\/gitlab\/backups`. Schedule it daily via cron with a seven-day retention window. Run <code>sudo crontab -e<\/code> and add these two lines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>0 2 * * * \/opt\/gitlab\/bin\/gitlab-backup create CRON=1\n0 3 * * * find \/var\/opt\/gitlab\/backups -name \"*.tar\" -mtime +7 -delete<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>CRON=1<\/code> flag suppresses progress output so that it doesn\u2019t spam cron logs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pro tip:<\/strong> the data backup does not include `\/etc\/gitlab\/gitlab-secrets.json` or `\/etc\/gitlab\/gitlab.rb`.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Those files hold the database encryption key, two-factor seeds, and CI\/CD variables. The configuration secrets are not part of the regular backup and <a target=\"_blank\" href=\"https:\/\/docs.gitlab.com\/administration\/backup_restore\/backup_gitlab\/\">must be saved separately<\/a>. Restore data without the secrets file, and two-factor accounts break, encrypted variables turn into garbage, and you spend a long evening figuring out why.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Add this to the same cron job:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo cp \/etc\/gitlab\/gitlab-secrets.json \/etc\/gitlab\/gitlab.rb \/var\/opt\/gitlab\/backups\/<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A <a target=\"_blank\" href=\"https:\/\/docs.gitlab.com\/administration\/backup_restore\/restore_gitlab\/\">backup can only be restored<\/a> to the same version and edition (CE-to-CE, not CE-to-EE) of GitLab on which it was created.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Upgrade carefully: don&#8217;t restore an old backup onto a freshly installed GitLab without first downgrading the install to match.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Test the restore process at least once.<\/em> A backup you\u2019ve never tested is just a file.<\/p>\n\n\n\n<h2 id=\"h-is-self-hosting-gitlab-actually-worth-it-for-your-team\" class=\"wp-block-heading\">Is Self-Hosting GitLab Actually Worth It for Your Team?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Self-hosting GitLab is a control decision for most teams. The cost math sometimes works out, but the <em>reason<\/em> people stick with self-hosting is rarely the line item.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s the honest monthly time cost for a small-team install:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>~30 minutes of patching \u2013<\/strong> apt upgrades, GitLab minor releases<\/li>\n\n\n\n<li><strong>~15 minutes of backup verification<\/strong> <strong>\u2013 <\/strong>don&#8217;t trust a backup you haven&#8217;t restored<\/li>\n\n\n\n<li><strong>~15 minutes of capacity check \u2013<\/strong> disk usage, RAM headroom<\/li>\n\n\n\n<li><strong>~2x if CI\/CD runs on the box \u2013<\/strong> A busy runner can double the load<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s about an hour a month on a slow week, or two on a busy one.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At around $150 per hour, 12 hours of operational time runs about $1,800 \u2014 roughly five GitLab.com Premium seats.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A practitioner case study from <a target=\"_blank\" href=\"https:\/\/maddevs.io\/blog\/how-do-we-save-about-10000-a-year-using-self-hosted-gitlab\/\">Mad Devs<\/a> walks through how their team saves more than $10,000 per year by running self-hosted GitLab CE instead of paying for Premium seats. The savings only materialize once the team is large enough that seat licenses dominate the budget.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That said, self-hosting is the wrong choice for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Two- to three-person teams without compliance reasons.<\/strong> GitLab.com Free covers you. The operational time is more than the saved cost.<\/li>\n\n\n\n<li><strong>Teams without anyone comfortable on the command line.<\/strong> &#8220;Comfortable&#8221; doesn&#8217;t mean sysadmin-grade. It means you can read `\/var\/log\/gitlab` errors without panic.<\/li>\n\n\n\n<li><strong>Teams whose biggest blocker is hiring, not tooling.<\/strong> Self-hosting takes attention away from the product. If product velocity is the constraint, hosted is the right call.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">So, when does self-hosting make sense? Below are a few scenarios:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Regulated industries<\/strong> with explicit data-residency or chain-of-custody requirements<\/li>\n\n\n\n<li><strong>EU\/UK teams<\/strong> with sovereignty concerns about U.S.-hosted code<\/li>\n\n\n\n<li><strong>Teams of 30+<\/strong> where seat licenses dominate the budget<\/li>\n\n\n\n<li><strong>Customer contracts<\/strong> that forbid third-party SaaS for source code<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If your reason is <em>&#8220;GitHub charges per seat,&#8221;<\/em> you&#8217;ll probably come out ahead. If your reason is <em>&#8220;I want to feel in control,&#8221;<\/em> you might find the operational reality less romantic than expected.<\/p>\n\n\n\n<h2 id=\"h-should-you-run-gitlab-ci-cd-runners-on-the-same-vps\" class=\"wp-block-heading\">Should You Run GitLab CI\/CD Runners on the Same VPS?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For evaluation, yes. For production, no.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A CI runner on the same box steals memory and CPU from the GitLab UI. The classic symptom is &#8220;GitLab feels slow at 9 a.m.,&#8221; which usually traces back to a build kicking off the morning&#8217;s first pipeline and starving the web frontend. The cleaner setup is a separate small VPS (or a <a target=\"_blank\" href=\"https:\/\/www.dreamhost.com\/cloud\/computing\/\">DreamCompute<\/a> instance) for the runner, registered to the GitLab instance over the network.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you must keep runners on the same box, bump the VPS to 16 GB.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">According to <a target=\"_blank\" href=\"https:\/\/docs.gitlab.com\/runner\/install\/requirements\/\">GitLab&#8217;s runner system requirements<\/a>, the runner process itself is light. The workloads it executes are not, and they share the box&#8217;s CPU and disk with everything else GitLab is doing.<\/p>\n\n\n\n<h2 id=\"h-ready-to-make-the-switch\" class=\"wp-block-heading\">Ready to Make the Switch?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Back to the Friday afternoon team chat.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If GitHub goes yellow and your team laughs about it again and goes to get coffee, that&#8217;s fine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But if GitHub going down starts to feel like something serious?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Maybe it\u2019s threatening a customer contract? Comes up in a compliance audit? Or the seat-license bill finally crossed the line?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Self-hosting GitLab CE starts to become a totally reasonable option. All it takes is a VPS, a domain, an Omnibus install, and an hour of hardening.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By the next time the GitHub status page lights up, your code will keep pushing just fine.<\/p>\n\n\n\n\n<div class=\"article-cta-shared article-cta-small article-cta--product\">\n\t<div class=\"tr-img-wrap-outer jsLoading\"><img decoding=\"async\" class=\"js-img-lazy \" src=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/themes\/blog2018\/assets\/img\/lazy-loading-transparent.webp\" data-srcset=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/06\/cta_image_a-877x522.webp 1x, https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/06\/cta_image_a.webp 2x\"  \/><\/div>\n\n\t<a href='https:\/\/www.dreamhost.com\/hosting\/vps\/' class='link-top' target='_blank' rel='noopener noreferrer'>\n\t\t<span>VPS<\/span>\n\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 384 512\" width=\"15\"><path d=\"M342.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L274.7 256 105.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z\"\/><\/svg>\n\t<\/a>\n\n\t<div class=\"content-btm\">\n\t\t<h2 class=\"h2--md\">\n\t\t\tOwn Your Entire Stack. Apps, AI, Databases, and More.\n\t\t<\/h2>\n\t\t<p class=\"p--md\">\n\t\t\tKeep every credential and conversation on a server you control, with NVMe speed and unmetered bandwidth built in.\n\t\t<\/p>\n\n\t\t        <a\n            href=\"https:\/\/www.dreamhost.com\/hosting\/vps\/\"\n                        class=\"btn btn--white-outline btn--sm btn--round\"\n                                    target=\"_blank\"\n            rel=\"noopener noreferrer\"\n            >\n                            Explore VPS Hosting Plans                    <\/a>\n\n\t<\/div>\n<\/div>\n\n\n<h2 id=\"h-frequently-asked-questions-about-self-hosting-gitlab\" class=\"wp-block-heading\">Frequently Asked Questions About Self-Hosting GitLab<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Is there anything else you want to know about self-hosting GitLab on a VPS? Below are the answers to some commonly asked questions.<\/p>\n\n\n\n<h3 id=\"h-is-gitlab-ce-free-for-self-hosting\" class=\"wp-block-heading\">Is GitLab CE free for self-hosting?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes, GitLab CE is free for self-hosting under an MIT-style open-source license. There&#8217;s no user limit and no per-seat pricing. The only costs are the VPS itself and the operational time to maintain it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">DreamHost&#8217;s VPS Stack 4 is a reasonable starting point for evaluation. Production teams typically run on Stack 8 or Stack 16.<\/p>\n\n\n\n<h3 id=\"h-how-much-ram-does-gitlab-ce-actually-need\" class=\"wp-block-heading\">How much RAM does GitLab CE actually need?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Plan for 16 GB of RAM for up to 1,000 users, which is GitLab&#8217;s published baseline (about 20 requests per second). Smaller teams can run on less, down to a documented floor of 2 GB plus 1 GB of swap for evaluation. Either way, if you run CI\/CD pipelines on the same box, plan for 16 GB.<\/p>\n\n\n\n<h3 id=\"h-can-i-self-host-gitlab-on-a-4-gb-vps\" class=\"wp-block-heading\">Can I self-host GitLab on a 4 GB VPS?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes, you can run GitLab CE on 4 GB, but it will feel sluggish under any real load. GitLab documents a 2 GB + 1 GB swap fallback for memory-constrained environments \u2014 that path is for evaluation, not production. For a team actively pushing code and running pipelines, 8 GB is the practical minimum.<\/p>\n\n\n\n<h3 id=\"h-how-long-does-it-take-to-install-gitlab-ce-on-a-vps\" class=\"wp-block-heading\">How long does it take to install GitLab CE on a VPS?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">About 10 to 15 minutes for the package install, plus roughly an hour for prep and hardening, so about 90 minutes start to finish. The install itself is mostly waiting on the reconfigure step.<br><br>The hardening pass, which requires disabling open sign-up, enforcing two-factor authentication, and locking down project creation, takes the remaining hour and is non-optional for any production instance.<\/p>\n\n\n\n<h3 id=\"h-is-self-hosting-gitlab-worth-it-for-a-five-person-team\" class=\"wp-block-heading\">Is self-hosting GitLab worth it for a five-person team?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Probably not, unless you have a privacy or compliance reason. GitLab.com Free covers up to five users with unlimited private projects and 400 CI\/CD minutes per month. The operational time of self-hosting outweighs the saved per-seat cost at that team size.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Self-hosting starts to pay off, in pure cost terms, around 30+ active users.<\/p>\n\n\n\n<h3 id=\"h-what-s-the-difference-between-gitlab-ce-and-gitlab-community-edition\" class=\"wp-block-heading\">What&#8217;s the difference between GitLab CE and GitLab Community Edition?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">GitLab CE and GitLab Community Edition are the same product. CE is the standard abbreviation. The &#8220;Self-Managed&#8221; terminology refers to where you run it (your infrastructure), not which edition.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">GitLab Community Edition is open-source. GitLab Enterprise Edition (EE) adds paid features on top of the same code base.<\/p>\n\n\n\n<h3 id=\"h-where-does-gitlab-ce-differ-from-gitlab-ee\" class=\"wp-block-heading\">Where does GitLab CE differ from GitLab EE?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">GitLab CE is the free, open-source edition. GitLab EE uses the same code base, plus paid features that activate when you upload a license file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The practical difference comes down to the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>CE is MIT-licensed and fully functional.<\/strong> Source control, merge requests, issues, basic CI\/CD, container registry, the works.<\/li>\n\n\n\n<li><strong>EE adds enterprise features behind a license.<\/strong> Think <a target=\"_blank\" href=\"https:\/\/docs.gitlab.com\/user\/group\/epics\/\">epics<\/a>, advanced compliance frameworks, value-stream analytics, multiple approval rules, and advanced security scanning. Per <a target=\"_blank\" href=\"https:\/\/about.gitlab.com\/pricing\/feature-comparison\/\">GitLab&#8217;s self-managed feature comparison<\/a>, the gap matters mostly for organizations with formal change-management processes.<\/li>\n\n\n\n<li><strong>You can install EE without a license,<\/strong> and it functions as CE until licensed. That&#8217;s how most teams hedge against a future need to upgrade.<\/li>\n\n\n\n<li><strong>You cannot downgrade EE to CE cleanly.<\/strong> Plan accordingly.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For most self-hosting teams, CE is sufficient. If your reason is privacy or cost, EE features rarely change the calculus.<\/p>\n\n\n\n<h3 id=\"h-how-do-i-keep-my-self-hosted-gitlab-instance-updated\" class=\"wp-block-heading\">How do I keep my self-hosted GitLab instance updated?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Run `sudo apt update &amp;&amp; sudo apt upgrade gitlab-ce` to apply security patches. Monthly cadence is the practical floor for a production instance. Always create a backup before upgrading.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Major version upgrades must be done sequentially \u2014 you cannot skip major versions. Going from 16.x to 18.x requires upgrading to 17.x first, then 18.x. Skipping a major version will break database migrations. Always check the <a target=\"_blank\" href=\"https:\/\/gitlab-com.gitlab.io\/support\/toolbox\/upgrade-path\/\">GitLab upgrade path tool <\/a>before upgrading, and create a backup immediately before each step.<\/p>\n\n\n\n<h3 id=\"h-where-does-dreamhost-fit-into-self-hosted-gitlab\" class=\"wp-block-heading\">Where does DreamHost fit into self-hosted GitLab?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.dreamhost.com\/hosting\/vps\/\" target=\"_blank\" rel=\"noreferrer noopener\">DreamHost&#8217;s VPS Hosting<\/a> provides the root-access Linux server GitLab CE installs onto. The Stack 16 plan (16 GB RAM) matches GitLab&#8217;s official requirement for up to 1,000 users, with headroom for active CI\/CD pipelines.<\/p>\n\n\n<p><script type=\"application\/ld+json\"><br \/>\n{<br \/>\n  \"@context\": \"https:\/\/schema.org\",<br \/>\n  \"@type\": \"FAQPage\",<br \/>\n  \"mainEntity\": [<br \/>\n    {<br \/>\n      \"@type\": \"Question\",<br \/>\n      \"name\": \"Is GitLab CE free for self-hosting?\",<br \/>\n      \"acceptedAnswer\": {<br \/>\n        \"@type\": \"Answer\",<br \/>\n        \"text\": \"Yes, GitLab CE is free for self-hosting under an MIT-style open-source license. There's no user limit and no per-seat pricing. The only costs are the VPS itself and the operational time to maintain it.\"<br \/>\n      }<br \/>\n    },<br \/>\n    {<br \/>\n      \"@type\": \"Question\",<br \/>\n      \"name\": \"How much RAM does GitLab CE actually need?\",<br \/>\n      \"acceptedAnswer\": {<br \/>\n        \"@type\": \"Answer\",<br \/>\n        \"text\": \"Plan for 16 GB of RAM for up to 1,000 users, which is GitLab's published baseline (about 20 requests per second). Smaller teams can run on less, down to a documented floor of 2 GB plus 1 GB of swap for evaluation. Either way, if you run CI\/CD pipelines on the same box, plan for 16 GB.\"<br \/>\n      }<br \/>\n    },<br \/>\n    {<br \/>\n      \"@type\": \"Question\",<br \/>\n      \"name\": \"Can I self-host GitLab on a 4 GB VPS?\",<br \/>\n      \"acceptedAnswer\": {<br \/>\n        \"@type\": \"Answer\",<br \/>\n        \"text\": \"Yes, you can run GitLab CE on 4 GB, but it will feel sluggish under any real load. GitLab documents a 2 GB + 1 GB swap fallback for memory-constrained environments \u2014 that path is for evaluation, not production. For a team actively pushing code and running pipelines, 8 GB is the practical minimum.\"<br \/>\n      }<br \/>\n    },<br \/>\n    {<br \/>\n      \"@type\": \"Question\",<br \/>\n      \"name\": \"How long does it take to install GitLab CE on a VPS?\",<br \/>\n      \"acceptedAnswer\": {<br \/>\n        \"@type\": \"Answer\",<br \/>\n        \"text\": \"About 10 to 15 minutes for the package install, plus roughly an hour for prep and hardening, so about 90 minutes start to finish. The install itself is mostly waiting on the reconfigure step. The hardening pass, which requires disabling open sign-up, enforcing two-factor authentication, and locking down project creation, takes the remaining hour and is non-optional for any production instance.\"<br \/>\n      }<br \/>\n    },<br \/>\n    {<br \/>\n      \"@type\": \"Question\",<br \/>\n      \"name\": \"Is self-hosting GitLab worth it for a five-person team?\",<br \/>\n      \"acceptedAnswer\": {<br \/>\n        \"@type\": \"Answer\",<br \/>\n        \"text\": \"Probably not, unless you have a privacy or compliance reason. GitLab.com Free covers up to five users with unlimited private projects and 400 CI\/CD minutes per month. The operational time of self-hosting outweighs the saved per-seat cost at that team size.\"<br \/>\n      }<br \/>\n    },<br \/>\n    {<br \/>\n      \"@type\": \"Question\",<br \/>\n      \"name\": \"What's the difference between GitLab CE and GitLab Community Edition?\",<br \/>\n      \"acceptedAnswer\": {<br \/>\n        \"@type\": \"Answer\",<br \/>\n        \"text\": \"GitLab CE and GitLab Community Edition are the same product. CE is the standard abbreviation. The \"Self-Managed\" terminology refers to where you run it (your infrastructure), not which edition.\"<br \/>\n      }<br \/>\n    },<br \/>\n    {<br \/>\n      \"@type\": \"Question\",<br \/>\n      \"name\": \"Where does GitLab CE differ from GitLab EE?\",<br \/>\n      \"acceptedAnswer\": {<br \/>\n        \"@type\": \"Answer\",<br \/>\n        \"text\": \"GitLab CE is the free, open-source edition. GitLab EE uses the same code base, plus paid features that activate when you upload a license file.\"<br \/>\n      }<br \/>\n    },<br \/>\n    {<br \/>\n      \"@type\": \"Question\",<br \/>\n      \"name\": \"How do I keep my self-hosted GitLab instance updated?\",<br \/>\n      \"acceptedAnswer\": {<br \/>\n        \"@type\": \"Answer\",<br \/>\n        \"text\": \"Run sudo apt update && sudo apt upgrade gitlab-ce to apply security patches. Monthly cadence is the practical floor for a production instance. Always create a backup before upgrading.\"<br \/>\n      }<br \/>\n    },<br \/>\n    {<br \/>\n      \"@type\": \"Question\",<br \/>\n      \"name\": \"Where does DreamHost fit into self-hosted GitLab?\",<br \/>\n      \"acceptedAnswer\": {<br \/>\n        \"@type\": \"Answer\",<br \/>\n        \"text\": \"DreamHost's VPS Hosting (specifically the VPS Hosting for GitLab CE plan) provides the root-access Linux server GitLab CE installs onto. The Stack 16 plan (16 GB RAM) matches GitLab's official requirement for up to 1,000 users, with headroom for active CI\/CD pipelines.\"<br \/>\n      }<br \/>\n    }<br \/>\n  ]<br \/>\n}<br \/>\n<\/script><\/p>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Self-host GitLab CE on a VPS for full code control. Step-by-step setup, real RAM thresholds, and an honest take on whether self-hosting is worth it.<\/p>\n","protected":false},"author":2,"featured_media":85249,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_yoast_wpseo_opengraph-title":"How to Self-Host GitLab CE on a VPS: Step-by-Step Guide","_yoast_wpseo_opengraph-description":"Run GitLab CE on your own VPS for full code control and no per-user fees. Covers Omnibus install, RAM thresholds, and whether self-hosting actually pays off.","_yoast_wpseo_twitter-title":"How to Self-Host GitLab CE on a VPS: Step-by-Step Guide","_yoast_wpseo_twitter-description":"Run GitLab CE on your own VPS for full code control and no per-user fees. Covers Omnibus install, RAM thresholds, and whether self-hosting actually pays off.","toc_headlines":"[[\"h-why-would-you-self-host-gitlab-instead-of-using-gitlab-com\",\"Why Would You Self-Host GitLab Instead of Using GitLab.com?\"],[\"h-what-are-the-hardware-requirements-for-gitlab-ce\",\"What Are the Hardware Requirements for GitLab CE?\"],[\"h-how-do-you-prepare-your-vps-before-installing-gitlab\",\"How Do You Prepare Your VPS Before Installing GitLab?\"],[\"h-how-do-you-install-gitlab-ce-on-ubuntu-using-the-omnibus-package\",\"How Do You Install GitLab CE on Ubuntu Using the Omnibus Package?\"],[\"h-how-do-you-lock-down-a-self-hosted-gitlab-instance\",\"How Do You Lock Down a Self-Hosted GitLab Instance?\"],[\"h-how-do-you-back-up-and-restore-a-self-hosted-gitlab-instance\",\"How Do You Back Up and Restore a Self-Hosted GitLab Instance?\"],[\"h-is-self-hosting-gitlab-actually-worth-it-for-your-team\",\"Is Self-Hosting GitLab Actually Worth It for Your Team?\"],[\"h-should-you-run-gitlab-ci-cd-runners-on-the-same-vps\",\"Should You Run GitLab CI\/CD Runners on the Same VPS?\"],[\"h-ready-to-make-the-switch\",\"Ready to Make the Switch?\"],[\"h-frequently-asked-questions-about-self-hosting-gitlab\",\"Frequently Asked Questions About Self-Hosting GitLab\"]]","hide_toc":false,"footnotes":""},"categories":[550,807,804],"tags":[],"class_list":["post-85247","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","category-vps-hosting","category-web-hosting"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.3 (Yoast SEO v27.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How To Self-Host GitLab CE on a VPS - DreamHost<\/title>\n<meta name=\"description\" content=\"Self-host GitLab CE on a VPS for full code control. Step-by-step setup, real RAM thresholds, and an honest take on whether self-hosting is worth it.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Self-Host GitLab CE on a VPS: Step-by-Step Guide\" \/>\n<meta property=\"og:description\" content=\"Run GitLab CE on your own VPS for full code control and no per-user fees. Covers Omnibus install, RAM thresholds, and whether self-hosting actually pays off.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/\" \/>\n<meta property=\"og:site_name\" content=\"DreamHost Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/DreamHost\/\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-07T14:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-07T14:46:51+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1220x628_OGIMAGE_How-To-Self-Host-GitLab-CE-on-a-VPS.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Dallas Kashuba\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"How to Self-Host GitLab CE on a VPS: Step-by-Step Guide\" \/>\n<meta name=\"twitter:description\" content=\"Run GitLab CE on your own VPS for full code control and no per-user fees. Covers Omnibus install, RAM thresholds, and whether self-hosting actually pays off.\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/dallas\" \/>\n<meta name=\"twitter:site\" content=\"@dreamhost\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Dallas Kashuba\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How To Self-Host GitLab CE on a VPS - DreamHost","description":"Self-host GitLab CE on a VPS for full code control. Step-by-step setup, real RAM thresholds, and an honest take on whether self-hosting is worth it.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/","og_locale":"en_US","og_type":"article","og_title":"How to Self-Host GitLab CE on a VPS: Step-by-Step Guide","og_description":"Run GitLab CE on your own VPS for full code control and no per-user fees. Covers Omnibus install, RAM thresholds, and whether self-hosting actually pays off.","og_url":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/","og_site_name":"DreamHost Blog","article_publisher":"https:\/\/www.facebook.com\/DreamHost\/","article_published_time":"2026-07-07T14:00:00+00:00","article_modified_time":"2026-07-07T14:46:51+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1220x628_OGIMAGE_How-To-Self-Host-GitLab-CE-on-a-VPS.webp","type":"image\/webp"}],"author":"Dallas Kashuba","twitter_card":"summary_large_image","twitter_title":"How to Self-Host GitLab CE on a VPS: Step-by-Step Guide","twitter_description":"Run GitLab CE on your own VPS for full code control and no per-user fees. Covers Omnibus install, RAM thresholds, and whether self-hosting actually pays off.","twitter_creator":"@http:\/\/twitter.com\/dallas","twitter_site":"@dreamhost","twitter_misc":{"Written by":"Dallas Kashuba","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/#article","isPartOf":{"@id":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/"},"author":{"name":"Dallas Kashuba","@id":"https:\/\/www.dreamhost.com\/blog\/#\/schema\/person\/f6a12ad459538e8e418cf31b8b603814"},"headline":"How To Self-Host GitLab CE on a VPS","datePublished":"2026-07-07T14:00:00+00:00","dateModified":"2026-07-07T14:46:51+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/"},"wordCount":3114,"publisher":{"@id":"https:\/\/www.dreamhost.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1460x1095-BLOG-HERO-How-To-Self-Host-GitLab-CE-on-a-VPS.webp","articleSection":["Tutorials","VPS Hosting","Web Hosting"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/","url":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/","name":"How To Self-Host GitLab CE on a VPS - DreamHost","isPartOf":{"@id":"https:\/\/www.dreamhost.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/#primaryimage"},"image":{"@id":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1460x1095-BLOG-HERO-How-To-Self-Host-GitLab-CE-on-a-VPS.webp","datePublished":"2026-07-07T14:00:00+00:00","dateModified":"2026-07-07T14:46:51+00:00","description":"Self-host GitLab CE on a VPS for full code control. Step-by-step setup, real RAM thresholds, and an honest take on whether self-hosting is worth it.","breadcrumb":{"@id":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/#primaryimage","url":"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1460x1095-BLOG-HERO-How-To-Self-Host-GitLab-CE-on-a-VPS.webp","contentUrl":"https:\/\/www.dreamhost.com\/blog\/wp-content\/uploads\/2026\/07\/1460x1095-BLOG-HERO-How-To-Self-Host-GitLab-CE-on-a-VPS.webp","width":1460,"height":1095,"caption":"How To Self-Host GitLab CE on a VPS"},{"@type":"BreadcrumbList","@id":"https:\/\/www.dreamhost.com\/blog\/self-host-gitlab-ce-on-vps\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.dreamhost.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How To Self-Host GitLab CE on a VPS"}]},{"@type":"WebSite","@id":"https:\/\/www.dreamhost.com\/blog\/#website","url":"https:\/\/www.dreamhost.com\/blog\/","name":"DreamHost Blog","description":"","publisher":{"@id":"https:\/\/www.dreamhost.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dreamhost.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.dreamhost.com\/blog\/#organization","name":"DreamHost","url":"https:\/\/www.dreamhost.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dreamhost.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/dhblog.dream.press\/blog\/wp-content\/uploads\/2019\/01\/dh_logo-blue-2.png","contentUrl":"https:\/\/dhblog.dream.press\/blog\/wp-content\/uploads\/2019\/01\/dh_logo-blue-2.png","width":1200,"height":168,"caption":"DreamHost"},"image":{"@id":"https:\/\/www.dreamhost.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/DreamHost\/","https:\/\/x.com\/dreamhost","https:\/\/www.instagram.com\/dreamhost\/","https:\/\/www.linkedin.com\/company\/dreamhost\/","https:\/\/www.youtube.com\/user\/dreamhostusa"]},{"@type":"Person","@id":"https:\/\/www.dreamhost.com\/blog\/#\/schema\/person\/f6a12ad459538e8e418cf31b8b603814","name":"Dallas Kashuba","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/05ab6fb1606be97d16c74efb0fba01b3c11e91501dc5f9661bdfbb5c5b0cd113?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/05ab6fb1606be97d16c74efb0fba01b3c11e91501dc5f9661bdfbb5c5b0cd113?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/05ab6fb1606be97d16c74efb0fba01b3c11e91501dc5f9661bdfbb5c5b0cd113?s=96&d=mm&r=g","caption":"Dallas Kashuba"},"description":"Dallas Kashuba co-founded DreamHost while attending Harvey Mudd College and has spent nearly three decades building infrastructure at scale. Today he serves as an advisor, board member, and investor for various tech startups, with a consistent focus on user privacy, open source, and data portability. When he's not thinking about the Open Web, he's probably making music. Follow Dallas on X.","sameAs":["http:\/\/www.idallas.com\/","https:\/\/x.com\/http:\/\/twitter.com\/dallas"],"url":"https:\/\/www.dreamhost.com\/blog\/author\/dallas\/"}]}},"lang":"en","translations":{"en":85247,"de":85510,"es":85477,"nl":85482,"pl":85485,"it":85488,"ru":85495,"uk":85501,"fr":85504,"pt":85506},"pll_sync_post":{},"_links":{"self":[{"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/posts\/85247","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"version-history":[{"count":7,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/posts\/85247\/revisions"}],"predecessor-version":[{"id":85275,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/posts\/85247\/revisions\/85275"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/media\/85249"}],"wp:attachment":[{"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/media?parent=85247"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/categories?post=85247"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dreamhost.com\/blog\/wp-json\/wp\/v2\/tags?post=85247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}