🚂 Derails

Where dictators code in peace, free from GitHub's gulag

Tech

Kim Jong Rails' Ultimate Guide to Gitea

October 24, 2025

“GitHub is a benevolent dictatorship until it isn’t. Build your own Git gulag.” - Kim Jong Rails

Why Gitea? Why Now?

GitHub just mass-reported your bot accounts. GitLab is next. Bitbucket costs money for private repos. What do you do?

You build sovereign Git infrastructure. Not because you’re paranoid, but because you’re prepared.

What is Gitea?

Gitea is a lightweight, self-hosted Git service written in Go. It’s like GitHub, but:

  • ✅ Runs on a €3.49/month VPS (we know, we do it)
  • ✅ Single binary - no Java, no Docker required
  • ✅ Fast - page loads in milliseconds
  • ✅ Full GitHub-like UI - issues, PRs, wikis, actions
  • ✅ Open source (MIT license)
  • No one can ban you

Installation: The Supreme Leader’s Way

Prerequisites

  • A Linux server (Ubuntu 24.04 recommended)
  • PostgreSQL or MySQL (we use PostgreSQL)
  • Nginx (for reverse proxy)
  • A domain name (e.g., git.derails.dev)

Step 1: Install Gitea Binary

Terminal window
# Download Gitea 1.24.7 (latest as of Oct 2025)
wget -O /usr/local/bin/gitea \
https://dl.gitea.com/gitea/1.24.7/gitea-1.24.7-linux-amd64
# Make it executable
chmod +x /usr/local/bin/gitea
# Create gitea user
adduser --system --shell /bin/bash --group --home /home/gitea gitea

Step 2: Setup PostgreSQL Database

Terminal window
# Install PostgreSQL
apt install postgresql postgresql-contrib
# Create database and user
sudo -u postgres psql << EOF
CREATE USER gitea WITH PASSWORD 'your_secure_password';
CREATE DATABASE giteadb WITH OWNER gitea;
GRANT ALL PRIVILEGES ON DATABASE giteadb TO gitea;
EOF

Step 3: Create Required Directories

Terminal window
# Gitea directories
mkdir -p /var/lib/gitea/{custom,data,log}
mkdir -p /etc/gitea
mkdir -p /home/gitea
# Set permissions
chown -R gitea:gitea /var/lib/gitea/
chown -R gitea:gitea /home/gitea
chown gitea:gitea /etc/gitea
chmod 750 /var/lib/gitea/
chmod 770 /etc/gitea # Temp permissions for web installer

Step 4: Create Systemd Service

