Build Your Own GitHub: Self-Hosted Git for a 4-Person Team From zero to a running Gitea server with full CI/CD β€” no DevOps experience required

πŸ“š Tutorial ⏱ ~35 min read 🧩 4 Parts Β· 13 Sections Beginner β†’ Intermediate

🎯 What You'll Learn

πŸ“‹ Before You Begin

0. Prerequisites: What You Need (and Don't Need) Beginner

Before we begin, let's be crystal clear about what software you must have installed β€” and what you can safely ignore.

⚠️ One-time warning Every command in this tutorial uses plain text and code you can inspect. No installers phone home, no telemetry, no sign-up required (except your own Gitea server). You stay in control.

βœ… Required Software β€” Server Side

SoftwareLinux PathWindows 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)

βœ… Required Software β€” Developer Machines (All 4 Team Members)

Each developer who will use the Gitea server needs these on their local machine:

🚫 What You Do NOT Need

This list surprises most people. You can skip installing all of these:

πŸ’‘ Bottom line for Windows users To run the server: download Git for Windows + the Gitea .exe file. That's it. Two downloads, zero dependencies.
To connect as a developer: install Git for Windows. One download. Done.

πŸ’» Minimum Hardware Requirements

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.

πŸ“– Table of Contents

  1. Prerequisites: What You Need (and Don't Need)
  2. Why Build Your Own Git Server?
  3. A Brief History of Version Control
  4. Platform Shootout: Gitea vs GitLab CE vs Forgejo vs GitHub
  5. Architecture for a Small Team
  6. Step-by-Step: Install Gitea on Linux
  7. Step-by-Step: Install Gitea on Windows
  8. The First-Time Setup Wizard
  9. Configuring Your Team Workflow
  10. CI/CD with Gitea Actions
  11. Connecting Windows Dev Machines to Gitea
  12. The Daily Git Cycle Cheat Sheet
  13. AI & Coding Agents: Can You Use Claude, Copilot, and Cursor with Gitea?
  14. What's Next?

1. Why Build Your Own Git Server? Beginner

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:

πŸ’‘ The alternative Self-host Gitea on a $5/month VPS. Unlimited repos, unlimited collaborators, unlimited CI minutes. Your code, your server, your rules.

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.

Quiz 1 🧠 Why Self-Host?

Which of the following is NOT a reason to self-host Gitea instead of using GitHub Free?

Correct! GitHub Free gives you only 2,000 Actions minutes/month for private repos β€” not unlimited. That is NOT a reason to choose GitHub over self-hosting. All other options are valid reasons to self-host.

2. A Brief History of Version Control Beginner

To appreciate what Gitea does, it helps to understand how we got here. Version control went through three eras:

Era 1: Local Version Control

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.

Era 2: Centralized Version Control (CVCS)

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.

Era 3: Distributed Version Control (DVCS) β€” Git (2005)

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.

3. Platform Shootout: Gitea vs GitLab CE vs Forgejo vs GitHub Intermediate

If you're going to self-host, which platform do you choose? Here's an honest comparison for a 4-person team.

The Analogy

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)
⚠️ Honest take GitLab CE is a powerful platform, but its minimum RAM requirement (4 GB) is absurd for a 4-person team. GitLab is designed for enterprises with hundreds of users. For a small team, Gitea or Forgejo are the right choice β€” they run comfortably on 256 MB RAM and install in 60 seconds.

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.

4. Architecture for a Small Team Intermediate

For 4 people, you do not need Kubernetes, load balancers, or high-availability clusters. A single machine running Docker Compose is the right architecture.

Networking Layout

Internet ──▢ [Your VPS / Server]
                β”‚
                β”œβ”€β”€ Port 3000 (Web UI)
                β”œβ”€β”€ Port 2222 (SSH for Git operations)
                β”‚
                └── Docker Compose
                      β”‚
                      β”œβ”€β”€ gitea/gitea:1.26.4
                      └── (optional) postgres:16

Database Decision: SQLite vs Postgres

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.

Storage Layout

./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.

Quiz 2 🧠 Architecture & Database

For a 4-person team, which database should you use with Gitea and why?

Correct! SQLite is the right choice for small teams. Gitea natively supports it with zero maintenance β€” no separate database server needed. You can migrate to Postgres later if your team grows beyond 10+ developers.

5. Step-by-Step: Install Gitea on Linux Intermediate

This is the recommended path for production use. We'll use Docker Compose for automatic restarts, easy updates, and clean separation.

Prerequisites

Ensure your Linux server has Docker and Docker Compose installed:

sudo apt update && sudo apt install docker.io docker-compose-v2 -y

Step 1: Create the Project Directory

mkdir ~/gitea && cd ~/gitea

Step 2: Create docker-compose.yml

πŸ”΄ Critical 2026 Security Notice Use Gitea v1.26.4 or later. Earlier versions (v1.26.2 and below) have CVE-2026-20896 β€” an insecure default wildcard in proxy configurations. Always pin a specific version.
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)

Step 3: Launch Gitea

docker compose up -d

Gitea is now running. Open your browser to http://your-server-ip:3000.

βœ… Verify it's running 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.

6. Step-by-Step: Install Gitea on Windows Intermediate

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.

⚠️ Note This installs Gitea directly as a Windows binary. For production, the Docker-on-Linux method (Section 5) is more robust. This method is ideal for a dev machine or small office setup.

Prerequisites

Step 1: Download Gitea

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.

Step 2: Create the Directory Structure

