How To Install GitLab on Fedora 44

Install GitLab on Fedora 44

Running a self-hosted Git platform gives your team full control over source code, CI/CD pipelines, and user access without sending sensitive data to third-party services. Many organizations choose Fedora 44 for its cutting-edge security features and rapid adoption of upstream patches, but installing GitLab on this distribution requires understanding Fedora’s unique security model. This guide walks you through the complete process to install GitLab on Fedora 44 using the official Omnibus package method, which bundles all dependencies into a single, manageable installation.

GitLab Community Edition (CE) is a free, open-source DevOps platform that includes Git repository hosting, built-in CI/CD runners, issue tracking, and container registry support. Unlike GitHub or GitLab.com, self-hosting means you control when backups happen, which users can access the system, and where your data physically resides. The installation process looks intimidating at first, but breaking it into discrete steps with clear explanations of why each command matters makes it straightforward even for beginners.

This tutorial assumes you are comfortable with the Linux command line and have sudo access to your Fedora 44 server. By the end of these steps, you will have a fully functional GitLab instance accessible through your web browser, secured with proper firewall rules and SELinux policies.

Table of Contents

Prerequisites

Before starting the GitLab on Fedora 44 setup, ensure you have the following requirements met:

  • Operating System: Fresh Fedora 44 minimal server installation (released April 2026)
  • RAM: Minimum 4 GB (8 GB recommended for teams of 5+ developers)
  • CPU: At least 2 cores (4 cores recommended for production use)
  • Disk Space: 20 GB available storage (GitLab Omnibus package is around 1 GB)
  • User Account: Root access or a user with sudo privileges
  • Network: Active internet connection and either a public IP address or valid domain name pointing to your server
  • Ports: Ports 80 (HTTP), 443 (HTTPS), and 22 (SSH) must be accessible

The system should be a clean installation without other web servers (Apache, Nginx) or mail transfer agents running, as these can conflict with GitLab’s bundled services. If you already have conflicting software installed, you can either remove it during the process or configure GitLab to use different ports.

Step 1: Update Your System Packages

Why System Updates Matter First

Fedora 44 may have pending security patches, kernel updates, or OpenSSL library upgrades at the time of installation. Running GitLab on an outdated system can cause TLS handshake failures between internal services or create security vulnerabilities from known exploits. System updates ensure all underlying libraries are current before adding new software.

Execute the Update Command

sudo dnf update -y

This command uses Fedora’s default package manager (DNF) to check all configured repositories for available updates. The -y flag automatically confirms the installation prompt, which is appropriate for single-administrator setups. If you work in a shared environment where changes require review, remove the -y flag to inspect the update list first.

Expected Output

Last metadata expiration check: 0:05:23 ago on Mon Jun 08 17:30:00 2026.
Dependencies resolved.
================================================================================
 Package                   Architecture       Version                  Repository
================================================================================
Upgrade:
 glibc                     x86_64             2.40-11.fc44             updates
 openssh-clients           x86_64             9.9p1-4.fc44             updates
 systemd                   x86_64             256-1.fc44               updates
================================================================================
Complete!

After the update completes, check if a new kernel was installed:

uname -r

If the running kernel version does not match the latest installed kernel, reboot your server:

sudo reboot

A kernel update ensures GitLab’s Gitaly service (which handles Git operations) can load kernel modules without issues. This step is critical for system stability.

Step 2: Install Required System Dependencies

Understanding What Dependencies GitLab Needs

GitLab Omnibus includes most internal services, but several system-level packages must exist beforehand. These dependencies handle network communication, security contexts, and Git operations that GitLab itself does not bundle.

Install the Dependency Packages

sudo dnf install -y curl policycoreutils openssh-server perl

Why Each Package Is Necessary

curl downloads files over HTTPS and is required to fetch the GitLab repository installation script from packages.gitlab.com. Without curl, you cannot register the official GitLab RPM repository that DNF needs to find the GitLab package.

