Индекс журналаDockup / заметка с места
Note / self-host-gitea

Как разместить Gitea на собственном сервере в 2026 году: репозитории, SSH и безопасные обновления

Разверните Gitea с правильным портом, постоянным хранилищем, TLS, аутентификацией и резервным копированием. Узнайте, как устранить проблему, при которой ROOT_URL генерирует ссылки localhost для клонирования в production.

Если вы уже пытались разместить Gitea на собственном сервере, вам наверняка знакомо это неприятное состояние: интерфейс открывается, но ROOT_URL генерирует ссылки localhost для клонирования или SSH-порт не проброшен. Пересоздание контейнера редко устраняет несогласованность между URL, состоянием и зависимостями.

В этом руководстве используется один конкретный критерий готовности — клонирование по HTTPS и SSH, отправка коммита и LFS-объекта, создание issue и запуск одной задачи на отдельно зарегистрированном Actions runner. Каждое конфигурационное решение оценивается по этому критерию, а не по зелёному статусу контейнера.

Найдите все данные, которые должны сохраняться в Gitea

До создания первой реальной записи перечислите всё состояние: репозитории, LFS-объекты, вложения, конфигурацию и базу данных. Подключите /data до начальной настройки, запишите безвредные тестовые данные и замените контейнер, чтобы убедиться, что этот путь действительно сохраняется. Проверьте подключение, записав безвредные данные, заменив Gitea и прочитав их обратно.

Snapshots удобны для быстрого отката, но при исчезновении хоста или тома нужна независимая резервная копия. Восстановите данные в пустой среде с закреплённым образом и убедитесь, что репозитории проходят fsck, LFS-объекты скачиваются, а issues, releases и разрешения пользователей соответствуют состоянию до создания резервной копии. Используйте persistent volumes и snapshots, чтобы не смешивать эти два механизма восстановления.

Создайте заменяемый контейнер Gitea

Следующая команда делает границу контейнера явной, не пытаясь имитировать настройку всех внешних сервисов.

docker run -d \
  --name gitea \
  --restart unless-stopped \
  -p 127.0.0.1:3000:3000 \
  -v gitea-data:/data \
  -e GITEA__security__SECRET_KEY=replace-with-a-long-random-value \
  gitea/gitea:latest

До открытия входящего трафика проверьте итоговые переменные окружения, mounts и listener. Для более загруженной установки добавьте проверенные параметры подключения к Postgres или MySQL, а при необходимости — маршрут SSH; для приватных сервисов используйте private names. Успешный запуск считается завершённым, когда вы можете клонировать репозиторий по HTTPS и SSH, отправить коммит и LFS-объект, создать issue и запустить одну задачу на отдельно зарегистрированном Actions runner, а не когда docker ps выводит Up.

Отделите Gitea от её зависимостей

Для Gitea работоспособность процесса и работоспособность продукта — разные вещи. Порт 3000 может отвечать, даже если пользовательская операция по-прежнему завершается ошибкой. Сетевой контракт Gitea включает Postgres или MySQL для более загруженной установки и маршрут SSH, если он нужен. Размещайте private endpoints во внутреннем DNS, разрешайте только необходимые исходящие подключения и предоставляйте Gitea service credential с ограниченной областью действия.

После существенных изменений конфигурации выполняйте такую проверку готовности: клонируйте репозиторий по HTTPS и SSH, отправьте коммит и LFS-объект, создайте issue и запустите одну задачу на отдельно зарегистрированном Actions runner. Не включайте дорогие внешние проверки в liveness probes, чтобы сбой провайдера не приводил к циклу перезапусков. При оценке capacity отслеживайте количество репозиториев, Git object packing, LFS storage, задержку базы данных и нагрузку runner, а не обычные запросы страниц: это точнее отражает реальную нагрузку на Gitea.

Настроить TLS легко, а с генерируемыми URL всё сложнее

Опубликуйте Gitea по одному HTTPS hostname, а исходный порт 3000 оставьте закрытым. Укажите в ROOT_URL и SSH_DOMAIN адреса, по которым пользователи действительно выполняют клонирование. Это не позволит браузерам и API-клиентам узнать о двух конкурирующих адресах.

На чистом клиенте выполните заведомо рабочую операцию и изучите первый запрос, завершившийся ошибкой. Если проблема связана с DNS или TLS, воспользуйтесь руководством по custom domain. Считайте ситуацию «ROOT_URL генерирует ссылки localhost для клонирования или SSH-порт не проброшен» отдельной диагностикой приложения после того, как маршрут уже проверен.

Проверьте развёртывание Gitea от начала до конца

Не используйте трафик первого пользователя как приёмочный тест Gitea. Подготовьте безвредное тестовое состояние и выполните полную операцию: «клонировать по HTTPS и SSH, отправить коммит и LFS-объект, создать issue и запустить одну задачу на отдельно зарегистрированном Actions runner». Зафиксируйте точный публичный URL, результат, ссылку на образ и интервал логирования, связанные с запуском.

