Самостоятельный хостинг Gitea на VPS с Docker Compose

10 мин чтения·Matthieu·ci-cdself-hostingdocker-composegiteapostgresqldockergit|

Разворачиваем боевой экземпляр Gitea с PostgreSQL, SSH-проксированием на порту 22, CI/CD через Gitea Actions, Git LFS, зеркалированием с GitHub и автоматическими бэкапами. Всё на одном VPS через Docker Compose.

Gitea — это лёгкий самохостящийся Git-сервис, написанный на Go. Он предоставляет pull request'ы, трекер задач, CI/CD, реестры пакетов и Git LFS в одном бинарнике, который в простое занимает около 150 МБ оперативной памяти. Сравните с минимальными 4 ГБ GitLab — и станет понятно, почему Gitea отлично подходит для VPS.

В этом руководстве мы развернём Gitea с Docker Compose и PostgreSQL на VPS. Вы настроите SSH-проксирование (passthrough), чтобы git clone git@ваш-сервер:user/repo.git работал на порту 22, сконфигурируете Gitea Actions с контейнеризированным раннером, включите Git LFS, настроите зеркалирование репозиториев с GitHub, webhook'и и автоматические бэкапы.

Что нужно перед установкой Gitea?

VPS с Debian 12 или Ubuntu 24.04, на котором установлены Docker и Docker Compose v2, доменное имя, указывающее на сервер, и обратный прокси (Nginx или Caddy) с настроенным TLS. Руководство предполагает, что вы уже провели базовую настройку безопасности сервера: не-root пользователь с sudo, аутентификация по SSH-ключу, включённый файрвол.

Требование Минимум
ОС Debian 12 / Ubuntu 24.04
RAM 1 ГБ (2 ГБ рекомендуется с CI-раннером)
Docker 27.x+ с Compose v2
Домен A-запись, указывающая на IP VPS
Обратный прокси Nginx или Caddy с TLS

Как развернуть Gitea с Docker Compose и PostgreSQL?

Создайте директорию проекта, сгенерируйте секреты в файле .env и опишите сервисы Gitea и PostgreSQL в docker-compose.yml. Файл .env хранит учётные данные вне системы контроля версий и compose-файлов.

Создание директории проекта

sudo mkdir -p /opt/gitea
sudo chown $USER:$USER /opt/gitea
cd /opt/gitea

Генерация секретов

openssl rand -base64 32 > /dev/null  # test that openssl works
cat > .env << 'ENVFILE'
POSTGRES_USER=gitea
POSTGRES_PASSWORD=REPLACE_ME
POSTGRES_DB=gitea
GITEA_SECRET_KEY=REPLACE_ME
GITEA_INTERNAL_TOKEN=REPLACE_ME
GITEA_LFS_JWT_SECRET=REPLACE_ME
ENVFILE

Замените каждый REPLACE_ME настоящим секретом:

sed -i "s/^POSTGRES_PASSWORD=.*/POSTGRES_PASSWORD=$(openssl rand -base64 32)/" .env
sed -i "s/^GITEA_SECRET_KEY=.*/GITEA_SECRET_KEY=$(openssl rand -base64 32)/" .env
sed -i "s/^GITEA_INTERNAL_TOKEN=.*/GITEA_INTERNAL_TOKEN=$(openssl rand -base64 32)/" .env
sed -i "s/^GITEA_LFS_JWT_SECRET=.*/GITEA_LFS_JWT_SECRET=$(openssl rand -base64 32)/" .env
chmod 600 .env

Файл Docker Compose

