What Is Gitea
Gitea is a lightweight, self-hosted Git service — think of it as your own private GitHub. It runs on your VPS alongside OpenClaw and gives you:
- Git repositories for code, notes, configs, or any versioned files
- Issue tracking for organizing tasks, ideas, bugs, and projects
- A web interface for browsing repos, reading issues, and managing projects
- An API that your OpenClaw can use to read and create issues programmatically
- Complete ownership — your data never leaves your server
Gitea is tiny (uses ~100MB RAM) and fits comfortably alongside OpenClaw on your 8GB VPS.
Step 1: Install Gitea with Docker
SSH into your server:
ssh claw@YOUR_SERVER_IP
Create a directory for Gitea:
mkdir -p ~/gitea
cd ~/gitea
Create a docker-compose.yml:
nano docker-compose.yml
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
volumes:
- ./data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
Start Gitea:
docker compose up -d
Open the firewall for the web interface and Git-over-SSH:
sudo ufw allow 3000/tcp comment 'Gitea web'
sudo ufw allow 222/tcp comment 'Gitea SSH'
Step 2: Set Up HTTPS with Caddy
If you completed Lesson 15 (Install Caddy), you already have a reverse proxy with automatic HTTPS. Add Gitea to your Caddyfile:
sudo nano /etc/caddy/Caddyfile
Add this block:
git.yourdomain.com {
reverse_proxy localhost:3000
}
That's it — Caddy handles HTTPS automatically. Reload:
sudo systemctl reload caddy
Restrict Access
Gitea should not be publicly accessible by default. Only allow your home IP and the VPS itself:
git.yourdomain.com {
@blocked not client_ip YOUR_HOME_IP 127.0.0.1 ::1
abort @blocked
reverse_proxy localhost:3000
}
Replace YOUR_HOME_IP with your actual IP (find it at whatismyip.com). See Lesson 15 for details on IP allowlists, basic auth, and other access control options.
Now close the raw web port (keep 222 for Git SSH):
sudo ufw delete allow 3000/tcp
Gitea is now at https://git.yourdomain.com.
Step 3: Initial Configuration
Visit https://git.yourdomain.com (or http://YOUR_SERVER_IP:3000 if no domain). The first-run wizard appears:
- Database: Choose SQLite3 (simplest, fine for personal use)
- Site Title: Something like "My Gitea" or your name
- Repository Root Path: Leave default
- Server Domain:
git.yourdomain.com(or your server IP) - SSH Server Port:
222 - Gitea Base URL:
https://git.yourdomain.com/(orhttp://YOUR_SERVER_IP:3000/) - Click Install Gitea
Then register your admin account — the first user automatically becomes the admin.
Save this login in Bitwarden.
Disable Public Registration
Your Gitea is for you and your OpenClaw. If registration is open, anyone who finds the URL can create an account. Disable it:
nano ~/gitea/data/gitea/conf/app.ini
Find or add the [service] section and set:
[service]
DISABLE_REGISTRATION = true
Restart Gitea for the change to take effect:
cd ~/gitea
docker compose restart
Step 4: Generate an API Token
You'll need this for OpenClaw to interact with Gitea:
- Click your avatar → Settings → Applications
- Under Manage Access Tokens, enter a name (e.g., "openclaw")
- Select scopes: repository: Read and Write, issue: Read and Write
- Click Generate Token
- Copy the token immediately — it's only shown once
- Save it in Bitwarden
Step 5: Back Up Gitea
Gitea's data lives in ~/gitea/data/. Back it up the same way as OpenClaw:
Manual backup
cd ~/gitea
docker compose stop
tar czf gitea-backup-$(date +%Y%m%d).tar.gz data/
docker compose up -d
Gitea's built-in backup command
docker exec -it gitea gitea dump -c /data/gitea/conf/app.ini
This creates a zip file at /tmp/gitea-dump-TIMESTAMP.zip inside the container. Copy it out:
docker cp gitea:/tmp/gitea-dump-*.zip ~/gitea/
Copy backups to your local machine periodically:
# On your LOCAL machine
scp claw@YOUR_SERVER_IP:~/gitea/gitea-backup-*.tar.gz ~/gitea-backups/
Automated backup via cron
crontab -e
Add:
0 3 * * 0 cd /home/claw/gitea && tar czf gitea-backup-$(date +\%Y\%m\%d).tar.gz data/ && find . -name 'gitea-backup-*' -mtime +30 -delete
This backs up every Sunday at 3 AM and deletes backups older than 30 days.
Step 6: Update Gitea
cd ~/gitea
docker compose pull
docker compose down
docker compose up -d
Your data is in a mounted volume, so it survives container replacement.
When You're Done
- Gitea running in Docker
- HTTPS configured via Caddy (if you have a domain)
- Access restricted via IP allowlist or basic auth
- Public registration disabled
- Admin account created and saved in Bitwarden
- API token generated and saved in Bitwarden
- At least one manual backup created
- Automated weekly backup cron job set up
- Know how to update Gitea