How to Set Up a Git Server with Gitea on RHEL 7
Gitea is a lightweight, self-hosted Git service written in Go. It provides a GitHub-style web interface for repository management, issue tracking, pull requests, webhooks, and user management — all from a single binary that consumes a fraction of the resources required by GitLab or Bitbucket. On Red Hat Enterprise Linux 7, Gitea is an excellent choice for teams that need a private Git server without the operational overhead of a full DevOps platform. This guide covers creating a dedicated system user, downloading and installing the Gitea binary, configuring the app.ini file, creating a systemd service, setting up an Nginx reverse proxy, and migrating existing repositories from GitHub.
Prerequisites
- RHEL 7 server with at least 1 CPU core and 512 MB RAM (1 GB recommended)
- Root or
sudoaccess - Nginx installed and running (or ready to install)
- A supported database: SQLite3 (default, zero-config), MySQL/MariaDB, or PostgreSQL
- Port 3000 free on the host, or a different port of your choice
- A domain name or IP address for the Gitea web interface
Step 1: Create the git System User and Directory Structure
Gitea should run under a dedicated, non-privileged system account. Create the git user with a home directory where repositories will be stored, and set up the required directories:
sudo useradd
--system
--shell /bin/bash
--comment "Gitea git user"
--create-home
--home-dir /home/git
git
Create the directories Gitea needs for its data, configuration, log files, and custom templates:
sudo mkdir -p /var/lib/gitea/{custom,data,log}
sudo mkdir -p /etc/gitea
sudo chown -R git:git /var/lib/gitea /etc/gitea
sudo chmod 750 /var/lib/gitea
sudo chmod 770 /etc/gitea
The /etc/gitea directory needs write permission during initial setup so the web installer can write app.ini. After setup is complete, you will tighten these permissions.
Step 2: Download the Gitea Binary
Gitea is distributed as a pre-compiled binary for Linux on the GitHub releases page. Download the latest stable release for the linux-amd64 architecture. Check https://dl.gitea.io/gitea/ for the current stable version and replace 1.21.11 with the latest:
GITEA_VERSION="1.21.11"
sudo wget -O /usr/local/bin/gitea
"https://dl.gitea.io/gitea/${GITEA_VERSION}/gitea-${GITEA_VERSION}-linux-amd64"
Download and verify the SHA256 checksum:
sudo wget -O /tmp/gitea.sha256
"https://dl.gitea.io/gitea/${GITEA_VERSION}/gitea-${GITEA_VERSION}-linux-amd64.sha256"
# Verify checksum (cd to /usr/local/bin first)
cd /usr/local/bin
sha256sum -c /tmp/gitea.sha256
Successful output: gitea: OK
Make the binary executable:
sudo chmod +x /usr/local/bin/gitea
Confirm it runs:
gitea --version
Step 3: Configure the Database (SQLite for Small Deployments)
For installations with fewer than 20 concurrent users, SQLite3 is the simplest choice — it requires no separate database server. SQLite is built into the Gitea binary. Ensure the sqlite shared library is present:
sudo yum install -y sqlite
For MySQL/MariaDB (recommended for larger teams), install MariaDB and create the database:
sudo yum install -y mariadb-server mariadb
sudo systemctl enable mariadb
sudo systemctl start mariadb
sudo mysql_secure_installation
sudo mysql -u root -p <<'EOF'
CREATE DATABASE gitea CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'gitea'@'localhost' IDENTIFIED BY 'strong-password-here';
GRANT ALL PRIVILEGES ON gitea.* TO 'gitea'@'localhost';
FLUSH PRIVILEGES;
EOF
Step 4: Create the Gitea systemd Service
Create a systemd unit file so Gitea starts automatically on boot and can be managed with systemctl:
sudo tee /etc/systemd/system/gitea.service <<'EOF'
[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
After=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
# Limit number of open files
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
If you are not using MariaDB, remove the After=mariadb.service line. Reload systemd and enable the service (do not start it yet — the web installer must run first):
sudo systemctl daemon-reload
sudo systemctl enable gitea
Step 5: Configure app.ini
Gitea’s configuration file is /etc/gitea/app.ini. You can either let the web installer generate it or write it manually for automation. Here is a production-ready template for a SQLite installation:
sudo tee /etc/gitea/app.ini <<'EOF'
APP_NAME = My Gitea Instance
RUN_USER = git
RUN_MODE = prod
[database]
DB_TYPE = sqlite3
PATH = /var/lib/gitea/data/gitea.db
[repository]
ROOT = /var/lib/gitea/data/gitea-repositories
[server]
DOMAIN = git.example.com
HTTP_PORT = 3000
ROOT_URL = https://git.example.com/
DISABLE_SSH = false
SSH_PORT = 22
SSH_LISTEN_PORT = 2222
LFS_START_SERVER = true
LFS_JWT_SECRET = generate-a-random-64-char-string-here
[mailer]
ENABLED = false
[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
DISABLE_REGISTRATION = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
ENABLE_CAPTCHA = false
REQUIRE_SIGNIN_VIEW = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = [email protected]
[picture]
AVATAR_UPLOAD_PATH = /var/lib/gitea/data/avatars
[attachment]
PATH = /var/lib/gitea/data/attachments
[log]
MODE = file
LEVEL = Info
ROOT_PATH = /var/lib/gitea/log
[security]
INSTALL_LOCK = true
SECRET_KEY = generate-a-random-64-char-string-here
INTERNAL_TOKEN = generate-a-different-random-token-here
EOF
Generate random secrets with:
openssl rand -hex 32
Set ownership and restrict permissions on the config file once written:
sudo chown root:git /etc/gitea/app.ini
sudo chmod 640 /etc/gitea/app.ini
Step 6: Open the Firewall and Start Gitea
Allow traffic on port 3000 (Gitea web) and port 2222 (Git over SSH, if using a non-standard port):
sudo firewall-cmd --permanent --add-port=3000/tcp
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
Start the Gitea service:
sudo systemctl start gitea
sudo systemctl status gitea
Check the log to confirm a clean start:
sudo journalctl -u gitea -f
You should see lines like Listen: http://0.0.0.0:3000. Gitea is now reachable at http://<server-ip>:3000.
Step 7: Configure Nginx as a Reverse Proxy
Install Nginx from EPEL and configure a virtual host for Gitea:
sudo yum install -y epel-release
sudo yum install -y nginx
sudo tee /etc/nginx/conf.d/gitea.conf <<'EOF'
server {
listen 80;
server_name git.example.com;
# Uncomment to redirect HTTP to HTTPS:
# return 301 https://$host$request_uri;
access_log /var/log/nginx/gitea.access.log;
error_log /var/log/nginx/gitea.error.log;
client_max_body_size 512m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
}
EOF
Test and enable Nginx:
sudo nginx -t
sudo systemctl enable nginx
sudo systemctl start nginx
Allow HTTP through the firewall:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Step 8: Complete the Initial Admin Setup
If INSTALL_LOCK = false in app.ini (the default when no app.ini exists), navigate to http://git.example.com in a browser. The first-run installer presents a form to configure the database, site title, and admin credentials. Fill in the fields and click Install Gitea.
If you pre-wrote app.ini with INSTALL_LOCK = true, create the admin user directly from the command line:
sudo -u git gitea admin user create
--username admin
--password 'SecurePassword123!'
--email [email protected]
--admin
--config /etc/gitea/app.ini
Log in to the web interface and verify the admin account works.
Step 9: Upload SSH Keys and Create a Repository
Navigate to your Gitea user profile, click Settings > SSH / GPG Keys > Add Key, and paste your public key:
cat ~/.ssh/id_ed25519.pub
Create a new repository in the web interface under + > New Repository, or clone the empty repository immediately:
git clone [email protected]:admin/my-project.git
cd my-project
echo "# My Project" > README.md
git add README.md
git commit -m "Initial commit"
git push origin main
If using the non-standard SSH port 2222, configure your SSH client in ~/.ssh/config:
Host git.example.com
Hostname git.example.com
User git
Port 2222
IdentityFile ~/.ssh/id_ed25519
Step 10: Migrate Repositories from GitHub
Gitea has a built-in migration feature that imports repositories, issues, pull requests, milestones, and labels from GitHub, GitLab, Bitbucket, and other Gitea instances. To migrate from GitHub:
- In Gitea, click + > New Migration > GitHub
- Enter your GitHub personal access token (needs
reposcope) in the API Token field - Enter the repository owner and name
- Select which items to migrate: Issues, Labels, Milestones, Pull Requests, Releases, Wiki
- Click Migrate Repository
For bulk migration using the Gitea CLI on the server:
sudo -u git gitea admin repo-sync-push-mirror
--config /etc/gitea/app.ini
Or use the Gitea API to automate migration of multiple repositories:
curl -X POST
-H "Content-Type: application/json"
-H "Authorization: token YOUR_GITEA_TOKEN"
-d '{
"clone_addr": "https://github.com/myorg/myrepo",
"auth_token": "YOUR_GITHUB_TOKEN",
"uid": 1,
"repo_name": "myrepo",
"mirror": false,
"private": true,
"issues": true,
"pull_requests": true,
"releases": true,
"labels": true,
"milestones": true
}'
https://git.example.com/api/v1/repos/migrate
Step 11: Tighten Security and Configure Backups
After initial setup is complete, lock down the installation directory permissions:
sudo chmod 750 /etc/gitea
sudo chmod 640 /etc/gitea/app.ini
Set up a nightly backup with a simple cron job that archives the data directory and database:
sudo tee /etc/cron.d/gitea-backup <<'EOF'
0 2 * * * git /usr/local/bin/gitea dump
--config /etc/gitea/app.ini
--file /var/backups/gitea/gitea-dump-$(date +%Y%m%d).zip
--skip-log 2>&1 | logger -t gitea-backup
EOF
sudo mkdir -p /var/backups/gitea
sudo chown git:git /var/backups/gitea
Conclusion
Gitea is now running on your RHEL 7 server, secured behind Nginx, managed by systemd, and ready to host Git repositories for your team. You have created a dedicated system user, configured the application through app.ini, set up SSH key authentication, and established a path for migrating existing GitHub repositories. Gitea’s minimal resource footprint makes it an excellent fit for resource-constrained environments or air-gapped networks where a full-featured platform would be prohibitive. From here, consider integrating Gitea with your CI/CD system — Gitea supports webhooks and has native integrations with Drone CI, Woodpecker CI, and Jenkins.