C:\gitea\
  β”œβ”€β”€ gitea.exe
  β”œβ”€β”€ custom\
  └── data\

Step 3: Run Gitea (First Time)

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.

Step 4: Register Gitea as a Windows Service

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.

7. The First-Time Setup Wizard Beginner

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:

SettingRecommended ValueWhy
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.
πŸ”΄ Critical: Create your admin account NOW On the setup page, scroll down to "Administrator Account Settings" and create your admin account (username, password, email). If you skip this step, the first user who registers on the site will automatically become the administrator β€” which could be someone else!

8. Configuring Your Team Workflow Intermediate

8.1 Organization Structure

Don't clutter your Gitea dashboard with individual repos under personal namespaces. Instead, create an Organization for your team:

  1. Click the + icon in the top navigation β†’ New Organization
  2. Name it your-team-name (e.g., core-team)
  3. Add all 4 members with appropriate roles

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.

8.2 Branch Protection (The Crown Jewel)

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 this works for 4 people With only 4 devs, you want a lightweight process β€” not the heavyweight enterprise flow. Requiring 1 approval on every PR means code gets reviewed quickly, but nothing breaks main. No one can bypass the process.

Quiz 3 🧠 Branch Protection

Why should a 4-person team set branch protection on the main branch with "Require Pull Request before merging" and "Require 1 approval"?

Correct! With branch protection, no one can push directly to main. Every change goes through a Pull Request and at least one review. This prevents accidents without slowing down a small team β€” 1 approval is fast but effective.

9. CI/CD with Gitea Actions Advanced

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.

Setting Up the Runner

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

Example Pipeline: Test & Deploy

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.

10. Connecting Windows Dev Machines to Gitea Beginner

Your 4-person team is likely on Windows laptops. Here's how they connect to the Gitea server.

Step 1: Install Git for Windows

Each developer downloads and installs Git from gitforwindows.org. During installation:

Step 2: Introduce Yourself to Git

git config --global user.name "Your Name"
git config --global user.email "[email protected]"

Step 3: Clone Using HTTPS

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.

11. The Daily Git Cycle Cheat Sheet Beginner

Here's the 5-command rhythm every developer on your team needs to know. Print this, tape it to your monitor.

#CommandWhat 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.

The Full Daily Workflow

# 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
πŸ’‘ Pro tip for small teams With 4 people, pull before you push β€” always. If someone else pushed while you were working, Git will ask you to merge. Resolve merge conflicts with your editor's merge tool (VS Code has a great one built-in).

Quiz 4 🧠 Daily Git Workflow

What is the correct order of the 5-command daily Git cycle?

Correct! Pull (get latest) β†’ Edit (make changes) β†’ Status (check what changed) β†’ Add (stage) β†’ Commit (snapshot) β†’ Push (send to server). Pull before you push β€” always!

12. AI & Coding Agents: Can You Use Claude, Copilot, and Cursor with Gitea? Advanced

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.

12.1 The Gitea MCP Server β€” Your AI Gateway

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.

ClientStatusWhat 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

12.2 How to Connect: The 5-Minute Setup

Connecting your AI assistant to Gitea takes exactly four steps:

Step 1: Generate a Personal Access Token in Gitea

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.

Step 2: Install the Gitea MCP Server

pip install gitea-mcp

Or use uvx gitea-mcp without installing anything (recommended for isolation).

Step 3: Configure Your Client

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"
      }
    }
  }
}

Step 4: Start Using Natural Language

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?"

12.3 Gitea Actions as AI Agents

Beyond MCP, Gitea can run AI agents directly inside your CI/CD pipelines using Gitea Actions. Two community projects make this possible:

AgentHow It WorksTrigger
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.

12.4 tea-skills β€” Agent Skills for the CLI

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"

12.5 What About GitHub Copilot?

GitHub Copilot works primarily with GitHub.com. It does not natively support self-hosted Git servers like Gitea. However, there are two workarounds:

⚠️ Reality check for Copilot users Copilot's deep GitHub integration (PR summaries, code review, Actions insights) only works with GitHub.com. If you're deeply invested in Copilot Enterprise features, switching to a self-hosted Gitea means losing those. The trade-off: you gain full control, unlimited collaborators, and zero per-seat costs. For most 4-person teams, local code completion + MCP integration covers 95% of what you need.

12.6 What About GitLab Duo?

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.

πŸ’‘ The open advantage Gitea's approach to AI is fundamentally different from GitHub and GitLab. Rather than bundling a proprietary AI assistant you have to pay for per-seat, Gitea gives you an open MCP interface that works with any AI provider. You choose the model (Claude, GPT, Gemini, local open-source), the client (Cursor, Claude, VS Code), and the security policies. No vendor lock-in. No per-seat AI fees.

Quiz 5 🧠 AI & Coding Agents with Gitea

What is the MCP (Model Context Protocol) in the context of Gitea?

Correct! MCP is an open standard β€” like a USB-C port for AI. Gitea's MCP server lets any MCP-compatible client (Claude, Cursor, ChatGPT, Copilot CLI) manage repos, issues, PRs, and more through natural language.

Quiz 6 🧠 Gitea vs GitHub for AI

Which statement about AI coding assistants and Gitea is true?

Correct! Local AI code completion works regardless of where your Git remote is. For agentic features (PR management, issue triage, code review), Gitea's MCP server bridges the gap, letting tools like Cursor and Claude interact with your repos.

13. What's Next? Advanced

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:


πŸ† Key Takeaways