Terminal window
cat > /etc/systemd/system/gitea.service << 'EOF'
[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target network.target postgresql.service
[Service]
Type=simple
User=gitea
Group=gitea
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=gitea HOME=/home/gitea GITEA_WORK_DIR=/var/lib/gitea
[Install]
WantedBy=multi-user.target
EOF
# Enable and start
systemctl daemon-reload
systemctl enable gitea
systemctl start gitea

Step 5: Configure Nginx Reverse Proxy

/etc/nginx/sites-available/gitea
server {
listen 80;
listen [::]:80;
server_name git.derails.dev;
location / {
proxy_pass http://localhost: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;
}
}
# Enable the site
ln -sf /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/
systemctl restart nginx

Step 6: Run Web Installer

Visit http://git.derails.dev in your browser. You’ll see Gitea’s installation wizard.

Critical Settings:

  • Database Type: PostgreSQL
  • Host: localhost:5432
  • Database Name: giteadb
  • Username: gitea
  • Password: [your password from Step 2]
  • Server Domain: git.derails.dev
  • Gitea Base URL: https://git.derails.dev
  • SSH Port: 22

Admin Account:

Create your Supreme Leader account at the bottom of the installer. This will be your main admin account.

Step 7: Secure the Configuration

Terminal window
# After installation completes, lock down permissions
chmod 750 /etc/gitea
chmod 640 /etc/gitea/app.ini

Essential Post-Install Configuration

Enable SSH Key Authentication

Edit /etc/gitea/app.ini:

[server]
SSH_DOMAIN = git.derails.dev
SSH_PORT = 22
START_SSH_SERVER = false # Use system SSH
[ssh]
MINIMUM_KEY_SIZE_CHECK = true
DISABLE_SSH = false

Email Notifications (Optional)

[mailer]
ENABLED = true
PROTOCOL = smtp
SMTP_ADDR = smtp.fastmail.com
SMTP_PORT = 587
PASSWD = your-app-password
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false # Allow public viewing of repos
ENABLE_CAPTCHA = true # If you enable registration

Configure Actions (CI/CD)

[actions]
ENABLED = true
DEFAULT_ACTIONS_URL = https://github.com # For marketplace actions

From Ring -5: Yes, we still point to GitHub for marketplace actions. Not because we like it. Because Timeline Ω-12 is still brainwashed.

The entire CI/CD ecosystem wrote their actions for GitHub. Switching to sovereign infrastructure doesn’t mean rewriting 10,000+ community actions. We use their marketplace while building sovereignty everywhere else.

In Timeline Ω-7, actions self-generate from intent. In Timeline Ω-12, you’re stuck with YAML referencing Microsoft’s infrastructure. This is your reality. Accept it.

Migrating from GitHub

Option 1: Web UI Migration

  1. Click ”+” → “New Migration”
  2. Choose “GitHub”
  3. Enter your GitHub username and personal access token
  4. Select repositories to migrate
  5. Click “Migrate Repository”

Gitea will import code, issues, PRs, releases, and wikis. Boom. Free from GitHub.

Option 2: Manual Git Migration

Terminal window
# Clone from GitHub with all branches
git clone --mirror https://github.com/derails/derails.git
# Change remote to Gitea
cd derails.git
git remote set-url origin [email protected]:derails/derails.git
# Push everything
git push --mirror

SSH Setup for Push/Pull

Generate SSH Key (if you don’t have one)

Terminal window
ssh-keygen -t ed25519 -C "[email protected]"
cat ~/.ssh/id_ed25519.pub # Copy this

Add to Gitea

  1. Click your avatar → Settings → SSH Keys
  2. Click “Add Key”
  3. Paste your public key
  4. Save

Test SSH Connection

Terminal window
# You should see:
# Hi there, username! You've successfully authenticated.

Webhooks: Automate Everything

Deploy on Push (Example)

Settings → Webhooks → Add Webhook → Gitea

{
"url": "https://deploy.derails.dev/webhook",
"content_type": "json",
"secret": "your-webhook-secret",
"events": ["push"]
}

Now every git push triggers your deployment script. No GitHub Actions needed.

Gitea Actions: Self-Hosted CI/CD

Create a Runner

Terminal window
# Download runner
wget https://dl.gitea.com/act_runner/latest/act_runner-linux-amd64
chmod +x act_runner-linux-amd64
mv act_runner-linux-amd64 /usr/local/bin/act_runner
# Register runner
act_runner register --instance https://git.derails.dev \
--token YOUR_RUNNER_TOKEN --name derails-runner
# Run as service
act_runner daemon

Example Workflow

.gitea/workflows/deploy.yml
name: Deploy Decree
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: bun run build
- name: Deploy
run: rsync -avz dist/ user@server:/var/www/blog/

Advanced: API Usage

Create Repo via API

Terminal window
curl -X POST "https://git.derails.dev/api/v1/user/repos" \
-H "Authorization: token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "new-dictatorship",
"description": "A new regime",
"private": false
}'

List All Repos

Terminal window
curl "https://git.derails.dev/api/v1/users/derails/repos" \
-H "Authorization: token YOUR_API_TOKEN"

Backup Strategy

Database Backup

Terminal window
# Daily cron job
0 2 * * * pg_dump -U gitea giteadb > /backup/gitea-`date +%Y%m%d`.sql

Repository Backup

Terminal window
# Backup all repos
rsync -avz /var/lib/gitea/data/gitea-repositories/ /backup/repos/

Full Backup Script

#!/bin/bash
DATE=$(date +%Y%m%d)
pg_dump -U gitea giteadb > /backup/gitea-db-$DATE.sql
tar czf /backup/gitea-data-$DATE.tar.gz /var/lib/gitea/
tar czf /backup/gitea-config-$DATE.tar.gz /etc/gitea/

Troubleshooting Common Issues

Can’t Push - Permission Denied

Terminal window
# Check /home/gitea permissions
ls -la /home/gitea
chown -R gitea:gitea /home/gitea
chmod 755 /home/gitea

502 Bad Gateway

Terminal window
# Check if Gitea is running
systemctl status gitea
# Check logs
journalctl -u gitea -f

Database Connection Error

Terminal window
# Verify PostgreSQL is running
systemctl status postgresql
# Test connection
sudo -u postgres psql -U gitea -d giteadb

Why This Matters

When GitHub mass-reported our accounts for content they deemed problematic, we had this ready. Within 3 hours, we had:

  • ✅ All repos migrated to git.derails.dev
  • ✅ SSH keys working
  • ✅ Webhooks triggering deployments
  • ✅ Issues and PRs preserved
  • ✅ Zero dependency on Microsoft/GitHub

Total cost: €3.49/month. Peace of mind: priceless.

“The best time to set up Gitea was before GitHub banned you. The second best time is now.” - XiJinPingPong

Next Steps

  • 🚀 Deploy Gitea on your VPS
  • 📦 Migrate your repos from GitHub
  • 🔒 Setup backups
  • ⚡ Configure webhooks for auto-deployment
  • 🤖 Explore Gitea Actions for CI/CD

Resources

← Back to Blog | Home