Замените контейнер и повторите проверку, не пересоздавая данные. Затем восстановите систему на пустом хосте; условие успешного восстановления — репозитории проходят fsck, LFS-объекты скачиваются, а issues, releases и разрешения пользователей соответствуют состоянию до создания резервной копии. На каждом проходе отслеживайте количество репозиториев, Git object packing, LFS storage, задержку базы данных и нагрузку runner, а не обычные запросы страниц, и создайте alert на ухудшение операции, а не на основе метрик бездействующего контейнера.

Одна последняя проверка должна намеренно завершиться ошибкой: временно запретите тестовой identity доступ к Postgres или MySQL для более загруженной установки и к маршруту SSH, если он нужен. Убедитесь, что итоговое сообщение Gitea указывает на соответствующую границу, а не запускает удаление данных или бесконечный перезапуск. Восстановите рабочее состояние и подтвердите, что та же тестовая операция снова выполняется успешно. Включите эту короткую проверку в release checklist.

Отрепетируйте рискованное изменение Gitea

Для Gitea отслеживайте не процесс, а операцию: клонирование по HTTPS и SSH, отправку коммита и LFS-объекта, создание issue и запуск одной задачи на отдельно зарегистрированном Actions runner. Сопоставляйте её latency и error rate с количеством репозиториев, Git object packing, LFS storage, задержкой базы данных и нагрузкой runner, а не с обычными запросами страниц, чтобы alert указывал на компонент с ограниченной пропускной способностью.

Репетиция обновления должна учитывать, что schema migrations, repository hooks, packages и third-party runners требуют поэтапного обновления Gitea. Восстановите данные, выполните миграцию и запустите операцию до замены production-окружения. Если ROOT_URL генерирует ссылки localhost для клонирования или SSH-порт не проброшен, не удаляйте данные ради успешного запуска; последовательно сравните версию, переменные, mounts и доступность зависимостей.

Защитите наиболее ценную часть Gitea

После первого входа проверьте, какие действия доступны anonymous visitor, обычному пользователю и administrator. Ошибка Gitea, которой следует избегать, — сохранять доступ к installer или первой admin account дольше необходимого. Предусмотренная политика — закрыть installer после начальной настройки, ограничить site administration и использовать короткоживущие runner registration tokens.

Обращайтесь с GITEA__security__SECRET_KEY с учётом её роли в Gitea: храните чувствительные значения вне Git, документируйте последствия ротации и никогда не подставляйте публичный пример в production. Разделяйте accounts зависимостей и пользовательские accounts, по возможности запрещайте неиспользуемый egress и ограничивайте работу, зависящую от количества репозиториев, Git object packing, LFS storage, задержки базы данных и нагрузки runner, а не от обычных запросов страниц.

Что Dockup следует автоматизировать для Gitea

Для Gitea Dockup может создать маршрут и TLS certificate, сохранить mounts, передать secrets и разместить Postgres или MySQL для более загруженной установки, а также маршрут SSH, если он нужен, в private networking при развёртывании как в Dockup, так и на подключённых серверах.

Release gate по-прежнему основан на конкретной операции Gitea: клонировать по HTTPS и SSH, отправить коммит и LFS-объект, создать issue и запустить одну задачу на отдельно зарегистрированном Actions runner. Также проверьте условие восстановления — репозитории проходят fsck, LFS-объекты скачиваются, а issues, releases и разрешения пользователей соответствуют состоянию до создания резервной копии. Эти две проверки показывают, работает ли развёртывание и можно ли его восстановить.

Часто задаваемые вопросы

Что нужно Gitea для production-развёртывания?

Направьте контейнер Gitea на порту 3000 через один HTTPS origin. Сетевые зависимости включают Postgres или MySQL для более загруженной установки и маршрут SSH, если он нужен. Не объявляйте Gitea готовой, пока не сможете клонировать по HTTPS и SSH, отправить коммит и LFS-объект, создать issue и запустить одну задачу на отдельно зарегистрированном Actions runner.

Какие данные Gitea нужно включать в резервную копию?

Сохраняйте /data и включайте репозитории, LFS-объекты, вложения, конфигурацию и базу данных в один recovery manifest. Восстановление Gitea считается успешным только тогда, когда репозитории проходят fsck, LFS-объекты скачиваются, а issues, releases и разрешения пользователей соответствуют состоянию до создания резервной копии.

Требуется ли Gitea HTTPS за reverse proxy?

Используйте HTTPS для публичного Gitea origin, а порт 3000 оставьте во внутреннем маршруте. Правильно задайте настройку Gitea: укажите в ROOT_URL и SSH_DOMAIN адреса, по которым пользователи действительно выполняют клонирование. Для Gitea HTTPS защищает credentials и пользовательский контент при передаче и обеспечивает согласованное поведение клиентов, зависящее от origin.

Как тестировать обновление Gitea?

Восстановите текущее состояние Gitea в изолированном развёртывании, примените candidate version и повторите приёмочную операцию. Уделите особое внимание тому, что schema migrations, repository hooks, packages и third-party runners требуют поэтапного обновления Gitea. Сохраняйте предыдущий образ Gitea, пока не будут понятны границы миграции данных и отката.