# /opt/gitea/docker-compose.yml
services:
  gitea:
    image: docker.gitea.com/gitea:1.25.5
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=db:5432
      - GITEA__database__NAME=${POSTGRES_DB}
      - GITEA__database__USER=${POSTGRES_USER}
      - GITEA__database__PASSWD=${POSTGRES_PASSWORD}
      - GITEA__server__DOMAIN=git.example.com
      - GITEA__server__ROOT_URL=https://git.example.com/
      - GITEA__server__SSH_DOMAIN=git.example.com
      - GITEA__server__SSH_PORT=22
      - GITEA__server__LFS_START_SERVER=true
      - GITEA__server__LFS_JWT_SECRET=${GITEA_LFS_JWT_SECRET}
      - GITEA__service__DISABLE_REGISTRATION=true
      - GITEA__service__REQUIRE_SIGNIN_VIEW=false
      - GITEA__security__SECRET_KEY=${GITEA_SECRET_KEY}
      - GITEA__security__INTERNAL_TOKEN=${GITEA_INTERNAL_TOKEN}
      - GITEA__actions__ENABLED=true
    restart: always
    volumes:
      - gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "127.0.0.1:3000:3000"
    depends_on:
      db:
        condition: service_healthy
    networks:
      - gitea

  db:
    image: docker.io/library/postgres:17
    container_name: gitea-db
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
    restart: always
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - gitea
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5

networks:
  gitea:
    external: false

volumes:
  gitea-data:
  postgres-data:

Замените git.example.com на ваш домен. Ключевые решения:

  • PostgreSQL 17 вместо устаревшего 14, который до сих пор рекомендуют в большинстве гайдов
  • Именованные тома (gitea-data, postgres-data) вместо bind mount для более чистого управления
  • Health check на PostgreSQL, чтобы Gitea дождалась готовности базы данных
  • DISABLE_REGISTRATION=true, потому что открытая регистрация на публичном инстансе привлекает злоупотребления
  • ACTIONS__ENABLED=true для активации Gitea Actions с самого начала
  • Порт 3000 привязан к localhost (127.0.0.1:3000:3000), чтобы доступ был только через обратный прокси, а не напрямую из интернета
  • Нет маппинга SSH-порта на контейнере. SSH будет работать через проксирование на хосте (следующий раздел)

Запуск стека

docker compose up -d
[+] Running 3/3
 ✔ Network gitea_gitea     Created
 ✔ Container gitea-db      Healthy
 ✔ Container gitea         Started
docker compose ps
NAME        IMAGE                           STATUS                   PORTS
gitea       docker.gitea.com/gitea:1.25.5   Up 2 minutes             127.0.0.1:3000->3000/tcp
gitea-db    postgres:17                     Up 2 minutes (healthy)   5432/tcp

Настройка обратного прокси

Добавьте Gitea в существующую конфигурацию Nginx:

server {
    listen 443 ssl http2;
    server_name git.example.com;

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

    server_tokens off;

    client_max_body_size 512M;

    location / {
        proxy_pass http://127.0.0.1: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;
    }
}

client_max_body_size 512M разрешает большие пуши, что особенно полезно при активном Git LFS. server_tokens off скрывает версию Nginx в заголовках ответа, так как раскрытие версии помогает атакующим нацелиться на известные уязвимости.

sudo nginx -t && sudo systemctl reload nginx

Создание администратора

docker exec -it gitea gitea admin user create \
  --username admin \
  --password "$(openssl rand -base64 16)" \
  --email admin@example.com \
  --admin \
  --must-change-password
New user 'admin' has been successfully created!

Сохраните сгенерированный пароль в надёжном месте (менеджер паролей, а не стикер на мониторе). Флаг --must-change-password заставит сменить пароль при первом входе. После входа включите двухфакторную аутентификацию в Settings > Security > Two-Factor Authentication.

Как настроить SSH-проксирование для Gitea в Docker?

Создайте пользователя git на хосте с тем же UID, что и внутри контейнера. Добавьте блок AuthorizedKeysCommand в /etc/ssh/sshd_config, который вызывает docker exec gitea /usr/local/bin/gitea keys. Это маршрутизирует SSH-операции с git с порта 22 хоста напрямую в контейнер, без открытия второго SSH-порта.

Создание пользователя git на хосте

Пользователю нужен UID 1000, чтобы совпадать с внутренним пользователем контейнера:

sudo adduser --system --shell /bin/bash --group --disabled-password --home /home/git --uid 1000 git

Если UID 1000 уже занят вашим обычным пользователем, измените USER_UID/USER_GID в compose-файле на доступный UID или подправьте флаг --uid здесь.

Создание shell-обёртки

Shell пользователя git должен перенаправлять команды в контейнер:

sudo tee /usr/local/bin/gitea-shell > /dev/null << 'WRAPPER'
#!/bin/sh
/usr/bin/docker exec -i --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" gitea sh "$@"
WRAPPER
sudo chmod 755 /usr/local/bin/gitea-shell
sudo usermod -s /usr/local/bin/gitea-shell git
ls -la /usr/local/bin/gitea-shell
-rwxr-xr-x 1 root root 99 Mar 20 10:00 /usr/local/bin/gitea-shell

Добавление пользователя git в группу docker

sudo usermod -aG docker git

Это даёт пользователю git разрешение на выполнение docker exec. На выделенном сервере Gitea это допустимо. На общем хосте лучше использовать правила sudo, ограниченные конкретной командой docker exec.

Настройка sshd

Добавьте этот блок в конец /etc/ssh/sshd_config:

# Gitea SSH passthrough
Match User git
  AuthorizedKeysCommandUser git
  AuthorizedKeysCommand /usr/bin/docker exec -i gitea /usr/local/bin/gitea keys -c /etc/gitea/app.ini -e git -u %u -t %t -k %k

AuthorizedKeysCommand спрашивает контейнер Gitea, принадлежит ли предъявленный SSH-клиентом публичный ключ зарегистрированному пользователю Gitea. Если ключ совпадает, SSH предоставляет доступ. Блок Match User git ограничивает это только пользователем git, не затрагивая ваш обычный SSH-доступ.

sudo sshd -t

Отсутствие вывода означает, что конфигурация валидна. Если видите ошибки, проверьте блок Match на опечатки.

sudo systemctl restart sshd

Проверка SSH-доступа

Добавьте ваш публичный SSH-ключ в аккаунт Gitea через веб-интерфейс (Settings > SSH/GPG Keys). Затем с локальной машины:

ssh -T git@git.example.com
Hi there, admin! You've successfully authenticated with the key named "my-laptop", but Gitea does not provide shell access.

Теперь можно клонировать, пушить и пуллить по SSH на порту 22:

git clone git@git.example.com:admin/my-repo.git

Как включить и настроить Gitea Actions для CI/CD?

Gitea Actions — встроенная система CI/CD с синтаксисом, совместимым с GitHub Actions. Активируется переменной окружения (уже задана в нашем compose-файле), раннер разворачивается как сервис Docker Compose, а файлы workflow пишутся в YAML прямо в репозиториях.

Как зарегистрировать act_runner через Docker Compose?

Сначала сгенерируйте токен регистрации раннера из панели администратора Gitea:

docker exec -it gitea gitea actions generate-runner-token
NxxxxxxxxxxxxxxxxxxxxxxxN

Скопируйте этот токен. Добавьте его в файл .env:

echo "GITEA_RUNNER_TOKEN=YOUR_TOKEN_HERE" >> /opt/gitea/.env
chmod 600 /opt/gitea/.env

Добавьте сервис раннера в docker-compose.yml:

  runner:
    image: docker.io/gitea/act_runner:0.3.0
    container_name: gitea-runner
    environment:
      - GITEA_INSTANCE_URL=http://gitea:3000
      - GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_TOKEN}
      - GITEA_RUNNER_NAME=vps-runner
    volumes:
      - runner-data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - gitea
    restart: always
    networks:
      - gitea

Добавьте runner-data: в секцию volumes: внизу файла. Запустите раннер:

docker compose up -d runner
docker compose logs runner --tail 20
level=info msg="Starting runner daemon"
level=info msg="Runner registered successfully"

Раннер монтирует Docker-сокет (/var/run/docker.sock), чтобы запускать контейнеры для каждой задачи. Это стандартная практика для CI-раннеров, но означает, что задачи могут обращаться к Docker-демону хоста. Для изолированных сред рассмотрите запуск раннера с Docker-in-Docker (DinD).

Переменная окружения Назначение
GITEA_INSTANCE_URL Внутренний URL, по которому раннер обращается к Gitea (используйте имя сервиса, а не публичный домен)
GITEA_RUNNER_REGISTRATION_TOKEN Одноразовый токен из gitea actions generate-runner-token
GITEA_RUNNER_NAME Отображаемое имя в панели администратора Gitea

Как выглядит workflow Gitea Actions?