policycoreutils provides SELinux management utilities like semanage and restorecon. Fedora 44 runs SELinux in enforcing mode by default, which blocks processes from binding to ports unless explicitly allowed. GitLab’s bundled Nginx server needs SELinux port contexts configured correctly to serve web traffic on ports 80 and 443.

openssh-server enables SSH protocol access for Git operations. Developers clone repositories and push code using the git@server.com:path/to/repo.git SSH URL format. Without an active SSH daemon, this authentication method fails entirely.

perl is used by GitLab’s internal migration scripts and the Gitaly server during reconfiguration. Some older components in the Omnibus package still rely on Perl for file processing tasks.

Enable and Start the SSH Service

sudo systemctl enable sshd
sudo systemctl start sshd

The enable command creates a systemd symlink so SSH starts automatically after reboots. The start command activates the service immediately without waiting for a reboot. SSH must be running before developers can push code to GitLab.

Verify SSH Is Active

sudo systemctl status sshd

Expected output shows active (running):

● sshd.service - OpenSSH server daemon
     Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled)
     Active: active (running) since Mon 2026-06-08 17:35:12 WIB

Step 3: Install and Configure Postfix for Email Notifications

Why GitLab Needs a Mail Transfer Agent

GitLab sends transactional emails for user registration confirmations, password reset links, merge request notifications, CI/CD pipeline failures, and mention alerts. Without a working mail transfer agent (MTA), these notifications fail silently, and users lose visibility into important project events.

Install Postfix

sudo dnf install -y postfix

Postfix is the default MTA choice for GitLab because it is lightweight, well-maintained, and configured to work as a local relay out of the box. This means it can send emails without requiring an external SMTP server configuration for basic functionality.

Enable and Start Postfix

sudo systemctl enable postfix
sudo systemctl start postfix

Enabling Postfix ensures the mail service survives server reboots. If Postfix is not running when GitLab’s Sidekiq job processor attempts to queue an email, the job fails and retries repeatedly, consuming CPU resources and filling log files with error messages.

Verify Postfix Is Running

sudo systemctl status postfix

Look for active (running) in the output. If the service fails to start, check for port 25 conflicts with other mail software:

sudo ss -tlnp | grep :25

Optional: Configure External SMTP Instead

If your organization uses SendGrid, Mailgun, or AWS SES for email delivery, skip Postfix and configure SMTP settings directly in gitlab.rb later. This approach is better for production environments because external SMTP services offer better deliverability rates and tracking. However, Postfix is the fastest zero-configuration solution for new installations.

Step 4: Add the Official GitLab CE Repository

Why You Need GitLab’s Official Repository

GitLab Community Edition is not included in Fedora’s default repositories or EPEL. The official GitLab package repository must be added manually so DNF can locate, verify, and install signed GitLab RPM packages. Using unofficial sources risks installing outdated or compromised software.

Execute the Repository Setup Script

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash

This script performs three critical actions automatically:

  1. Adds a .repo file to /etc/yum.repos.d/ that points to GitLab’s package servers
  2. Imports GitLab’s GPG signing key so DNF can verify package signatures
  3. Verifies the key fingerprint to ensure the package source is authentic

Security Note on Piping Commands

Piping curl output directly to bash is a common pattern but carries risk if the source URL is compromised. For production environments with strict security requirements, download the script first, inspect it for unexpected commands, then execute it separately:

curl -O https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh
nano script.rpm.sh  # Review the script contents
sudo bash script.rpm.sh
rm script.rpm.sh

This extra step gives you full visibility into what commands will run on your system.

Verify the Repository Was Added

dnf repolist | grep gitlab

Expected output should show:

gitlab-ce    GitLab CE RPM repository for Fedora 44

If no output appears, the repository installation failed. Check your internet connection and try the setup script again.

Step 5: Install GitLab CE with External URL Configuration

Why Setting External_url During Installation Matters

