Gitea — лёгкая и быстрая альтернатива тяжёлым платформам управления репозиториями. Она отлично подходит для команд, которым нужен приватный Git с минимальными накладными расходами. В этой инструкции развернём Gitea на облачном VDS: настроим systemd‑сервис, поднимем Nginx reverse proxy с HTTPS, включим SSH для git и подготовим резервное копирование. Материал ориентирован на Debian/Ubuntu.
План развёртывания и требования
Мы установим Gitea в режиме приложения, слушающего локальный порт, а снаружи будем публиковать её через Nginx как обратный прокси. Такой подход упрощает выпуск и ротацию TLS‑сертификатов, даёт гибкость при настройке заголовков и буферов, а также удобен для масштабирования.
Минимальные требования к VDS: 1 vCPU, 1–2 ГБ RAM, 20 ГБ диска. Для 5–10 пользователей и десятков репозиториев этого достаточно; для Git LFS или CI закладывайте больше диска и ОЗУ. Нужен домен для HTTPS, открытые порты 22/80/443 и корректные A/AAAA‑записи. Если домена ещё нет — поможет регистрация доменов.
Почему не слушать 443 прямо в Gitea? Разделение ролей «приложение на localhost» и «Nginx на внешнем интерфейсе» упрощает сопровождение: TLS‑политики, лимиты, компрессия и защита от аномалий сосредоточены в одном месте — в конфигурации Nginx.
Подготовка системы
Начнём с обновления пакетов и установки базового окружения. Имя пользователя сервиса — git, данные храним в /var/lib/gitea, конфиг — в /etc/gitea.
sudo apt update
sudo apt install -y nginx git unzip curl tar coreutils ca-certificates
sudo apt install -y certbot python3-certbot-nginx
# Системный пользователь без shell
sudo adduser --system --shell /usr/sbin/nologin --gecos 'Gitea' --group --disabled-password --home /home/git git
# Каталоги для данных и конфигов
sudo mkdir -p /var/lib/gitea/{custom,data,log}
sudo mkdir -p /etc/gitea
# Права и владельцы
sudo chown -R git:git /var/lib/gitea
sudo chmod -R 750 /var/lib/gitea
sudo chown root:git /etc/gitea
sudo chmod 770 /etc/gitea
Если используется UFW или другой файрвол, откройте порты 22, 80 и 443. Для UFW это выглядит так:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status
Установка Gitea (бинарь) и базовая конфигурация
Удобнее всего использовать подготовленный бинарь: его легко обновлять без изменения схемы каталогов. Замените версию на актуальную стабильную из релизов проекта.
GITEA_VERSION=1.22.3
sudo curl -fL -o /usr/local/bin/gitea https://dl.gitea.com/gitea/${GITEA_VERSION}/gitea-${GITEA_VERSION}-linux-amd64
sudo chmod 755 /usr/local/bin/gitea
sudo chown root:root /usr/local/bin/gitea
# Создаём файл конфига
sudo tee /etc/gitea/app.ini > /dev/null << 'EOF'
APP_NAME = Gitea
RUN_MODE = prod
RUN_USER = git
[server]
PROTOCOL = http
DOMAIN = gitea.example.com
ROOT_URL = https://gitea.example.com/
HTTP_ADDR = 127.0.0.1
HTTP_PORT = 3000
DISABLE_SSH = false
START_SSH_SERVER = false
SSH_PORT = 22
SSH_DOMAIN = gitea.example.com
LFS_START_SERVER = true
LFS_JWT_SECRET = replace_me_lfs_secret
[database]
DB_TYPE = sqlite3
PATH = /var/lib/gitea/data/gitea.db
[security]
INSTALL_LOCK = true
SECRET_KEY = replace_me_secret
[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
[session]
COOKIE_SECURE = true
[log]
MODE = console
LEVEL = info
[repository]
ROOT = /var/lib/gitea/data/repositories
[lfs]
PATH = /var/lib/gitea/data/lfs
EOF
# Права доступа на конфиг
sudo chown root:git /etc/gitea/app.ini
sudo chmod 640 /etc/gitea/app.ini
Секреты лучше сгенерировать случайно и заменить плейсхолдеры:
openssl rand -hex 32
В примере используется SQLite — для небольших команд достаточно. Если ожидается рост, переходите на PostgreSQL: выше производительность и удобнее бэкап. В этом случае замените секцию [database] на параметры подключения.
systemd‑сервис с базовым hardening
Создадим юнит для Gitea. Ограничим привилегии, доступ к ФС и укажем каталоги, доступные на запись.
sudo tee /etc/systemd/system/gitea.service > /dev/null << 'EOF'
[Unit]
Description=Gitea (Git with a cup of tea)
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
User=git
Group=git
WorkingDirectory=/var/lib/gitea
Environment=GITEA_WORK_DIR=/var/lib/gitea
Environment=GITEA_CUSTOM=/var/lib/gitea/custom
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
RestartSec=3s
# Журналирование
StandardOutput=journal
StandardError=journal
# Базовое hardening
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=full
ProtectHome=yes
ProtectKernelTunables=yes
ProtectControlGroups=yes
ProtectKernelModules=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes
CapabilityBoundingSet=
# Каталоги, доступные на запись
ReadWritePaths=/var/lib/gitea /etc/gitea
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now gitea
sudo systemctl status gitea
На этом этапе Gitea должна слушать 127.0.0.1:3000. Проверьте журнал на ошибки конфигурации и права каталогов.
Nginx reverse proxy: редирект на HTTPS, проксирование и WebSocket
Настроим Nginx как обратный прокси с редиректом на HTTPS и поддержкой веб‑сокетов (уведомления). Пробрасываем реальные IP и имя хоста, увеличиваем таймауты для долгих Git‑операций и настраиваем лимиты для LFS.
sudo tee /etc/nginx/sites-available/gitea.conf > /dev/null << 'EOF'
server {
listen 80;
listen [::]:80;
server_name gitea.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name gitea.example.com;
# Временные пути к сертификатам (certbot пропишет актуальные)
ssl_certificate /etc/letsencrypt/live/gitea.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/gitea.example.com/privkey.pem;
# Рекомендуемые настройки TLS
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# Ограничения и таймауты
client_max_body_size 1G;
keepalive_timeout 65s;
# Основной прокси
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 https;
proxy_set_header X-Forwarded-Host $host;
# WebSocket для уведомлений
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Долгие операции (clone/push)
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
# Git LFS: разумно отключить буферизацию для крупных загрузок
location ~ ^/.+\.git/info/lfs/ {
proxy_pass http://127.0.0.1:3000;
proxy_request_buffering off;
client_max_body_size 2G;
}
}
EOF
sudo nginx -t
sudo systemctl reload nginx
Замените gitea.example.com на ваш FQDN. После выпуска сертификата сайт будет доступен по HTTPS.

SSL: выпуск Let’s Encrypt и автоматическое продление
Для бесплатного сертификата используйте certbot с плагином Nginx: он пропишет пути к сертификатам и редиректы. Если нужен коммерческий сертификат, доступен вариант с GlobalSign — смотрите SSL-сертификаты.
sudo certbot --nginx -d gitea.example.com --agree-tos -m admin@example.com --redirect
sudo systemctl reload nginx
# Проверим задачи автопродления
sudo systemctl list-timers | grep certbot
При планировании HSTS и постоянных редиректов пригодится разбор тонкостей миграции домена и политик безопасности: смотрите материал о 301, HSTS и SSL.
SSH для git: внешний OpenSSH и ключи пользователей
Gitea может не поднимать собственный SSH‑сервер и использовать системный OpenSSH. Современная интеграция — через AuthorizedKeysCommand: ключи пользователей проверяет бинарь Gitea, без записи в authorized_keys.
# Интеграция Gitea с внешним OpenSSH
sudo tee -a /etc/ssh/sshd_config > /dev/null << 'EOF'
# Gitea external SSH integration
AuthorizedKeysCommand /usr/local/bin/gitea --config /etc/gitea/app.ini keys -e
AuthorizedKeysCommandUser git
EOF
sudo systemctl restart ssh
Проверьте, что в app.ini указаны DISABLE_SSH = false, START_SSH_SERVER = false, корректные SSH_PORT и SSH_DOMAIN. Пользователи добавляют публичные ключи в веб‑интерфейсе, после чего clone/push по SSH работают из коробки.
Проверка clone/push
Создайте тестовый репозиторий в Gitea и попробуйте клон по SSH и HTTPS.
git clone ssh://git@gitea.example.com:22/vasya/hello.git
git clone https://gitea.example.com/vasya/hello.git
Тонкая настройка Gitea: регистрация, приватность, LFS
Рекомендую отключить саморегистрацию (DISABLE_REGISTRATION = true) и включить 2FA в политике организации. Если нужен публичный просмотр без логина — REQUIRE_SIGNIN_VIEW = false. Для Git LFS проверьте путь к хранилищу и свободное место.
Если Gitea — внутренняя система, задайте политику паролей (MIN_PASSWORD_LENGTH, PASSWORD_COMPLEXITY) и корректно настройте почту для уведомлений и reset паролей. В продакшене COOKIE_SECURE = true обязателен.
Производительность обратного прокси Nginx
Git‑операции могут держать соединения минутами, поэтому увеличены таймауты прокси. Для крупных репозиториев можно поднять proxy_max_temp_file_size или отключить буферизацию на отдельных локациях. Сжимать Git‑пакеты не нужно, но HTML/JSON интерфейса разумно отдавать с gzip/brotli, если это в политике компании. Для нестабильных клиентов проверьте keepalive_timeout и сетевые sysctl.
Резервное копирование: gitea dump и systemd‑таймер
Gitea умеет собирать единый архив, включающий репозитории, вложения, LFS и базу данных (включая SQLite). Это простой способ ежедневного бэкапа.
# Каталог для бэкапов
sudo mkdir -p /var/backups/gitea
sudo chown git:git /var/backups/gitea
# Скрипт бэкапа
sudo tee /usr/local/bin/gitea-backup > /dev/null << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
TS=$(date +%Y%m%d-%H%M%S)
OUT=/var/backups/gitea/gitea-$TS.tar.gz
/usr/local/bin/gitea dump --config /etc/gitea/app.ini --file $OUT --skip-attachments=false --skip-lfs=false
find /var/backups/gitea -type f -mtime +14 -name 'gitea-*.tar.gz' -delete
EOF
sudo chmod 750 /usr/local/bin/gitea-backup
sudo chown root:root /usr/local/bin/gitea-backup
# Юнит и таймер
sudo tee /etc/systemd/system/gitea-backup.service > /dev/null << 'EOF'
[Unit]
Description=Gitea backup
[Service]
Type=oneshot
User=git
Group=git
ExecStart=/usr/local/bin/gitea-backup
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=full
ReadWritePaths=/var/backups/gitea
EOF
sudo tee /etc/systemd/system/gitea-backup.timer > /dev/null << 'EOF'
[Unit]
Description=Daily Gitea backup
[Timer]
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now gitea-backup.timer
sudo systemctl list-timers | grep gitea-backup
Храните резервные копии вне того же диска VDS (объектное хранилище, отдельный сервер). Регулярно выполняйте пробные восстановление на тестовом инстансе — это единственный способ убедиться, что бэкапы рабочие.

Обновления Gitea
Обновление бинарной установки — это скачивание нового файла, замена и перезапуск сервиса. Перед обновлением сделайте бэкап.
GITEA_VERSION=1.22.4
sudo systemctl stop gitea
sudo curl -fL -o /usr/local/bin/gitea.new https://dl.gitea.com/gitea/${GITEA_VERSION}/gitea-${GITEA_VERSION}-linux-amd64
sudo mv /usr/local/bin/gitea.new /usr/local/bin/gitea
sudo chmod 755 /usr/local/bin/gitea
sudo chown root:root /usr/local/bin/gitea
sudo systemctl start gitea
sudo journalctl -u gitea -n 100 --no-pager
Диагностика типовых проблем
Нет HTTPS: проверьте DNS, файрвол и валидность сертификата. nginx -t должен проходить без ошибок, а systemctl status nginx — быть активным. 502 — чаще падение Gitea: смотрим journalctl -u gitea, права /var/lib/gitea и пользователя git.
Не работает SSH: проверьте путь в AuthorizedKeysCommand, доступ пользователя git к /etc/gitea/app.ini и журналы journalctl -u ssh. При строгих политиках возможно потребуются правила SELinux/AppArmor.
Медленный clone по HTTPS: увеличьте proxy_read_timeout/proxy_send_timeout, оцените пропускную способность диска и сетевые sysctl; для больших аплоадов помогает proxy_request_buffering off.
Рекомендации по безопасности
- Отключите саморегистрацию и включите 2FA на уровне организации.
- Ограничьте роли: доступ к админке только группе доверенных пользователей.
- Добавьте базовые заголовки в Nginx: CSP, X‑Frame‑Options, X‑Content‑Type‑Options.
- Регулярно обновляйте Gitea и системные пакеты; при необходимости включите unattended‑upgrades.
- Следите за журналами:
journalctl -u gitea, логи Nginx и активность SSH. Для управления секретами в инфраструктуре посмотрите практику с sops + age.
Итоги
Мы развернули Gitea на VDS с аккуратной архитектурой: приложение слушает localhost, снаружи — Nginx с TLS, а управление выполнением — через systemd. Добавили SSH для git, настроили резервные копии и обсудили тонкости производительности и безопасности. Дальше можно подключить PostgreSQL, e‑mail‑уведомления, веб‑хуки и мониторинг. Если требуется домен или сертификаты, используйте регистрация доменов и SSL-сертификаты.


