Руководства

Gitea на VPS: свой Git-сервер с CI за 10 минут

Gitea на VPS: свой Git-сервер с CI за 10 минут

Gitea — лёгкий сервер Git с веб-интерфейсом, похожим на GitHub: репозитории, задачи, пулреквесты, вики, реестр пакетов и встроенный CI — Gitea Actions, совместимый с синтаксисом GitHub Actions. Он написан на Go, запускается одним контейнером и спокойно живёт на сервере с 2 ГБ памяти — там, где GitLab даже не стартует. Ниже — какой VPS нужен, как поставить Gitea с PostgreSQL через Docker Compose, настроить HTTPS и SSH, подключить раннер для CI и не потерять репозитории.

Зачем свой Git-сервер

  • Код под вашим контролем. Репозитории не зависят от правил, тарифов и доступности чужой платформы.
  • Зеркало GitHub. Gitea умеет регулярно забирать изменения из репозиториев на GitHub и GitLab — получается резервная копия, которая обновляется сама.
  • Приватные проекты без лимитов. Сколько угодно закрытых репозиториев, участников и минут CI — ограничение только в ресурсах сервера.
  • Автодеплой рядом с кодом. Gitea Actions собирает и выкатывает проект на ваши серверы — см. «Автодеплой на VPS».

Какой сервер нужен

СценарийТарифРесурсыЦена
Личные репозитории, зеркала GitHubStart2 vCPU, 2 ГБ, 30 ГБ$10/мес
Команда до 10–15 человек, задачи, пакетыMedium3 vCPU, 4 ГБ, 40 ГБ$20/мес
Активная команда, много репозиториев и пакетовPremium4 vCPU, 8 ГБ, 50 ГБ$40/мес
Раннер для CI — отдельно от GiteaStart или Mediumпо тяжести сборок$10–20/мес

Почему раннер лучше держать на отдельном сервере — ниже, в разделе про Actions. Для пользователей из России подойдут Финляндия с NVMe — git-операции и поиск по коду работают быстрее на быстром диске — или Россия, если важно, чтобы код хранился в стране.

Установка через Docker Compose

Подготовьте сервер по статье «Как настроить VPS после покупки» и установите Docker — «Docker на VPS». Создайте папку ~/gitea и в ней файл .env с паролем базы:

DB_PASSWORD=длинный_пароль_из_букв_и_цифр

Рядом — docker-compose.yml:

services:
  server:
    image: docker.gitea.com/gitea:1.26
    restart: always
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=db:5432
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=${DB_PASSWORD}
    volumes:
      - ./data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "127.0.0.1:3000:3000"
      - "2222:22"
    depends_on:
      - db

  db:
    image: postgres:17-alpine
    restart: always
    environment:
      - POSTGRES_USER=gitea
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=gitea
    volumes:
      - ./postgres:/var/lib/postgresql/data

Что здесь важно:

  • Версия закреплена — 1.26, а не latest. Обновление до новой крупной версии будет вашим решением, а не сюрпризом после перезапуска.
  • Веб-интерфейс слушает только локальный адрес 127.0.0.1:3000 — наружу его выставит веб-сервер с HTTPS.
  • Git по SSH — на порту 2222. Порт 22 остаётся для администрирования самого сервера, и они не конфликтуют.
  • База данных не публикуется наружу — у неё нет секции ports.

Запуск:

docker compose up -d

HTTPS и домен

Направьте поддомен, например git.example.com, на IP сервера («DNS для начинающих»). Проще всего выставить Gitea наружу через Caddy — он сам получит сертификат Let's Encrypt. В /etc/caddy/Caddyfile:

git.example.com {
    reverse_proxy 127.0.0.1:3000
}

Откройте firewall для веба и Git по SSH:

sudo ufw allow 80,443/tcp
sudo ufw allow 2222/tcp

Подробнее о сертификатах — в статье «SSL на VPS».

Первичная настройка

Откройте https://git.example.com — появится страница установки. Параметры базы данных уже подставлены из переменных окружения. Проверьте и поменяйте:

  • Базовый URL — https://git.example.com/. Из него Gitea строит ссылки для клонирования и перенаправления; если ссылки показывают http или не тот адрес — дело в этой настройке.
  • Порт SSH-сервера — 2222, чтобы ссылки для клонирования были правильными.
  • Учётная запись администратора — создайте её здесь же.

Если сервер только для вас или вашей команды, закройте открытую регистрацию — иначе на публичном адресе со временем появятся чужие аккаунты. Добавьте в секцию environment сервиса Gitea строку GITEA__service__DISABLE_REGISTRATION=true и перезапустите: docker compose up -d. Новых участников администратор будет добавлять сам.