The EXTERNAL_URL environment variable tells GitLab what address users will use to access the web interface. This value gets baked into /etc/gitlab/gitlab.rb during the first automatic configuration run. If you skip this step, GitLab defaults to localhost, making it unreachable from other machines.

Execute the Installation Command

sudo EXTERNAL_URL="http://your-server-ip-or-domain.com" dnf install -y gitlab-ce

Replace your-server-ip-or-domain.com with your actual server IP address or fully qualified domain name. If you are using a domain name, ensure DNS A records point to your server’s public IP before running this command.

What Happens During Installation

The GitLab CE omnibus package is approximately 1 GB and includes all internal services:

  • PostgreSQL database for storing all data
  • Redis for caching and job queues
  • Nginx as the embedded web server
  • Puma as the Ruby application server
  • Sidekiq for background job processing
  • Gitaly for Git repository operations

During installation, the package automatically runs gitlab-ctl reconfigure for the first time. This process can take 3 to 5 minutes on a fresh server while it initializes the PostgreSQL database, creates the GitLab schema, and starts all services.

Expected Installation Progress

GitLab: https://www.gitlab.com
GitLab RCE: https://about.gitlab.com
GitLab Runner: https://gitlab.com/gitlab-org/gitlab-runner
GitLab Shell: https://gitlab.com/gitlab-org/gitlab-shell

Installing GitLab...
Reconfiguring gitlab...
Running gitlab-ctl reconfigure...
[ok] reconfiguring gitlab
...
GitLab Reconfigured!
Installation complete.

The final line GitLab Reconfigured! indicates successful completion. If you see errors before this message, note the error text and address it before proceeding.

Step 6: Configure firewalld to Allow Web Traffic

Why Firewall Configuration Is Critical

Fedora 44 ships with firewalld active in default-deny mode for incoming connections. Without explicit allow rules, HTTP and HTTPS requests from browsers are silently dropped at the kernel packet filter level. GitLab runs perfectly internally but remains invisible to external users.

Add HTTP, HTTPS, and SSH Services to the Firewall

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

Breakdown of Each Command

The --permanent flag writes rules to the firewalld XML zone configuration in /etc/firewalld/, ensuring they persist after reboots. Without this flag, rules only apply to the current session and vanish when firewalld restarts.

The --add-service option adds predefined service definitions rather than raw port numbers. Fedora maintains service definitions for common protocols, making firewall rules more readable and maintainable.

The --reload command applies permanent rules to the running configuration without dropping existing connections. This is safer than restarting firewalld entirely, which would interrupt active SSH sessions.

Verify Firewall Rules Are Active

sudo firewall-cmd --list-all

Expected output includes http, https, and ssh in the services list:

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources: 
  services: ssh dhcpv6-client http https
  ports: 
  protocols: 
  forward: no

If SSH is missing from the services list, you risk locking yourself out of the server after reloading firewall rules. Always verify SSH is included before reloading.

Step 7: Configure SELinux for GitLab

Understanding SELinux’s Role in Fedora Security

Fedora 44 runs SELinux in enforcing mode by default. SELinux uses type enforcement to control which processes can access which files and ports. GitLab’s bundled Nginx may be blocked from binding to ports 80 and 443 without explicit SELinux type contexts.

Allow Nginx to Bind to HTTP and HTTPS Ports

sudo semanage port -a -t http_port_t -p tcp 80
sudo semanage port -a -t http_port_t -p tcp 443

The semanage port command adds ports 80 and 443 to the http_port_t SELinux type context. This is the context SELinux expects for legitimate web server processes. Without this rule, Nginx attempts to bind to these ports but SELinux denies the operation, causing GitLab web interface errors.

If the Port Already Exists, Use Modify Instead

sudo semanage port -m -t http_port_t -p tcp 80
sudo semanage port -m -t http_port_t -p tcp 443