Gitea Actions использует тот же YAML-синтаксис, что и GitHub Actions, с некоторыми отличиями. Создайте .gitea/workflows/build.yml в репозитории:

name: Build and Test

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.23'

      - name: Build
        run: go build -v ./...

      - name: Test
        run: go test -v ./...

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4

      - name: Deploy via SSH
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
        run: |
          mkdir -p ~/.ssh
          echo "$DEPLOY_KEY" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh -o StrictHostKeyChecking=accept-new user@production "cd /app && git pull && systemctl restart myapp"

Сохраните секрет DEPLOY_KEY в настройках репозитория: Settings > Actions > Secrets.

Возможность Gitea Actions GitHub Actions
Директория workflow .gitea/workflows/ .github/workflows/
uses: actions/* Работает (по умолчанию подтягивается с GitHub) Нативно
Контейнерные сервисы Поддерживается Поддерживается
Матричные сборки Поддерживается Поддерживается
Переиспользуемые workflow Поддерживается с Gitea 1.24 Поддерживается
Actions из Marketplace Большинство работает, некоторые требуют адаптации Нативно

Как включить Git LFS в Gitea?

Git Large File Storage позволяет отслеживать бинарные файлы (изображения, модели, датасеты) без раздувания репозитория. Gitea имеет встроенную поддержку LFS. Мы уже включили её через LFS_START_SERVER=true в compose-файле. Данные LFS по умолчанию хранятся в томе gitea-data.

Чтобы явно задать путь хранения или увеличить лимиты, отредактируйте конфигурацию Gitea:

docker exec -i gitea sh -c 'cat >> /data/gitea/conf/app.ini' << 'EOF'

[lfs]
PATH = /data/git/lfs
EOF

Перезапустите Gitea для применения изменений:

docker compose restart gitea

На стороне клиента установите git-lfs и начните отслеживать типы файлов:

git lfs install
git lfs track "*.bin" "*.h5" "*.onnx"
git add .gitattributes
git commit -m "Track model files with LFS"
git push

LFS-файлы хранятся на сервере по настроенному PATH внутри контейнера. Для крупных инсталляций можно настроить S3-совместимое хранилище в app.ini в секции [lfs].

Как зеркалировать репозитории GitHub в Gitea?

Pull-зеркалирование создаёт копию GitHub-репозитория «только для чтения» на вашем экземпляре Gitea. Синхронизация происходит автоматически по настраиваемому расписанию. Полезно для бэкапов, в качестве локального кэша за CI-раннером или для снижения зависимости от GitHub.

В веб-интерфейсе Gitea:

  1. Нажмите + > New Migration
  2. Выберите GitHub как источник
  3. Введите URL репозитория (например, https://github.com/owner/repo.git)
  4. Для приватных репозиториев введите ваше имя пользователя GitHub и personal access token в качестве пароля
  5. Отметьте This repository will be a mirror
  6. Установите интервал зеркалирования (по умолчанию: 8 часов)
  7. Нажмите Migrate Repository

Зеркало синхронизирует ветки, теги и релизы. Issues, pull request'ы и вики тоже могут быть перенесены при первичном импорте, но не синхронизируются непрерывно.

Зеркалирование через API:

curl -X POST "https://git.example.com/api/v1/repos/migrate" \
  -H "Authorization: token YOUR_GITEA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "clone_addr": "https://github.com/owner/repo.git",
    "mirror": true,
    "mirror_interval": "8h",
    "repo_name": "repo-mirror",
    "repo_owner": "admin",
    "service": "github"
  }'

Как настроить webhook'и для деплоя?

Webhook'и отправляют HTTP POST-запросы на URL при наступлении событий в репозитории. Это простой способ запускать деплои, уведомления или внешние CI-системы.

В вашем репозитории перейдите в Settings > Webhooks > Add Webhook > Gitea:

  • Target URL: https://deploy.example.com/hooks/gitea
  • HTTP Method: POST
  • Content Type: application/json
  • Secret: сгенерируйте через openssl rand -hex 32
  • Trigger events: Push events (или настройте по необходимости)

На принимающей стороне ваш скрипт деплоя должен проверять подпись webhook'а:

# The webhook sends a X-Gitea-Signature header
# Verify it with the shared secret before acting on the payload
EXPECTED=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $2}')
if [ "$SIGNATURE" != "$EXPECTED" ]; then
  echo "Invalid signature"
  exit 1
fi

Минимальный приёмник webhook'ов с помощью лёгкой утилиты webhook:

[
  {
    "id": "deploy",
    "execute-command": "/opt/deploy.sh",
    "command-working-directory": "/opt/app",
    "trigger-rule": {
      "match": {
        "type": "payload-hmac-sha256",
        "secret": "your-webhook-secret",
        "parameter": {
          "source": "header",
          "name": "X-Gitea-Signature"
        }
      }
    }
  }
]

Как сделать бэкап экземпляра Gitea?

В Gitea есть команда gitea dump, которая упаковывает репозитории, базу данных, конфигурацию и LFS-объекты в один zip-файл. Для PostgreSQL нужен ещё отдельный pg_dump для восстановления на определённый момент времени.

Ручной бэкап

docker exec -it gitea /usr/local/bin/gitea dump -c /data/gitea/conf/app.ini --file /data/gitea-backup.zip
docker cp gitea:/data/gitea-backup.zip /opt/gitea/backups/

Дамп включает:

Содержимое Включено в дамп
Git-репозитории Да
База данных (SQLite или дамп) Да
Конфигурация (app.ini) Да
LFS-объекты Да
Вложения, аватары Да
Пакеты Нет (бэкапить отдельно)

Для PostgreSQL также выполните:

docker exec gitea-db pg_dump -U gitea gitea | gzip > /opt/gitea/backups/gitea-db-$(date +%Y%m%d).sql.gz

Автоматический бэкап через cron

sudo mkdir -p /opt/gitea/backups
sudo chown root:root /opt/gitea/backups
sudo chmod 700 /opt/gitea/backups

Создайте скрипт бэкапа:

sudo tee /opt/gitea/backup.sh > /dev/null << 'BACKUP'
#!/bin/bash
set -euo pipefail

BACKUP_DIR="/opt/gitea/backups"
DATE=$(date +%Y%m%d-%H%M)

# Gitea dump
docker exec gitea /usr/local/bin/gitea dump -c /data/gitea/conf/app.ini --file /data/gitea-backup.zip --quiet
docker cp gitea:/data/gitea-backup.zip "$BACKUP_DIR/gitea-dump-$DATE.zip"
docker exec gitea rm /data/gitea-backup.zip

# PostgreSQL dump
docker exec gitea-db pg_dump -U gitea gitea | gzip > "$BACKUP_DIR/gitea-db-$DATE.sql.gz"

# Keep last 7 daily backups
find "$BACKUP_DIR" -name "gitea-*" -mtime +7 -delete

echo "Backup completed: $DATE"
BACKUP
sudo chmod 700 /opt/gitea/backup.sh
ls -la /opt/gitea/backup.sh
-rwx------ 1 root root 523 Mar 20 10:00 /opt/gitea/backup.sh

Запланируйте ежедневный запуск в 3 часа ночи:

echo "0 3 * * * root /opt/gitea/backup.sh >> /var/log/gitea-backup.log 2>&1" | sudo tee /etc/cron.d/gitea-backup
sudo chmod 644 /etc/cron.d/gitea-backup

Один раз запустите скрипт вручную для проверки:

sudo /opt/gitea/backup.sh
Backup completed: 20260320-1030
ls -lh /opt/gitea/backups/
-rw-r--r-- 1 root root 2.3M Mar 20 10:30 gitea-dump-20260320-1030.zip
-rw-r--r-- 1 root root  48K Mar 20 10:30 gitea-db-20260320-1030.sql.gz

Скопируйте бэкапы с сервера. Локальный бэкап, который погибнет вместе с диском — это не бэкап.

Как безопасно обновить Gitea?

Скачайте новый образ, пересоздайте контейнер и дайте Gitea автоматически выполнить миграции базы данных. Фиксируйте версии образов, чтобы обновления были намеренными, а не случайными.

cd /opt/gitea

# Back up first
sudo /opt/gitea/backup.sh

# Update the image tag in docker-compose.yml, then:
docker compose pull gitea
docker compose up -d gitea
docker compose logs gitea --tail 30

Следите за сообщениями о миграции:

2026/03/20 10:35:00 ...les/migration.go:67:Migrate() [I] Migration completed

Убедившись, что Gitea запустилась без ошибок, обновите раннер, если доступна новая версия:

docker compose pull runner
docker compose up -d runner

В чём разница между Gitea и Forgejo?

Forgejo отделился от Gitea в конце 2022 года после того, как коммерческая компания (Gitea Ltd.) взяла проект под контроль. Forgejo управляется Codeberg e.V. — немецкой некоммерческой организацией. К началу 2026 года Forgejo — это hard fork с расходящимися кодовыми базами. Оба работают с похожей Docker-конфигурацией, но миграция между ними больше не бесшовная.

Gitea Forgejo
Управление Gitea Ltd. (коммерческая) Codeberg e.V. (некоммерческая)
Лицензия MIT GPL-3.0+ (с Forgejo v9.0)
Docker-образ docker.gitea.com/gitea codeberg.org/forgejo/forgejo
Поддержка Actions Да (act_runner) Да (совместимый раннер)
Совместимость API Совместим с GitHub Совместим с GitHub
Уникальные возможности Gitea Enterprise, MCP-сервер Федерация (ForgeFed), инструменты модерации

Если хотите проект под управлением сообщества с copyleft-лицензией — выбирайте Forgejo. Если хотите оригинальный проект с коммерческой поддержкой — выбирайте Gitea. Docker Compose-конфигурация из этого руководства работает для обоих с минимальными изменениями (замените образ, подправьте пути).

Если начали с Gitea и хотите перейти позже: экспортируйте данные через gitea dump, разверните Forgejo и импортируйте. Тщательно протестируйте. Кодовые базы разошлись достаточно, чтобы некоторые схемы базы данных отличались.

Сколько RAM и CPU нужно Gitea?

Экземпляр Gitea с PostgreSQL в простое потребляет около 150-250 МБ оперативной памяти. При активном использовании с 5-10 пользователями и CI-раннерами ожидайте 300-500 МБ суммарно. Это примерно в 10 раз легче экземпляра GitLab, которому нужно минимум 4 ГБ.

Эти числа получены с работающего экземпляра Gitea на VPS Virtua Cloud (4 vCPU, 8 ГБ RAM):

docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
NAME            CPU %     MEM USAGE / LIMIT
gitea           0.15%     148.2MiB / 7.77GiB
gitea-db        0.08%     45.3MiB / 7.77GiB
gitea-runner    0.02%     32.1MiB / 7.77GiB
Сценарий RAM (весь стек) CPU
Простой, мало репозиториев ~230 МБ < 1%
Активная работа, 5-10 пользователей ~400 МБ 2-5%
Запущена CI-сборка ~600 МБ (пики во время сборок) 20-50% на задачу
Аналог GitLab 4 000+ МБ 10%+ в простое

Gitea комфортно работает на VPS с 2 ГБ. С CI-раннерами 4 ГБ дают запас для параллельных сборок.

Устранение неполадок

SSH-соединение отклонено: Проверьте, что пользователь git существует, в sshd_config есть блок Match, и sshd был перезапущен. Посмотрите логи:

journalctl -u sshd -f

Раннер не берёт задачи: Убедитесь, что раннер зарегистрирован в панели администратора (Site Administration > Actions > Runners). Проверьте логи раннера:

docker compose logs runner --tail 50

Ошибки подключения к базе данных при старте: Health check должен это предотвращать, но если Gitea стартует раньше PostgreSQL:

docker compose restart gitea

LFS push завершается ошибкой 413: Увеличьте client_max_body_size в конфигурации Nginx. 512M обычно достаточно, но подстройте под ваши самые большие файлы.

Логи Gitea:

docker compose logs gitea --tail 100

Или в реальном времени:

docker compose logs gitea -f

Авторское право 2026 Virtua.Cloud. Все права защищены. Данный контент является оригинальным произведением команды Virtua.Cloud. Воспроизведение, повторная публикация или распространение без письменного разрешения запрещены.

Готовы попробовать?

Разверните свой сервер за секунды. Linux, Windows или FreeBSD.

Смотреть тарифы VPS