git commit before)Before we begin, let's be crystal clear about what software you must have installed β and what you can safely ignore.
| Software | Linux Path | Windows Path |
|---|---|---|
| Docker Engine | Required. Install via sudo apt install docker.io |
Not required (Gitea runs as a native binary) |
| Docker Compose | Required. Install via sudo apt install docker-compose-v2 |
Not required |
| Git for Windows | Not needed (Git is built into Docker images) | Required. Download from gitforwindows.org |
| Administrator / sudo access | Required (to install Docker and run containers) | Required (to register a Windows Service) |
Each developer who will use the Gitea server needs these on their local machine:
Git Bash) that works on Windows.ssh to verify. No installation needed.This list surprises most people. You can skip installing all of these:
Gitea is famously lightweight. Here's what you actually need:
A $5/month VPS (1 GB RAM, 1 core, 25 GB SSD) can comfortably serve dozens of developers and run CI pipelines.
If your team is 4 people, GitHub Free sounds like a good deal β unlimited public and private repositories, right? But here's what it doesn't tell you:
Gitea is a lightweight, open-source Git service written in Go. It feels exactly like GitHub β Issues, Pull Requests, Code Reviews, Actions, Wikis β but runs on hardware you control. A Raspberry Pi 4 can serve a 4-person team without breaking a sweat.
Which of the following is NOT a reason to self-host Gitea instead of using GitHub Free?
To appreciate what Gitea does, it helps to understand how we got here. Version control went through three eras:
In the early days, developers copied files into timestamped directories (project-backup-2024-01-01, project-backup-2024-01-02...). Tools like RCS (Revision Control System) used local patch files to track changes β but only on a single machine. If that hard drive died, your entire project history vanished.
Systems like CVS, Subversion (SVN), and Perforce introduced a central server that held the canonical repository. Developers "checked out" files, edited them, and "checked in" changes. The server was the single source of truth.
This was a leap forward, but it had a fatal flaw: if the server went offline, nobody could commit. If the server's hard drive crashed without a backup, the entire project history was lost.
Linus Torvalds built Git for the Linux kernel development workflow. The breakthrough: every developer has a complete copy of the entire repository β full history, all branches, all tags β on their local machine.
Local Machine ββpushβββΆ Central Server (Gitea)
βββpull/fetchββ
(full history) (full history + collaboration hub)
If the central server dies, any developer's machine can restore it. This is the world Gitea lives in β the Git protocol is already distributed; Gitea just adds the collaboration layer (Issues, PRs, CI) on top.
If you're going to self-host, which platform do you choose? Here's an honest comparison for a 4-person team.
Think of GitHub as a luxury hotel β everything is taken care of, but you pay per night and follow their rules. GitLab CE is a full-service office building with heating, security, and a cafeteria β great for 50+ people but overkill (and power-hungry) for 4. Gitea and Forgejo are a cozy flat you own β small, cheap, and fully under your control.
| Feature / Platform | Gitea | GitLab CE | Forgejo | GitHub |
|---|---|---|---|---|
| RAM Required | ~40 MB (idle) | ~4 GB (minimum) | ~40 MB (idle) | N/A (SaaS) |
| Install Method | 1 binary or Docker | Full stack (Ruby, Postgres, Redis) | 1 binary or Docker | Sign up online |
| Built-in CI/CD | Gitea Actions (GitHub Actions compatible YAML) | GitLab CI (mature, powerful) | Forgejo Actions (forked from Gitea) | GitHub Actions (2,000 min/mo free) |
| UI Familiarity | 1:1 GitHub clone | Different layout, more menus | 1:1 GitHub clone | Industry standard |
| Governance | Community (open) | Commercial (GitLab Inc.) | Community (non-profit, forked from Gitea) | Commercial (Microsoft) |
| Docker Setup | 2 minutes (1 yml file) | 20+ minutes (multiple containers) | 2 minutes (1 yml file) | N/A |
| Cost for 4 users | $5/month (VPS) + $0 licensing | $10-20/month (larger VPS) + $0 licensing | $5/month (VPS) + $0 licensing | $16/month (Team plan) + $0 (Free limitations) |
Verdict for this tutorial: Gitea. It's the most mature, has the largest community, natively supports GitHub Actions-compatible CI/CD, and the UI will be instantly familiar to anyone who's used GitHub.
For 4 people, you do not need Kubernetes, load balancers, or high-availability clusters. A single machine running Docker Compose is the right architecture.
Internet βββΆ [Your VPS / Server]
β
βββ Port 3000 (Web UI)
βββ Port 2222 (SSH for Git operations)
β
βββ Docker Compose
β
βββ gitea/gitea:1.26.4
βββ (optional) postgres:16
For 4 people, SQLite is perfect. Gitea's SQLite support stores the entire database in a single file (/data/gitea/gitea.db). Zero maintenance. Zero configuration. Zero extra containers.
Postgres only becomes necessary when you have:
For a 4-person team, SQLite handles everything effortlessly. You can migrate to Postgres later if you grow.
./gitea-data/ βββ data/ # Database (SQLite), avatars, attachments βββ git/ # All your Git repositories (bare repos) βββ ssh/ # SSH keys for your team
Backing up Gitea means backing up this single folder. That's it.
For a 4-person team, which database should you use with Gitea and why?
This is the recommended path for production use. We'll use Docker Compose for automatic restarts, easy updates, and clean separation.
Ensure your Linux server has Docker and Docker Compose installed:
sudo apt update && sudo apt install docker.io docker-compose-v2 -y
mkdir ~/gitea && cd ~/gitea
version: '3.8'
services:
server:
image: gitea/gitea:1.26.4
container_name: gitea-server
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
volumes:
- ./gitea-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000" # Web interface
- "2222:22" # SSH (use 2222 to avoid conflict with host SSH)
docker compose up -d
Gitea is now running. Open your browser to http://your-server-ip:3000.
docker compose logs -f shows real-time logs. docker compose ps shows the container status. If you see "Web server is ready", you're good.
If you don't have a Linux server, or you want to run Gitea on a Windows machine as a lightweight team server, here's the manual path. No Docker required.
Go to dl.gitea.com/gitea/ and download the latest Windows executable for your architecture (e.g., gitea-1.26.4-windows-4.0-amd64.exe). Rename it to gitea.exe.
C:\gitea\ βββ gitea.exe βββ custom\ βββ data\
Open an Administrator Command Prompt or PowerShell:
cd C:\gitea .\gitea.exe web
Gitea starts in the foreground. Visit http://localhost:3000 β you should see the setup wizard. Press Ctrl+C to stop it for now.
Run this command as Administrator to make Gitea start automatically on boot:
sc.exe create "Gitea" binPath="C:\gitea\gitea.exe web" start=auto sc.exe start Gitea
Gitea now runs as a background Windows service, restarting automatically if the machine reboots.
When you load Gitea for the first time (at http://your-server:3000 or http://localhost:3000), you'll see the setup wizard. Configure these settings for your 4-person team:
| Setting | Recommended Value | Why |
|---|---|---|
| Database Type | SQLite3 | Zero maintenance. A single file. Perfect for small teams. |
| Site Title | Our Team Forge (or your team name) |
Shows in the browser tab and email notifications. |
| Server Domain | Your server's IP or domain | Used in clone URLs. Set it correctly now β changing it later breaks existing clones. |
| SSH Server Port | 2222 (Linux/Docker) or 22 (Windows standalone) |
On Linux, port 22 is usually occupied by the host SSH server. |
| Gitea HTTP Port | 3000 |
Default. Don't change unless you have a conflict. |
| Gitea Base URL | http://your-server-ip:3000/ |
Must match the domain and port users will access. |
Don't clutter your Gitea dashboard with individual repos under personal namespaces. Instead, create an Organization for your team:
your-team-name (e.g., core-team)Now all repositories live under your-server:3000/core-team/project-x instead of your-server:3000/personal/project-x. This gives everyone consistent access.
For a small team, the biggest risk is someone force-pushing to main or merging broken code. Branch protection prevents this.
Navigate to: Settings β Branches β Branch Protection Rules β Add Rule
Configure for the main branch:
Why should a 4-person team set branch protection on the main branch with "Require Pull Request before merging" and "Require 1 approval"?
Gitea Actions uses GitHub Actions-compatible YAML syntax β so if you've written a .github/workflows file before, you already know how to write Gitea Actions. Gitea runs its own act_runner (a lightweight runner binary) to execute pipelines.
First, add a runner from the Gitea web UI: Settings β Actions β Runners β Create New Runner. Gitea gives you a registration token. Then, on your server:
docker run -d \ --name gitea-runner \ -e GITEA_INSTANCE_URL=http://server:3000 \ -e GITEA_RUNNER_REGISTRATION_TOKEN=YOUR_TOKEN_FROM_UI \ -v /var/run/docker.sock:/var/run/docker.sock \ gitea/act_runner:latest
Create .gitea/workflows/ci.yml in your repository:
name: Test and Deploy
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm test
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to production..."
Gitea Actions automatically picks up this file and runs the pipeline on every push. The syntax is identical to GitHub Actions β no learning curve.
Your 4-person team is likely on Windows laptops. Here's how they connect to the Gitea server.
Each developer downloads and installs Git from gitforwindows.org. During installation:
git config --global user.name "Your Name" git config --global user.email "[email protected]"
From the repository page in Gitea, copy the HTTPS clone URL and run:
git clone http://your-server-ip:3000/core-team/project-x.git
Windows will prompt for credentials. Type the Gitea username and password. Git for Windows caches credentials securely so you don't have to type them every time.
Here's the 5-command rhythm every developer on your team needs to know. Print this, tape it to your monitor.
| # | Command | What It Does |
|---|---|---|
| 1 | git status |
Check what files changed. Run this constantly to stay oriented. |
| 2 | git add <file> |
Stage specific changes. Use git add . only when you're sure everything should go in. |
| 3 | git commit -m "message" |
Take a snapshot locally. Write clear messages: "Fix login redirect bug" not "fix". |
| 4 | git push origin main |
Send your commits to Gitea. Now your teammates can see your code. |
| 5 | git pull origin main |
Get your teammates' latest changes before you start working. Do this every morning. |
# Morning: get everyone's latest changes git pull origin main # Make changes in your editor... # Check what you changed git status # Stage the changes git add . # Commit with a clear message git commit -m "Add user authentication middleware" # Push to Gitea so your team can see it git push origin main
What is the correct order of the 5-command daily Git cycle?
One of the most common questions from teams switching to a self-hosted Git server is: "Can I still use AI coding assistants?" The short answer is yes β and in some ways, Gitea gives you more control over AI integrations than GitHub does.
Gitea does not have a built-in AI assistant like GitHub Copilot or GitLab Duo. Instead, it exposes a full REST API and supports the Model Context Protocol (MCP), which lets any MCP-compatible AI tool connect to your Gitea instance. This is a fundamentally more open approach β you choose the AI tool, the model, and the policies.
The Gitea MCP Server (gitea-mcp) is an official tool that implements the Model Context Protocol β an open standard that lets AI applications (Claude, Cursor, ChatGPT, Copilot, VS Code) interact with Gitea using natural language. Think of it as a USB-C port for AI: one standard connector that works with any compatible client.
| Client | Status | What You Can Do |
|---|---|---|
| Cursor | β Full support | Create repos, branches, issues, PRs, review code, search β all from the editor |
| Claude Desktop / Claude Code | β Full support | Natural language repo management, issue triage, PR creation, code review |
| ChatGPT (GPT-5.x / Codex) | β Via MCP | Query repos, create and manage issues, read file contents |
| VS Code (GitHub Copilot Chat) | β Via MCP | Copilot can reference Gitea repos when connected via MCP |
| GitHub Copilot CLI | β οΈ Partial | Works with local git operations; remote Gitea operations require MCP bridge |
| Claude Cowork / OpenCode | β Via MCP | Full agentic coding workflows connected to your Gitea repos |
Connecting your AI assistant to Gitea takes exactly four steps:
Settings β Applications β Manage Access Tokens β Generate Token
Choose the permissions your AI agent needs (read/write on repos, issues, PRs). Copy the token β it's shown only once.
pip install gitea-mcp
Or use uvx gitea-mcp without installing anything (recommended for isolation).
For Cursor, add to .cursor/mcp.json:
{
"mcpServers": {
"gitea": {
"command": "uvx",
"args": ["gitea-mcp"],
"env": {
"GITEA_URL": "https://your-gitea-server:3000",
"GITEA_TOKEN": "your-personal-access-token"
}
}
}
}
For Claude Desktop, use the interactive setup:
gitea-mcp init
Claude prompts you for the Gitea URL and token, verifies the connection, and configures claude_desktop_config.json automatically.
For Claude Code, add to ~/.claude.json:
{
"mcpServers": {
"gitea": {
"command": "uvx",
"args": ["gitea-mcp"],
"env": {
"GITEA_URL": "https://your-gitea-server:3000",
"GITEA_TOKEN": "token"
}
}
}
}
Once connected, you can type things like:
# In Cursor or Claude: "List all open issues in our repository" "Create a new branch called fix-auth-bug from main" "Create a pull request merging fix-auth-bug into main" "Review the latest PR and suggest improvements" "What files changed in the last 3 commits?"
Beyond MCP, Gitea can run AI agents directly inside your CI/CD pipelines using Gitea Actions. Two community projects make this possible:
| Agent | How It Works | Trigger |
|---|---|---|
| Claude Code Gitea Action | Runs Claude Code inside a Gitea Action runner. Claude can respond to comments, review PRs, implement features, and push commits β all from within your CI pipeline. | Mention @claude in an issue or PR comment |
| Cursor Gitea Agent | Integrates Cursor AI as a Gitea Action. Tag @cursor on an issue or PR to get AI-powered code review, feature planning, or implementation help. |
Mention @cursor in an issue or PR comment |
Example workflow for .gitea/workflows/claude.yml:
name: Claude Code Assistant
on:
issue_comment:
types: [created]
jobs:
claude:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: markwylde/claude-code-gitea-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
gitea_token: ${{ secrets.GITEA_TOKEN }}
trigger_phrase: "@claude"
When someone comments @claude Review this PR please on a pull request, the action triggers Claude to analyze the code, post review comments, and even push fixes.
The tea-skills project packages Gitea/Forgejo workflows as installable skills for Claude Code and other agent CLIs. It uses the tea CLI (Gitea's official command-line tool) under the hood:
# Install tea-skills as a Claude Code plugin claude plugin marketplace add deevus/tea-skills claude plugin install tea@tea-skills # Now your agent can handle issues, PRs, milestones, labels "List all open issues tagged 'bug'" "Create a milestone for the next sprint" "Assign all priority-P1 issues to me"
GitHub Copilot works primarily with GitHub.com. It does not natively support self-hosted Git servers like Gitea. However, there are two workarounds:
GitLab Duo AI features (Code Suggestions, Duo Chat, vulnerability explanation) are built natively into GitLab's paid tiers (Premium and Ultimate). They work only with GitLab.com or GitLab Self-Managed instances with a valid subscription. Gitea does not have a native equivalent β but the MCP approach lets you use any AI tool of your choice rather than being locked into a vendor-specific AI.
What is the MCP (Model Context Protocol) in the context of Gitea?
Which statement about AI coding assistants and Gitea is true?
You now have a running Gitea server with repositories, team structure, branch protection, CI/CD, and a team that knows the daily workflow. Here's what to tackle next:
./gitea-data folder to an external location using rsync or a cron job.pull β edit β add β commit β push.