The reliable way to self-host GitLab on a VPS is to run GitLab’s official Docker image with Docker Compose, persist its three data directories on the host, point a real DNS name at the server, and pin the image to one GitLab version. GitLab lists 8 vCPUs as the baseline for a single-node installation; your repositories, CI jobs, registry, LFS objects, users, and retention policies may require more capacity.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
This guide covers the host layout, Compose configuration, DNS and HTTPS, SSH ports, initial administration, backups, upgrades, migration, and the failure points that most often make a deployment unusable.
As an Amazon Associate I earn from qualifying purchases.
Recommended Free Tools
What you need before deploying
A suitable VPS
GitLab’s current single-node installation requirements list 8 vCPUs as the minimum hardware baseline. Treat that as a starting point rather than a sizing guarantee. Rails, PostgreSQL, Redis, Gitaly, background jobs, CI runners, the container registry, Git LFS, artifacts, and concurrent users all consume resources.
Choose sustained CPU performance. GitLab’s requirements guidance cautions against burstable instance types because their performance is inconsistent. Leave headroom for upgrades, repository growth, temporary backup files, and CI bursts instead of sizing the server to today’s average load.
#1 Best Overall
- [Ultra-Lightweight Ear Buds Designed for Small Ears] Each earbud weighs only 3.7g and features a compact, ergonomic in-ear design made especially for small ears. Secure, low-profile, and comfortable for workouts, all-day wear or overnight sleeping.The ultra-slim profile sits flush in your ear with no hard edges poking or rubbing, so you can even sleep on your side without discomfort.
- [Immersive Stereo Sound with TOZO OrigX Technology] TOZO OrigX tuning delivers clear vocals, balanced mids, and natural stereo sound for music, podcasts, and videos.
- [Long Battery Life for Daily Use] Get up to 7 hours of playtime on a single charge, with up to 32 hours total using the charging case—ideal for workdays, commuting, and extended listening sessions.
- [Bluetooth 5.3 & Stable Connection] Bluetooth 5.3 provides fast pairing, stable wireless performance, and reduced dropouts as you move around home or office.
- [Deep Bass with Clear Vocals] High-performance drivers produce punchy bass while keeping vocals clean and detailed for everyday listening.
| VPS consideration | What to verify |
|---|---|
| CPU | At least 8 vCPUs for the documented single-node baseline, with sustained rather than burst-only performance. |
| Memory | Enough headroom for Rails, PostgreSQL, Redis, Gitaly, and your CI workload; the requirements do not establish one universal amount for every workload. |
| Storage | Fast persistent disks with capacity for repositories, artifacts, uploads, registry images, LFS objects, packages, Terraform state, logs, and backup working space. |
| Network | A publicly reachable IPv4 and/or IPv6 address, DNS control, firewall rules, and reverse-DNS options where your mail setup needs them. |
| Operations | Snapshots or provider backups, off-site backup support, a region appropriate for your users, an upgrade path, and support you can use during an outage. |
Provider prices and commercial terms are not comparable without checking current offers. Select on sustained capacity, disk I/O, recovery options, and support rather than a headline burst specification.
Docker, a hostname, and mail
Install a working Docker Engine and Docker Compose on a supported Linux VPS. GitLab’s Docker installation requires a valid, externally accessible hostname; localhost is not valid. Create the DNS record before testing the public URL and allow time for it to resolve from outside the VPS.
The image contains GitLab’s application services but not an SMTP server. If the instance must send invitations, password resets, notifications, or other mail, configure an external SMTP service or an MTA such as Postfix or Sendmail separately.
Prepare persistent storage
Container replacement must not remove GitLab’s configuration, logs, or application data. Create one host directory and three subdirectories, then expose the parent path through an environment variable:
sudo mkdir -p /srv/gitlab/config /srv/gitlab/logs /srv/gitlab/data
export GITLAB_HOME=/srv/gitlab
The required mounts are:
| Host path | Container path | Contents |
|---|---|---|
$GITLAB_HOME/config |
/etc/gitlab |
GitLab configuration and secrets, including gitlab-secrets.json. |
$GITLAB_HOME/logs |
/var/log/gitlab |
Application and service logs. |
$GITLAB_HOME/data |
/var/opt/gitlab |
Repositories, databases, uploads, artifacts, registry data, and other application state. |
On an SELinux host, use the :Z volume suffix shown in GitLab’s Docker guidance so the container receives the required labeling. Verify ownership and permissions if GitLab cannot write to a mounted directory. Avoid placing Gitaly data on NFS-based filesystems; GitLab warns that NFS can cause performance problems.
Create a pinned Docker Compose deployment
Pin the image to the exact GitLab version you intend to run in production. The latest tag is useful for a quick test, but it is not a controlled production choice because the image can change between deployments. Use the Enterprise Edition pattern below, replacing <version> with the specific release you selected. For Community Edition, use the corresponding gitlab/gitlab-ce tag.
Rank #2
- 【IP68 Waterproof Multifunctinal Smart Watch】Torjalph fitness activity tracker smart watch is IP68 waterproof technology ,you can wear it when swimming,handwashing,it's rain-proof which means that you perform multiple exercise modes outside without worrying about sweat or rain corroding your fitness smart watch,and this watch equipped with a 230 mAh large capacity battery magnetic charging ,and this sports activity tracker watch can be used 5-7 days If fully charged.
- 【Larger 1.83'' Full Screen Watch & Multi-dial Selection】1.83 inch full HD color touch screen smart watch for men / women provides excellent 240*284 resolution image quality ,This Bluetooth smart watch offers a better touch experience and remarkable immersion and ,more than 200 watch faces for you to choose from App"Da Fit ", you can change the dial style according to your mood to wear keeping the world on your wrist
- 【Accurate Activity Tracker Smart Watch 】sports watch activity tracker uses sweat and dust resistant breathable silicone strap, our Fitness Tracker Smart Watch for Android iOS Phones supports 12 sports modes,walking,running,bicycle,swimming,badminton,basketball,football,rope skipping. This bluetooth calls smart watch for men women is lightweight and stylish, bringing more convenient and relaxing sports experience while also providing more protection.
- 【Your 24 Hour Personal Daily Health Monitor】Fitness watch for women men full touch screen IP67 waterproof bluetooth smartwatch for Android iOS Phones with heart rate blood pressure monitor multifunction Andriod smart watch with steps counter sleep monitor sports fitness watch, monitoring blood oxygen saturation allows you to understand your physical condition in real time to track fitness progress ,to know your health status in time.
- 【More Functions Bluetooth Call Smart Watch】This fitness activity smart watch full screen for iPhone and Android phones includes a bunch of new features including:The bluetooth smart watch can hang up the phone, receive and display WhatsAPP /Text /Facebook /Twitter /Messenger reminder.Support sedentary reminder, alarm clock, stopwatch, timer,weather information,music control, remote camera control compatible with Android 5.0 and above or iOS 9.0 and above smartphones.
services:
gitlab:
image: gitlab/gitlab-ee:<version>-ee.0
container_name: gitlab
restart: always
hostname: gitlab.example.com
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.example.com'
gitlab_rails['gitlab_shell_ssh_port'] = 22
ports:
- "80:80"
- "443:443"
- "22:22"
volumes:
- $GITLAB_HOME/config:/etc/gitlab
- $GITLAB_HOME/logs:/var/log/gitlab
- $GITLAB_HOME/data:/var/opt/gitlab
shm_size: '256m'
Save the file, for example as compose.yml, in a directory you can administer. Ensure the shell that runs Compose has GITLAB_HOME set, or replace the variable with /srv/gitlab in all three volume lines.
Start the container with:
docker compose up -d
GitLab initializes several bundled services on the first start. The process can take time. Follow the startup log if the web page is not ready:
docker logs -f gitlab
Stop following with Ctrl+C; that does not stop the container.
Make the domain, HTTPS, and ports agree
DNS and external_url
Replace gitlab.example.com with the hostname users will actually open and point its DNS record to the VPS. The value in external_url must be the exact public scheme and hostname: use https:// when users will connect over TLS. A mismatch can produce incorrect clone URLs, redirects, or callback addresses even when the container itself is running.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Open the corresponding ports in both the VPS firewall and any provider firewall. The example publishes host ports 80 and 443 to GitLab’s HTTP and HTTPS listeners. Publishing a port in Compose does not bypass a blocked network firewall.
HTTPS certificates
Publishing port 443 makes the HTTPS listener reachable, but a usable deployment still needs a valid certificate for the hostname. Configure certificate management in the GitLab installation or use an appropriately configured TLS reverse proxy in front of the container. Keep the public URL, certificate name, and external_url identical.
Rank #3
- [Low Noise High Fidelity] New bee guitar cord with 22AWG oxygen-free-copper center conductors provides enhanced signal transfer, the PVC insulation material and the high-density stranded copper double shield provide noise rejection for quiet operation
- [Ideal for Choice] New bee 1/4 straight and right angle metal connectors, ensures a secure connection in any instrument, pedal, or amp jack. L shape great fro on stage guitar stands
- [Wide Compatible] Suitable for mixer, power amplifier, microphone, effector, decoder, equalizer, electoronic organ, electric guitar, electric bass and other electronic equipments. Widely used in the installation of smart home, karaoke speaker, professional stage audio, etc
- [Easy Disassemble] Making incidental repairs quick and easy! Very nice, flexible cable
- [Dont Hesite to Order] 24 hours customer services and professional technology team are standing by
Using a non-standard SSH port
If another service already uses host port 22, map a different host port to GitLab’s container port 22 and tell GitLab to advertise that host port. For example:
services:
gitlab:
image: gitlab/gitlab-ee:<version>-ee.0
hostname: gitlab.example.com
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.example.com'
gitlab_rails['gitlab_shell_ssh_port'] = 2424
ports:
- "80:80"
- "443:443"
- "2424:22"
volumes:
- $GITLAB_HOME/config:/etc/gitlab
- $GITLAB_HOME/logs:/var/log/gitlab
- $GITLAB_HOME/data:/var/opt/gitlab
shm_size: '256m'
Users will then clone over SSH using port 2424. The published host port, GitLab’s gitlab_shell_ssh_port, firewall rule, and the SSH URL shown in the interface must describe the same port.
Where persistent configuration lives
Inside the container, the main Omnibus configuration file is /etc/gitlab/gitlab.rb, which is stored on the host at $GITLAB_HOME/config/gitlab.rb. You can edit that file and run a reconfigure, or provide settings through GITLAB_OMNIBUS_CONFIG.
Environment-based settings are evaluated at startup and are not written into gitlab.rb. If you use that method, include the settings on every later docker run or Compose deployment; otherwise a replacement container can start without them.
Finish first startup and retrieve the administrator password
After the services finish initializing, retrieve the generated administrator password before restarting the container:
docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
GitLab automatically deletes /etc/gitlab/initial_root_password after the first container restart that occurs after 24 hours. Sign in, change the password, and create your normal administrator credentials rather than relying on that temporary file.
Rank #4
- Digital Family Calendar: BSIMB digital calendar wall touch screen puts an end to your chaotic life. Designed for busy families, the digital calendar keeps you organised and in step with your family. Assign different colours and tasks to each family member to make family scheduling easier and more intuitive.
- Easy Setup and Auto-Sync: Plug in, connect to WLAN and auto-syn your electric calendar in minutes. Digital wall calendar compatible with Google calendar, iCloud calendar, Outlook calendar, Cozi calendar and Yahoo calendar. Add events directly on the device or through the ecalendar app. Electronic calendar stays current whether you're at work or traveling—no manual updates needed.
- All-In-One Home Assistant: Smart calendar builds habits and encourage independence with personalised chores. Display daily meal plan to reduce the daily ‘What's for dinner?’ stress. To-do lists keep track of everything you want. Turning chores into valuable achievements with stars and rewards, making life easier and more enjoyable.
- Manage Anytime Anywhere: BSIMB electronic calendar for family stay connected with the powerful ecalendar app. Access and manage your digital wall calendar anytime, anywhere with free features like stars & rewards, photo screensaver, chore charts, meals plans, to-do lists etc. Electronic planner paid features like Magic Import tailor advanced tools for users with special needs.
- Stay in Touch with Loved Ones: Share photos or videos from your phone to electronic wall calendar with app, instantly update your life moment, and keep in touch with your family, especially those who are far away; you can also surprise your smart calendar digital wall by sending him a wish card; it's also great for keeping tech-illiterate elders in touch with the youngsters.
If the command returns no password, inspect docker logs -f gitlab, confirm that the mounted configuration directory is writable, and check whether the initialization file has already been removed.
Configure outbound email separately
GitLab’s Docker image does not include an SMTP server. Configure SMTP in the Omnibus settings when the instance must send mail, and provide the corresponding credentials and TLS requirements from your mail provider. If you operate Postfix or Sendmail on the VPS, configure that MTA independently and ensure DNS, reverse DNS, authentication, and firewall policy support delivery.
Test a password reset or notification after configuring mail. A healthy web interface does not prove that outbound email is working.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchBack up GitLab before upgrades
Create an application backup
Run GitLab’s backup task inside the running container:
docker exec -t gitlab gitlab-backup create
The backup is written under the mounted data volume. Confirm that a new backup archive appears on the host and that the disk has enough free space for the temporary and final files.
Protect the secrets file and configuration
Also copy /etc/gitlab/gitlab-secrets.json, which is available on the host as:
Best Value
/srv/gitlab/config/gitlab-secrets.json
A repository archive without this secrets file is not a practical recovery set. Keep a separate backup of the configuration directory, including gitlab.rb, and store backup copies off the VPS so a disk failure or server compromise does not destroy both the live instance and its recovery data.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Choose the right pre-upgrade backup
GitLab documents a database-only backup option for rollback-focused preparation. That option deliberately excludes repositories, artifacts, uploads, builds, Pages data, LFS objects, packages, and Terraform state. Use it only when that exclusion is intentional; it is not a substitute for a complete application backup.
Verify recovery, not just backup creation
Set retention limits, copy backups to a separate location, and perform periodic restore tests on an isolated instance. GitLab states that a backup can be restored only to the exact GitLab version and edition on which it was created. Record the running image tag with every backup and retain the previous image tag until an upgrade has been tested.
Upgrade the container without losing the instance
- Record the current version. Save the exact image tag shown by
docker inspect gitlabor your Compose file. - Create and verify a backup. Run
docker exec -t gitlab gitlab-backup create, copy the secrets and configuration files, and confirm the off-host copy exists. - Keep rollback material. Leave the prior image tag available and do not delete the previous backup set.
- Change only the image tag. Edit
compose.ymlto the intended pinned release and keep the hostname, ports, environment settings, and three mounts unchanged. - Recreate the service. Run
docker compose pullfollowed bydocker compose up -d. - Watch initialization. Use
docker logs -f gitlaband wait for all bundled services to become healthy. - Verify user paths. Open the HTTPS URL, sign in, inspect a project, clone over HTTP(S) and SSH, and test a representative CI job or registry operation if you use those features.
Do not restore a backup made by a different GitLab release or edition. If the new container fails, stop further changes, preserve logs, and use the documented rollback plan with the original tag and matching backup.
Migrate an existing Linux-package installation
GitLab documents two migration approaches: reuse the existing data directories in the Docker deployment, or create a fresh Docker instance and restore a backup. The source and destination GitLab versions must match.
Free tools Windows power users keep installed
One-click scans. No signup required.
Fresh Docker deployment and restore
- Record the source GitLab version and edition.
- Prepare the VPS, DNS, Docker installation, and the three host directories.
- Deploy the Docker image with the identical version and edition.
- Restore the application backup and
gitlab-secrets.jsonaccording to GitLab’s restore procedure. - Start the container, then run the configuration and health checks below.
Post-migration checks
docker exec -it gitlab gitlab-ctl reconfigure
docker exec -it gitlab gitlab-rake gitlab:check
Resolve reported database, repository, permissions, or configuration errors before switching all users to the new hostname. Verify projects, SSH access, artifacts, uploads, runners, and registry data that matter to your organization.
Troubleshoot the common failure points
| Symptom | Likely cause | Checks and corrective action |
|---|---|---|
| The URL does not resolve | DNS is missing, stale, or points elsewhere. | Check the public DNS record and confirm it resolves to the VPS address from an external network. |
| Redirects or clone URLs use the wrong host or scheme | external_url does not match the public HTTPS URL. |
Set the exact hostname and scheme, then reconfigure or recreate the container with the corrected setting. |
| SSH clone fails | The host port, firewall, and advertised GitLab SSH port disagree. | Match the Compose mapping, gitlab_shell_ssh_port, and firewall rule; test the port from outside the VPS. |
| GitLab starts slowly or is killed | Insufficient CPU, memory, or disk I/O for the workload. | Inspect container logs and host metrics, free disk space, and move to sustained resources with more headroom. |
| Permission-denied errors on startup | Mounted directories have unsuitable ownership, permissions, or SELinux labels. | Correct the host directory permissions and apply the documented :Z suffix on SELinux systems. |
| Notifications never arrive | No SMTP or MTA has been configured, or mail delivery is blocked. | Configure SMTP separately, then send a test notification and inspect mail-provider or MTA logs. |
| A restore cannot decrypt or start correctly | gitlab-secrets.json is missing, or the target version/edition differs. |
Restore the secrets file and use the exact same GitLab version and edition as the backup. |
| Repository operations are slow on shared storage | Gitaly data is on NFS or another storage layer with unsuitable latency. | Move repository data to fast local persistent storage and reassess disk I/O. |
Operational checklist
- Use the official GitLab Docker image and pin a specific production version.
- Keep
/etc/gitlab,/var/log/gitlab, and/var/opt/gitlabon persistent host mounts. - Use a publicly resolvable DNS name; never configure the deployment with
localhost. - Make
external_url, HTTPS exposure, SSH mapping, and firewall rules describe the same public endpoints. - Provide SMTP separately when GitLab must send mail.
- Back up the application, configuration, and
gitlab-secrets.jsonto off-host storage. - Test restores on the exact matching GitLab version and edition.
- Back up before every upgrade, retain the previous image tag, and verify real user workflows afterward.
The Bottom Line
A production-ready Docker GitLab installation is primarily an exercise in consistency: pin the image, persist all three Omnibus directories, use a real DNS name, align every public port with external_url, and prove that backups—including gitlab-secrets.json—can be restored before changing versions.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