Клонирование по SSH работает так:

git clone ssh://git@git.example.com:2222/user/repo.git

Чтобы не писать порт каждый раз, добавьте в ~/.ssh/config на своём компьютере блок для git.example.com с Port 2222 — как это делается, показано в статье «Как подключиться к VPS».

CI: Gitea Actions и раннер

Gitea Actions понимает workflow-файлы в формате GitHub Actions, поэтому многие готовые сценарии переносятся почти без изменений. Задачи выполняет отдельная программа — act_runner. В Gitea 1.26 у Actions появились повторный запуск только упавших задач, сводки по запускам, настройка прав токенов и управление каждым раннером по отдельности.

Порядок подключения:

  1. В Gitea откройте «Администрирование сайта» → Actions → «Раннеры» и создайте токен регистрации. Для раннера одного репозитория то же самое есть в его настройках.
  2. На сервере для раннера создайте docker-compose.yml:
    services:
      runner:
        image: gitea/act_runner
        restart: always
        environment:
          - GITEA_INSTANCE_URL=https://git.example.com
          - GITEA_RUNNER_REGISTRATION_TOKEN=токен_из_gitea
        volumes:
          - ./data:/data
          - /var/run/docker.sock:/var/run/docker.sock
    Токен нужен только при первом запуске — потом раннер хранит регистрацию в ./data.
  3. Запустите docker compose up -d — раннер появится в списке в Gitea.

Почему раннер — на отдельном сервере. Раннер выполняет код из репозиториев, а доступ к docker.sock на практике равен правам root на машине. Если раннер стоит рядом с Gitea, ошибка или вредоносный код в одном workflow получает доступ ко всем репозиториям и базе. Отдельный VPS за $10 изолирует сборки от исходников, а заодно тяжёлая сборка не тормозит веб-интерфейс.

Бэкапы

Всё, что нужно сохранить, лежит в двух папках: ./data — репозитории, вложения, настройки, и база PostgreSQL. Базу надёжнее копировать дампом, а не файлами:

docker compose exec -T db pg_dump -U gitea gitea | gzip > /var/backups/gitea-db-$(date +%F).sql.gz

Добавьте эту команду в cron и отправляйте дампы вместе с папкой ./data в отдельное хранилище — например, через restic. Как настроить — в статье «Сервер для бэкапа». Git-репозитории распределённые, но задачи, пулреквесты, вики и настройки живут только на сервере.

Обновление

Перед обновлением прочитайте заметки к релизу и сделайте бэкап. Затем поменяйте версию образа в docker-compose.yml, например на следующую 1.27, и выполните:

docker compose pull
docker compose up -d

Gitea сама обновит структуру базы при запуске. Не перепрыгивайте через несколько крупных версий сразу — обновляйтесь последовательно. Исправления безопасности внутри одной версии приходят регулярно: например, в 1.26 закрыли три уязвимости, — так что держать сервер на актуальном патч-релизе важно.

Gitea, Forgejo или GitLab

  • Forgejo — форк Gitea, который с 2022 года развивает некоммерческое сообщество; на нём работает Codeberg. Возможности и установка похожи, но проекты постепенно расходятся, и переезд между ними со временем усложняется. Выбирайте сразу, исходя из того, чья модель развития вам ближе.
  • GitLab — платформа с огромным набором функций, но требует в разы больше памяти и внимания. Оправдан, когда нужны его продвинутые возможности; для небольшой команды Gitea закрывает типовые задачи на сервере в несколько раз дешевле.

Medium в Финляндии, NVMe — $20/мес   Start в Финляндии — $10/мес   Start в России — $10/мес

Цены указаны на момент публикации, оплата у провайдера. Тариф можно повысить позже без переноса данных.

Коротко

  • Gitea — лёгкий Git-сервер с задачами, пулреквестами, пакетами и CI; для личных проектов хватает Start с 2 ГБ, для команды — Medium.
  • Установка — Docker Compose с PostgreSQL, версия образа закреплена, веб только на 127.0.0.1, Git по SSH на порту 2222.
  • Наружу — через Caddy с HTTPS; базовый URL и порт SSH задаются на странице установки.
  • Закройте открытую регистрацию, если сервер не публичный.
  • Раннер Gitea Actions — на отдельном VPS: он выполняет код из репозиториев.
  • Бэкап — дамп PostgreSQL и папка data в отдельное хранилище.