Self-host a Git Server with Gitea
Gitea is a Git hosting platform that fits on a Raspberry Pi and behaves a lot like GitHub. Issues, pull requests, releases, container registry, CI runners, OAuth — all in a single Go binary. Twenty minutes to install, almost zero ongoing maintenance.
Install
# Create the user
adduser --system --shell /bin/bash --gecos 'Git' \
--group --disabled-password --home /home/git git
# Fetch the binary
wget -O /usr/local/bin/gitea https://dl.gitea.com/gitea/1.22/gitea-1.22-linux-amd64
chmod +x /usr/local/bin/gitea
# Layout
mkdir -p /var/lib/gitea/{custom,data,log}
chown -R git:git /var/lib/gitea
mkdir /etc/gitea
chown root:git /etc/gitea
chmod 770 /etc/gitea
Systemd unit
# /etc/systemd/system/gitea.service
[Unit]
Description=Gitea
After=network.target postgresql.service
Wants=postgresql.service
[Service]
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
Visit http://server:3000 and walk through the installer. Database type PostgreSQL, host as your DB, hostname/email as appropriate, lock down "Disable self-registration" unless you actually want public signup.
Behind nginx
server {
listen 443 ssl http2;
server_name git.example.com;
client_max_body_size 1g; # for large pushes
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 https;
proxy_read_timeout 600s;
}
}
SSH access
Gitea uses the host's SSH daemon by default — pushes go to git@git.example.com and OpenSSH dispatches to a wrapper. Make sure AllowUsers in sshd_config includes git.
Alternative: built-in SSH server on a different port (app.ini → [server] START_SSH_SERVER = true, SSH_PORT = 2222). Useful if you can't share port 22.
Actions runner
Gitea has GitHub Actions-compatible workflows. The runner is a separate binary:
wget -O /usr/local/bin/act_runner https://dl.gitea.com/act_runner/0.2.10/act_runner-0.2.10-linux-amd64
chmod +x /usr/local/bin/act_runner
# Register
act_runner register --instance https://git.example.com --token YOUR_TOKEN
# Run as a service (write a systemd unit pointing at act_runner daemon)
Migrating from GitHub
Gitea has a built-in importer. Settings → New Migration → GitHub. Provide a personal access token and Gitea pulls the repo, issues, PRs, labels, milestones, and wiki. Mirrors stay synchronized if you keep them as mirrors.
Backup
sudo -u git gitea dump -c /etc/gitea/app.ini --skip-log --type zip
# produces gitea-dump-.zip with DB, repos, attachments