Gitea self-hosted na VPS

Gitea é o servidor Git self-hosted mais leve e completo, interface web similar ao GitHub, pull requests, issues, wikis, webhooks e agora CI/CD nativo com Gitea Actions compatível com GitHub Actions. Ideal para código privado que não deve sair da sua infraestrutura ou para equipes que querem controle total do SCM.

Instalar Gitea com Docker Compose

Stack com Gitea e PostgreSQL para produção:

yaml
# docker-compose.yml
services:
  gitea:
    image: gitea/gitea:latest
    restart: always
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=postgres:5432
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=${POSTGRES_PASSWORD}
      - GITEA__server__DOMAIN=git.seudominio.com.br
      - GITEA__server__ROOT_URL=https://git.seudominio.com.br/
      - GITEA__server__SSH_DOMAIN=git.seudominio.com.br
      - GITEA__server__SSH_PORT=2222
      - GITEA__service__DISABLE_REGISTRATION=true  # apenas convites
      - GITEA__mailer__ENABLED=false
    ports:
      - "127.0.0.1:3000:3000"   # HTTP
      - "2222:22"                # SSH Git
    volumes:
      - gitea_data:/data
      - /etc/timezone:/etc/timezone:ro
    depends_on:
      - postgres

  postgres:
    image: postgres:16-alpine
    restart: always
    environment:
      POSTGRES_DB: gitea
      POSTGRES_USER: gitea
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  gitea_data:
  postgres_data:

Configurar Nginx e SSH

Proxy reverso para HTTPS e acesso SSH para operações Git:

nginx
# /etc/nginx/conf.d/gitea.conf
server {
    listen 80;
    server_name git.seudominio.com.br;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name git.seudominio.com.br;

    ssl_certificate     /etc/letsencrypt/live/git.seudominio.com.br/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/git.seudominio.com.br/privkey.pem;

    client_max_body_size 512M;     # para repositórios grandes

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        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;
        proxy_read_timeout 300s;
    }
}

# Para clonar via SSH na porta 2222:
# git clone ssh://git@git.seudominio.com.br:2222/usuario/repo.git
# Ou adicionar ao ~/.ssh/config:
# Host git.seudominio.com.br
#     Port 2222

Migrar repositórios do GitHub para o Gitea

Migrar todos os repositórios de uma organização GitHub para o Gitea:

bash
# Migrar repositório individual via interface web:
# Gitea → + (New) → Migrate External Repository → GitHub

# Migração em massa via API do Gitea:
GITEA_URL="https://git.seudominio.com.br"
GITEA_TOKEN="seu_token_gitea"
GITHUB_TOKEN="seu_github_token"
GITHUB_ORG="sua-org-github"

# Listar repositórios da organização no GitHub:
REPOS=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/orgs/$GITHUB_ORG/repos?per_page=100" \
  | python3 -c "import sys,json; [print(r['full_name']) for r in json.load(sys.stdin)]")

# Migrar cada repositório:
for REPO in $REPOS; do
  REPO_NAME=$(echo "$REPO" | cut -d/ -f2)
  curl -X POST "$GITEA_URL/api/v1/repos/migrate" \
    -H "Authorization: token $GITEA_TOKEN" \
    -H "Content-Type: application/json" \
    -d "{
      "clone_addr": "https://github.com/$REPO",
      "auth_token": "$GITHUB_TOKEN",
      "repo_name": "$REPO_NAME",
      "private": true,
      "mirror": true
    }"
  echo "Migrado: $REPO_NAME"
done

Gitea Actions: CI/CD nativo

Gitea Actions é compatível com GitHub Actions, mesma sintaxe de workflow:

yaml
# .gitea/workflows/ci.yml — compatível com GitHub Actions syntax
name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest  # requer um runner registrado no Gitea

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
      - run: npm ci
      - run: npm test

# Registrar um runner no Gitea:
# 1. Settings → Actions → Runners → Create new runner
# 2. Copiar o token gerado
# 3. No servidor runner:
docker run -d --name gitea-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v gitea_runner:/data \
  gitea/act_runner:latest \
  register --no-interactive \
  --instance https://git.seudominio.com.br \
  --token TOKEN_DO_RUNNER \
  --name meu-runner

Backup e manutenção do Gitea

Backup completo incluindo repositórios e banco de dados:

bash
# Backup via comando nativo do Gitea:
docker compose exec gitea gitea admin user list
docker compose exec gitea gitea dump -c /data/gitea/conf/app.ini -w /tmp/backup

# Copiar o backup para fora do container:
docker compose cp gitea:/tmp/backup.zip /var/backups/gitea-$(date +%Y%m%d).zip

# Backup manual do banco + volumes:
DATE=$(date +%Y%m%d_%H%M)
docker compose exec -T postgres pg_dump -U gitea gitea \
  | gzip > /var/backups/gitea_db_${DATE}.sql.gz

docker run --rm \
  -v gitea_data:/data \
  -v /var/backups:/backup \
  alpine tar czf "/backup/gitea_vol_${DATE}.tar.gz" /data

# Manutenção do banco de dados Git (compactar repos):
docker compose exec gitea gitea admin git fsck-repos --all

Não quer configurar manualmente?

Implante o VPS em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

GitLab: mais completo (CI/CD robusto, container registry, board de issues), mas muito mais pesado, requer 4+ GB RAM só para o GitLab. Gitea: extremamente leve (~200 MB RAM), rápido de instalar, interface limpa, CI/CD com Gitea Actions. Para equipes pequenas e VPS com recursos limitados: Gitea é a escolha óbvia. GitLab faz sentido quando você precisa de todo o ecossistema integrado.

Sim, Git LFS está habilitado por padrão no Gitea. Para configurar: GITEA__server__LFS_START_SERVER=true. Armazenamento LFS local por padrão; pode ser configurado para usar MinIO/S3 como backend: GITEA__lfs__PATH=s3://bucket. Ideal para repositórios com assets binários grandes (modelos ML, imagens, vídeos).

Durante a migração: marque a opção "This repository will be a mirror". O Gitea sincroniza automaticamente com o repositório original em intervalos configuráveis. Útil para manter uma cópia local de repositórios importantes. Com autenticação: configure o token do GitHub nas configurações do mirror para sincronizar repositórios privados.

Sim, o Gitea usa Git padrão sobre HTTPS e SSH. Clone o repositório e trabalhe normalmente. Para integração mais profunda: instale a extensão "Gitea" no VSCode. Para SSH: adicione sua chave pública nas configurações do usuário Gitea e configure o ~/.ssh/config com a porta 2222.

Sim, API REST completa compatível com GitHub API v3 para operações de repositório, issues, pull requests, usuários e organizações. Documentação Swagger disponível em git.seudominio.com.br/api/swagger. Útil para automações, scripts de deploy que criam PRs automaticamente ou integração com ferramentas externas.