The -m flag modifies an existing rule instead of creating a new one. If the gitlab-on-fedora-44 setup encounters an error stating the port already exists, use modify rather than add.

Restore Correct File Contexts on GitLab Directories

sudo restorecon -R -v /var/log/gitlab

The restorecon command resets SELinux file contexts to match the active policy. GitLab Omnibus creates directories during installation with default contexts that may not match what SELinux expects. The -R flag applies changes recursively to all subdirectories, and -v shows verbose output of changed files.

Do Not Disable SELinux

Some older tutorials suggest disabling SELinux entirely with setenforce 0. This is a security anti-pattern that removes mandatory access control protection. SELinux blocks many attack vectors that firewalls cannot catch, including privilege escalation attempts and process injection attacks. Keep SELinux enforcing and configure it correctly instead.

Step 8: Edit gitlab.rb for Production Configuration

Why gitlab.rb Is the Single Source of Truth

The /etc/gitlab/gitlab.rb file is GitLab Omnibus’s master configuration. Every time you run gitlab-ctl reconfigure, this file is read and all internal service configurations are regenerated from it. Direct edits to internal configuration files (like PostgreSQL’s postgresql.conf) are overwritten on the next reconfigure run.

Open the Configuration File

sudo nano /etc/gitlab/gitlab.rb

Key Settings to Configure

Set the correct external URL:

external_url 'https://your-domain.com'

The external_url must exactly match the URL users type into their browser. Mismatches cause OAuth callback failures, broken asset paths, and redirect loops.

Enable SMTP for email delivery (if using external mail provider):

gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.mailgun.org"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "postmaster@yourdomain.com"
gitlab_rails['smtp_password'] = "your-smtp-password"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true

This configuration replaces Postfix with an external SMTP service. Fill in your actual SMTP credentials from your email provider.

Disable public user signup for private instances:

gitlab_rails['signup_enabled'] = false

For internal team use, disabling signup prevents unauthorized users from creating accounts. Admins can still create user accounts manually or via LDAP integration.

Change Nginx listen port if behind a reverse proxy:

nginx['listen_port'] = 8080

Only needed if another web server handles ports 80/443 on the same machine.

Save and Exit

Press Ctrl+X, then Y, then Enter to save changes and exit nano.

Step 9: Apply Configuration with gitlab-ctl reconfigure

Understanding What Reconfigure Does

The gitlab-ctl reconfigure command is a Chef-based provisioning run that reads gitlab.rb, generates all downstream configuration files, and restarts only the services whose configurations changed. It is idempotent, meaning running it multiple times produces the same result.

Execute Reconfigure

sudo gitlab-ctl reconfigure

What Happens During Reconfigure

During the first run after installation, GitLab:

  1. Initializes the PostgreSQL database if not already done
  2. Creates the GitLab schema and seeds default data
  3. Generates the initial root password
  4. Starts all internal services (Puma, Sidekiq, PostgreSQL, Redis, Nginx, Gitaly)

The process typically takes 3 to 5 minutes. Watch for the final line:

Running handlers complete
GitLab reconfigured!

Troubleshooting Reconfigure Failures

If you see errors before GitLab reconfigured!, check the logs:

sudo gitlab-ctl tail reconfigure

Common issues include syntax errors in gitlab.rb (missing quotes, incorrect brackets) or port conflicts with other services.

Step 10: Retrieve Initial Root Password and Log In

Finding Your Temporary Root Password

sudo cat /etc/gitlab/initial_root_password

Why This File Is Time-Limited

GitLab generates a random strong password for the root account during the first reconfigure run and stores it in this file. The file is automatically deleted 24 hours after installation. If you do not change the root password before deletion, you must use gitlab-rake to reset it manually.

Example Output

Password: abc123XYZ789!@#def456

Copy this password to a secure location immediately.

Access the Web Interface

Open your browser and navigate to:

http://your-server-ip-or-domain.com

If you set up SSL (see Step 11), use https:// instead.

