В этой заметке не буду обсуждать вопрос зачем поднимать свой git-сервер, а не использовать github/gitlab/codeberg или даже sourceforge.
Как развернуть свой легкий git сервер
Начнем с того, что самый простой способ - это создать git --bare init
репозиторий на вашем сервере и написать обычные скрипты для выполнения автоматических задач. Собственно этот блог собирался скриптом который запускался в cron, делал git pull репозитория с кодом блога, а потом собирал и публиковал результат.
Из плюсов подхода - всё очень просто, из минусов - всё очень просто.
Forgejo/Gitea
Что там с github дома? Есть отличный легковесный вариант - Forgejo - форк Gitea, который форк Gogs. Очень похож по функционалу на porngithub (issue, wiki,…) с приятным внешним видом:
Установка с помощью Docker
Создаем docker-compose.yaml
:
version: "3"
networks:
gitea:
volumes:
gitea:
services:
gitea:
image: codeberg.org/forgejo/forgejo:1.18.0-1
restart: always
ports:
- "3000:3000"
- "3022:22"
networks:
- gitea
volumes:
- gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
docker-compose up -d
Остаётся опубликовать 3000 порт в nginx:
server{
listen 443 ssl;
listen [::]:443 ssl;
server_name code.example.com;
location / {
proxy_pass http://localhost:3080;
client_max_body_size 16M;
}
ssl_certificate /etc/.../code.example.com.cer;
ssl_certificate_key /etc/.../code.example.com.key;
}
Заходим в браузере на code.example.com и настраиваем Forgejo. Из коробки сервис может работать с базой sqlite, для личного использования и маленьких команд этого достаточно. Если нужна более продвинутая база - можете почитать по ссылке.
Настройка SSH Passthrough
Доступ git к сервису по ssh можно настроить несколькими способами:
- опубликовать ssh порт контейнера (в примере выше 3022)
- использовать ssh сервер хост системы.
Чтобы настроить второй способ нам необходимо:
- одинаковый пользователь git в хост-системе и в контейнере;
- общий каталог с ключами для пользователя git в обеих системах;
- возможность передавать команды из ssh-сервера хоста в контейнер.
На хосте создадим пользователя git
:
sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' \
--group --disabled-password --home /home/git git
Получаем uid и gid пользователя:
id git
uid=118(git) gid=118(git)
Исправим docker-compose.yaml
:
...
services:
gitea:
...
volumes:
- gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
# пробрасываем ключи пользователя
- /home/git/.ssh/:/data/git/.ssh
environment:
# задаём uid и gid пользователю git
- USER_UID=118
- USER_GID=118
Далее создайте пользователю git ключи и добавьте публичный в authorized_keys
. Т.к. каталог .ssh на хосте и в контейнере общий - это позволит пользователю git выполнять команды по ssh из хост системы в контейнере.
Проверить можно так:
ssh -p 3022 -i /home/git/.ssh/id_rsa git@localhost hostname
Следующий шаг, создадим скрипт который будет пробрасывать команды из ssh-сервера хоста в контейнер, сделаем его исполняемым и назначим в качестве shell пользователю git:
cat <<"EOF" | sudo tee /home/git/ssh-shell
#!/bin/sh
shift
ssh -p 3022 -o StrictHostKeyChecking=no [email protected] "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $@"
EOF
sudo chmod +x /home/git/ssh-shell
sudo usermod -s /home/git/ssh-shell git
Добавим в /etc/ssh/sshd_config
блок и перезапустим sshd:
Match User git
AuthorizedKeysCommandUser git
AuthorizedKeysCommand /usr/bin/ssh -p 3022 -o StrictHostKeyChecking=no [email protected] /usr/local/bin/gitea keys -e git -u %u -t %t -k %k
AuthorizedKeysCommand
- позволяет sshd вместо authorized_keys использовать скрипт который должен вернуть публичный ключ пользователя, например из какого-то внешнего хранилища или базы.
Получается следующая схема:
- Внешний пользователь загружает через web интерфейс свой публичный ключ в Forgejo
- Подключается к ssh-серверу хоста под пользователем git используя свой приватный ключ
- ssh сервер с помощью параметра AuthorizedKeysCommand пытается получить публичный ключ из хранилища gitea (… /usr/local/bin/gitea keys -e git -u %u …)
- Если удалось проверить ключи - в качестве оболочки для пользователя используется наш
ssh-shell
который передает ssh команды внутрь контейнера.
В документации всё это описано более подробно и есть еще несколько вариантов настройки ssh passthrough.
После всех настроек у нас должна появиться возможность работать с git по ssh:
git clone [email protected]:jonhconnor/t800.git
или в существующем репозитории
git remote add origin [email protected]:jonhconnor/t800.git