Why Gitea and Fedora are the Perfect Match
Using GitHub or GitLab is great, but there’s a unique satisfaction in owning your own source code. If you’re running a budget VPS or an old machine at home, GitLab can be a nightmare as it consumes at least 4GB of RAM just to start. Gitea is different. It’s incredibly lightweight, using only about 100MB – 150MB of RAM for personal use while still offering full features like Pull Requests, Wikis, and Kanban boards.
I chose Fedora Server because this distro is always at the forefront of technology. It’s more stable than bleeding-edge versions but has significantly newer packages than Debian or old CentOS. Combined with built-in SELinux, your server will be strictly protected.
Quick Start: 5-Minute Installation
For those familiar with Fedora who want immediate results, here is the summary roadmap:
- Set up the MariaDB database.
- Create a
gituser (do not use root to run the app). - Download the latest Gitea binary.
- Open port 3000 on Firewalld.
- Configure via the Web UI.
# Install MariaDB and start it immediately
sudo dnf install mariadb-server -y
sudo systemctl enable --now mariadb
# Open port 3000 to access the installation web UI
sudo firewall-cmd --permanent --add-port=3000/tcp
sudo firewall-cmd --reload
Once this step is done, you have the foundation. Now let’s dive into the details to avoid common permission errors.
Step 1: Database Setup
Gitea supports multiple DB types, but MariaDB is the most reliable choice on Fedora. After installation, don’t forget to run the security script:
sudo mysql_secure_installation
Next, create a dedicated database for Gitea. Note the use of utf8mb4 to properly support special characters and emojis in commit messages:
CREATE DATABASE giteadb CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
CREATE USER 'gitea'@'localhost' IDENTIFIED BY 'YourPasswordHere';
GRANT ALL PRIVILEGES ON giteadb.* TO 'gitea'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Step 2: Create System User and Permissions
Golden rule: Never run web services with root privileges. A small vulnerability could cost you control of the entire server. Create a dedicated system user:
sudo useradd -m -r -s /bin/bash git
# Create standard directory structure
sudo mkdir -p /var/lib/gitea/{custom,data,log}
sudo chown -R git:git /var/lib/gitea/
sudo chmod -R 750 /var/lib/gitea/
sudo mkdir /etc/gitea
sudo chown root:git /etc/gitea
sudo chmod 770 /etc/gitea
Here, I’m giving the git group write access to /etc/gitea. After the installation is complete, we will revoke this permission to increase security.
Step 3: Download and Install the Gitea Binary
Instead of installing from outdated repos, I prefer using the binary directly from the official site to get the latest version (e.g., 1.21.x).
VERSION=1.21.4
wget -O /tmp/gitea https://dl.gitea.com/gitea/${VERSION}/gitea-${VERSION}-linux-amd64
sudo mv /tmp/gitea /usr/local/bin/gitea
sudo chmod +x /usr/local/bin/gitea
Step 4: Mastering SELinux (Don’t Disable It!)
Many online tutorials suggest running setenforce 0. That is terrible advice. SELinux is the armor protecting Fedora from privilege escalation attacks. Instead of turning it off, teach it to trust Gitea.
Install the management tools and label Gitea’s files correctly:
sudo dnf install policycoreutils-python-utils -y
# Assign correct contexts to binary and data
sudo semanage fcontext -a -t bin_t "/usr/local/bin/gitea"
sudo semanage fcontext -a -t var_lib_t "/var/lib/gitea(/.*)?"
sudo semanage fcontext -a -t etc_t "/etc/gitea(/.*)?"
sudo restorecon -Rv /usr/local/bin/gitea /var/lib/gitea /etc/gitea
Step 5: Configure Systemd Service
To make Gitea run automatically on every reboot, create a simple service file at /etc/systemd/system/gitea.service:
[Unit]
Description=Gitea
After=network.target mariadb.service
[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
[Install]
WantedBy=multi-user.target
Activate it using these two familiar commands:
sudo systemctl daemon-reload
sudo systemctl enable --now gitea
Step 6: Complete via Web UI
Access http://YOUR_IP:3000. Fill in the database information created in Step 1. A small note: In the Server Domain field, enter the correct IP or Domain you plan to use so that SSH/HTTP clone links work correctly.
Important: Create an Admin account immediately on this page. If you skip this, the first person to register an account on the site will automatically gain full Admin privileges.
Advanced: Running via Nginx and SSL
For a more professional setup, you should use Nginx as a Reverse Proxy and install an SSL certificate from Let’s Encrypt. This allows Gitea to run over the standard port 443 instead of port 3000.
server {
listen 80;
server_name git.your_domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Pro Tips & Best Practices
- Backup: Gitea has a
gitea dumpcommand. Create a cronjob to run this every night at 2 AM. A single zip file will contain everything: code, DB, and configuration. - Update: When a new version is released, simply download the new binary, overwrite the old file at
/usr/local/bin/gitea, and restart the service. The whole process takes less than 30 seconds. - SSH Errors: If code pushes are rejected even after adding an SSH key, it’s 99% likely that SELinux hasn’t allowed writing to the
.sshdirectory. Userestorecon -Rv /home/git/.sshto fix it.
Self-hosting Gitea not only saves you money but is also a great way to deepen your understanding of Linux systems. If any step gives you trouble during installation, don’t hesitate to post the error in the comments below!