Log in with:

  • Username: root
  • Password: The password from initial_root_password

Change the Root Password Immediately

Navigate to User Settings > Password in the GitLab web interface and set a permanent password. After securing root, create a personal admin account with your named email address. Using the root account for daily development work is a security anti-pattern.

Step 11: Secure Your Instance with SSL Using Let’s Encrypt

Why HTTPS Is Mandatory for Production

GitLab sends session cookies, API tokens, and user credentials over the network. Running without HTTPS means these are transmitted in cleartext and trivially interceptable on any shared network. SSL encryption prevents eavesdropping and man-in-the-middle attacks.

Configure Let’s Encrypt in gitlab.rb

Open the configuration file:

sudo nano /etc/gitlab/gitlab.rb

Add or modify these lines:

external_url 'https://your-domain.com'
letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['admin@yourdomain.com']

Important Requirements for Let’s Encrypt

  • Port 80 must be publicly accessible (required for ACME HTTP-01 challenge)
  • external_url must use a real, DNS-resolvable domain name, not an IP address
  • DNS A record must point to your server’s public IP

Apply the Configuration

sudo gitlab-ctl reconfigure

GitLab automatically requests the certificate from Let’s Encrypt, installs it, and configures Nginx to use HTTPS. Certificate renewal happens automatically every 60 days without manual intervention.

Verify SSL Is Working

Open your browser and check for the padlock icon in the address bar. You can also test with:

curl -I https://your-domain.com

Look for HTTP/2 200 in the response.

Troubleshooting Common Errors

Error 1: “502 Bad Gateway – Waiting for GitLab to boot”

Cause: Puma workers are still starting up. This is normal during the first few minutes after installation.

Solution: Wait 60 seconds and refresh the page. If the error persists, check memory availability:

free -h

If available RAM is below 1 GB, GitLab may struggle to start all workers. Consider adding more RAM or restarting services:

sudo gitlab-ctl restart

Error 2: SELinux AVC Denial in Audit Logs

Cause: SELinux is blocking GitLab from accessing a required resource.

Solution: Check the audit log for specific denials:

sudo grep denied /var/log/audit/audit.log | tail -20

Generate a custom SELinux policy module to allow the operation:

sudo audit2allow -a -M gitlab_custom
sudo semodule -i gitlab_custom.pp

Error 3: Port 80 Already in Use

Cause: Another web server (Apache, Nginx) is already listening on port 80.

Solution: Find and stop the conflicting service:

sudo ss -tlnp | grep :80
sudo systemctl stop nginx
sudo systemctl disable nginx

Alternatively, configure GitLab to use a different port in gitlab.rb:

nginx['listen_port'] = 8080

Error 4: initial_root_password File Is Missing

Cause: The file was automatically deleted after 24 hours.

Solution: Reset the root password manually using GitLab’s Rake task:

sudo gitlab-rake "gitlab:password:reset[root]"

Follow the prompts to enter a new password. This is more time-consuming than using the initial file, so change your password within the first 24 hours.

Error 5: Email Notifications Not Sending

Cause: Postfix is not running or SMTP settings are misconfigured.

Solution: Verify Postfix status:

sudo systemctl status postfix

If using external SMTP, check gitlab.rb settings and test delivery:

sudo gitlab-rake "gitlab:email:test"

[su_box title=”VPS Manage Service Offer” style=”bubbles” box_color=”#000000″ radius=”10″]If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal![/su_box]

r00t is a Linux Systems Administrator and open-source advocate with over ten years of hands-on experience in server infrastructure, system hardening, and performance tuning. Having worked across distributions such as Debian, Arch, RHEL, and Ubuntu, he brings real-world depth to every article published on this blog. r00t writes to bridge the gap between complex sysadmin concepts and practical, everyday application — whether you are configuring your first server or optimizing a production environment. Based in New York, US, he is a firm believer that knowledge, like open-source software, is best when shared freely.

Related Posts