Всем привет!

В данном туториале я расскажу вам как можно задеплоить gitea на своём железе с использованием docker-compose подключить drone, для возможности автоматизации тестирования и доставки собственных приложений, настроить reverse-proxy через nginx для доступа через сеть и включить portainer для мониторинга запущенных контейнеров.

Шаг 1 - проверяем наличие необходимых программ

Для запуска полного стека нам будет необходим следующий софт:

  • docker - стоит v20.10.21, хотя версии больше 18 должны подойти;

  • docker-compose - главное что бы поддерживался compose v3, у меня стоит 2.12.2;

  • go - golang v1.19.3+ будет использоваться для получения сертификатов через lego, тем кто не планирует размещение сайта данный пункт можно пропустить.

Инструкций по установке в зависимости от системы более чем достаточно, установка не должна быть сложной. Для проверки, что всё в норме можно запустить данный скрипт:

go version;docker version;docker compose version

Скрипт должен показать установленные версии программ.

Шаг 2 - запускаем локальный инстанс gitea

Минимальный compose для запуска локального инстанса выглядит следующим образом:

services:
  gitea:
    image: gitea/gitea:1.17.3
    container_name: gitea
    restart: unless-stopped
    environment:
      USER_UID: 1000
      USER_GID: 1000
      GITEA__server__APP_DATA_PATH: /data/gitea
      GITEA__server__DOMAIN: localhost
      GITEA__server__HTTP_PORT: 80
      GITEA__server__ROOT_URL: http://localhost/
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 80:80

Создаем рабочую директорию, в ней файл docker-compose.yml и добавляем туда следующее содержимое. После запускаем команду docker compose up.

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

Параметры менять не обязательно, можно оставить всё как есть и запустить локальную копию. После небольшого ожидания мы должны увидеть локальную версию gitea, уже готовую к использованию.

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

  • DEFAULT_USER_IS_RESTRICTED (service) - позволяет ограничить в правах новых пользователей (не могут просматривать контент и выполнять никакие действия), подойдет для закрытых команд;

  • MAX_CREATION_LIMIT (repository) - пользователи могут просматривать репозитории и создавать issue, но ограниченны определенным количеством в создании собственных;

  • PROTOCOL (server) - будет ли использоваться http или https, если планируется выносить сайт в сеть, то строго рекомендуется использовать https или настроить https после через nginx;

  • DOMAIN (server) - название домена сервера, которое в случае использование поддомена должно так же включать и его sub.example.pw;

  • ROOT_URL (server) - должен совпадать с используемой ссылкой и включать http:// или https://.

Полный список настроек есть на официальном сайте.

Так же есть много различных опций по настройке тем, плагинов и других плюшек.

Шаг 3 - подключаем drone-ci

Далее можно подключить к gitea дрона, что бы автоматизировать процесс тестирования и анализа кода:

Дрон подключается к gitea как сторонее приложение и требует предоставления ему соответствующих прав, через графу настройки -> приложения:

Там нужно указать название приложения и его адрес для перехода по ссылке в формате:

И после создать кнопку создать приложение, сохраненные secret/ client_id сохранить для compose. Далее необходимо сгенерировать токен в этой же вкладке, опять же для compose.

Теперь добавим дрон в сам с полученными параметрами docker-compose:

services:
  gitea:
    image: gitea/gitea:1.17.3
    container_name: gitea
    restart: unless-stopped
    environment:
      USER_UID: 1000
      USER_GID: 1000
      GITEA__server__APP_DATA_PATH: /data/gitea
      GITEA__server__DOMAIN: localhost
      GITEA__server__HTTP_PORT: 80
      GITEA__server__ROOT_URL: http://localhost/
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 80:80

  drone:
    image: drone/drone:2.15
    container_name: drone
    restart: unless-stopped
    environment:
      DRONE_DATABASE_DRIVER: sqlite3
      DRONE_DATABASE_DATASOURCE: /data/database.sqlite
      DRONE_GITEA_SERVER: http://localhost/
      DRONE_GIT_ALWAYS_AUTH: false
      DRONE_RPC_SECRET: very-secret
      DRONE_SERVER_PROTO: http
      DRONE_SERVER_HOST: localhost:81
      DRONE_TLS_AUTOCERT: false
      DRONE_USER_CREATE: username:dancheg97,machine:false,admin:true,token:55f24eb3d61ef6ac5e83d550178638dc
      DRONE_GITEA_CLIENT_ID: 1445cb69-6bf9-4803-beec-f914477b8053
      DRONE_GITEA_CLIENT_SECRET: gto_2rybvjtwcmcbd2k2k3exm5sguipdb6xjngv5n5jfjdszg6onwyva
    volumes:
      - ./drone:/data
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - 81:80
    depends_on:
      - gitea

  drone-runner:
    image: drone/drone-runner-docker:1.8.2
    container_name: droner
    restart: unless-stopped
    environment:
      DRONE_RPC_PROTO: http
      DRONE_RPC_HOST: drone
      DRONE_RPC_SECRET: very-secret
      DRONE_RUNNER_NAME: drone-runner
      DRONE_RUNNER_CAPACITY: 2
      DRONE_RUNNER_NETWORKS: habrz_default
      DRONE_DEBUG: false
      DRONE_TRACE: false
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - drone

Полученный токен идет в env DRONE_USER_CREATE, после token. Запускаем compose и подключаем drone.

Если запутались в процессе настройки, то тут официальная дока.

Авторизуем приложение и можем настроить дрон. В данный момент drone может начать выдавать ошибку:

  • invalid character '<' looking for beginning of value

Не стоит из-за этого сильно переживать, тк после настройки nginx данная проблема быстро решается.

Шаг 4 - перенаправляем трафик на наш ip адрес, при необходимости настраиваем маршрутизатор.

Сейчас наша задача - перенаправить весь входящий трафик на нашу железку, что бы при переходе по ссылке можно было всегда попадать в одно место.

Как правило данное действие состоит из двух этапов, во-первых - перенаправляем DNS записи у предоставителя нашего домена (на fozzy это выглядит так, сильных отличий в других местах быть не должно, интерфейс будет однообразен):

Для каждого поддомена рекомендуется создать отдельную запись.

Далее необходимо перенаправить трафик в роутере в локальной сети (в случае с использованием виртуалки достаточно просто открыть порты).

На моём роутере это выглядит примерно так:

Шаг 5 - настраиваем nginx

Теперь когда у нас уже есть gitea и drone, можно приступить к настройке nginx:

  nginx:
    image: nginx:1.23-alpine
    container_name: nginx
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro
      - ./.lego/certificates:/certs:ro
      - ./web:/web:ro
    depends_on:
      - gitea
      - drone

Добавляем следующие строки в уже написанный docker-compose. Так мы добавим nginx к существующим сервисам, но сначала нам нужно прописать конфиг для nginx.

Я буду писать его в файле - nginx/nginx.conf (и потом маунтить его в докер).

Он будет включать 2 пункта - в зависимости от поддомена (которые вы можете задать как хотите) будет перенаправлять трафик на запущенные контейнеры:

server {
    listen 80;
    listen 443 ssl;
    server_name gitea.dancheg97.ru;
    ssl_certificate /certs/gitea.example.pw.crt;
    ssl_certificate_key /certs/gitea.example.pw.key;
    location / {
        proxy_pass http://gitea/;
    }
}

server {
    listen 80;
    listen 443 ssl;
    server_name drone.dancheg97.ru;
    ssl_certificate /certs/drone.example.pw.crt;
    ssl_certificate_key /certs/drone.example.pw.key;
    location / {
        proxy_pass http://drone/;
    }
}

Теперь мы установим cli-утилиту которая называется lego и получим бесплатные сертификаты запустив данный скрипт в нашей директории с docker-compose.yml файлом.

go install github.com/go-acme/lego/v4/cmd/lego@latest
sudo lego --email="mail@gmail.com" --domains="gitea.example.pw" --http run
sudo lego --email="mail@gmail.com" --domains="drone.example.pw" --http run
sudo chown -R dancheg97:dancheg97 .lego

при этом певая строка - установка сертбота, последняя - предоставление доступа к сертам всем пользователям на устройстве (замените имя на своего пользователя).

Далее мы можем запускать nginx вместе с остальными контейнерами.

Шаг 6 - Подключаем portainer

Теперь мы можем опционально подключить портейнер (не всем это нужно, даже без него у нас есть рабочая конфигурация).

Далее этого добавим в compose еще 1 сервис:

  portainer:
    image: portainer/portainer-ce:2.0.0
    container_name: portainer
    command: -H unix:///var/run/docker.sock
    restart: always
    environment:
      - VIRTUAL_HOST=portainer.example.pw
      - VIRTUAL_PORT=9000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./portainer:/data

И выполним похожие действия по настройке домена/серта/nginx-a.

Настроенный портейнер позволит мониторить состояние остальных сервисов:

Данный сетап позволяет полностью уйти от использования внешних систем контроля версий (в моём случае - github) и оставлять все свои данные на собственных носителях. Настройка требует времени, но появляются следующие плюшки:

  • Полностью open-source + self-hosted стек.

  • Полный контроль за всеми данными в системе, отсутствие облаков и третьих лиц.

  • Удобный drone-ci для автоматизации операций с контейнерами.

  • Возможность моментальной автоматической выкладки в сеть верифицированного контента.

При наличии свободной железки (старый ноут или raspberry), система будет обходится примерно в 200Р в месяц в зависимости от стоимости домена/статического ip адреса у провайдера.

Мой собственный инстанс после настройки тем и других докрутов выглядит примерно так:

https://gitea.dancheg97.ru/

Моя версия docker-compose.yml (многое докрутил под себя):

services:
  nginx:
    image: nginx:1.23-alpine
    container_name: nginx
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/nginx.conf:ro
      - ./.lego/certificates:/certs:ro
      - ./web:/web:ro
    depends_on:
      - gitea
      - drone

  gitea:
    image: gitea/gitea:1.17.3
    container_name: gitea
    restart: unless-stopped
    environment:
      USER_UID: 1000
      USER_GID: 1000
      GITEA__server__APP_DATA_PATH: /data/gitea
      GITEA__server__DOMAIN: gitea.dancheg97.ru
      GITEA__server__SSH_DOMAIN: gitea.dancheg97.ru
      GITEA__server__HTTP_PORT: 80
      GITEA__server__ROOT_URL: https://gitea.dancheg97.ru/
      GITEA__server__DISABLE_SSH: false
      GITEA__server__SSH_PORT: 22
      GITEA__server__SSH_LISTEN_PORT: 22
      GITEA__server__LFS_START_SERVER: true
      GITEA__server__LFS_JWT_SECRET: xxx
      GITEA__server__OFFLINE_MODE: false
      GITEA__ui__THEMES: gitea,arc-green,plex,aquamarine,dark,dracula,hotline,organizr,space-gray,hotpink,onedark,overseerr,nord,earl-grey
      GITEA__ui__DEFAULT_THEME: earl-grey
      GITEA__service_DISABLE_REGISTRATION: false
      GITEA__service_REQUIRE_SIGNIN_VIEW: false
      GITEA__service_REGISTER_EMAIL_CONFIRM: false
      GITEA__service_ENABLE_NOTIFY_MAIL: false
      GITEA__service_ALLOW_ONLY_EXTERNAL_REGISTRATION: false
      GITEA__service_ENABLE_CAPTCHA: false
      GITEA__service_DEFAULT_KEEP_EMAIL_PRIVATE: false
      GITEA__service_DEFAULT_ALLOW_CREATE_ORGANIZATION: true
      GITEA__service_DEFAULT_ENABLE_TIMETRACKING: true
      GITEA__service_NO_REPLY_ADDRESS: noreply.localhost
      GITEA__service_DEFAULT_USER_IS_RESTRICTED: true
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro

  drone:
    image: drone/drone:2.15
    container_name: drone
    restart: unless-stopped
    environment:
      DRONE_DATABASE_DRIVER: sqlite3
      DRONE_DATABASE_DATASOURCE: /data/database.sqlite
      DRONE_GITEA_SERVER: https://gitea.dancheg97.ru/
      DRONE_GIT_ALWAYS_AUTH: false
      DRONE_RPC_SECRET: xxx
      DRONE_SERVER_PROTO: https
      DRONE_SERVER_HOST: drone.dancheg97.ru
      DRONE_TLS_AUTOCERT: false
      DRONE_USER_CREATE: xxx
      DRONE_GITEA_CLIENT_ID: xxx
      DRONE_GITEA_CLIENT_SECRET: xxx
    volumes:
      - ./drone:/data
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - gitea

  drone-runner:
    image: drone/drone-runner-docker:1.8.2
    container_name: droner
    restart: unless-stopped
    environment:
      DRONE_RPC_PROTO: http
      DRONE_RPC_HOST: drone
      DRONE_RPC_SECRET: xxx
      DRONE_RUNNER_NAME: drone-runner
      DRONE_RUNNER_CAPACITY: 2
      DRONE_RUNNER_NETWORKS: composer_default
      DRONE_DEBUG: false
      DRONE_TRACE: false
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - drone

При наличии вопросов в настройке прошу обращаться: tlg @dancheg97

Комментарии (16)


  1. tdemin
    05.12.2022 00:48
    +1

    А чего не Woodpecker (форк Drone CI 0.8.x до коммерциализации)? Drone давно перестал быть опенсорсом, с гитхаба так и старые исходники вытерли.

    Его успешно использует Codeberg (большой инстанс Gogs).


    1. dancheg Автор
      05.12.2022 01:00

      Спасибо, попробую адаптировать под woodpecker


    1. crackedmind
      05.12.2022 05:31
      +2

      Не вытерли, а переложили

      https://github.com/harness/drone


  1. TheKnight
    05.12.2022 02:02
    +1

    Gitlab CE рассматривали в качестве альтернативы? Если да - то почему не остановились на нем?


    1. Landgraph
      05.12.2022 07:32

      Тоже интересно. Буквально на днях выбирал что-нибудь для self-hosted. Остановился также на Gitea. Но мне скорее нужен был банальный менеджер репозиториев, я проще ничего не нашёл. Хотя и для небольших команд выглядит очень даже приемлемо. CI/CD ещё не прикручивал.

      А гитлаб какой-то слишком мудрёный. Возможно, это лучшая альтернатива в долгосрок если вкладываться.


    1. crackedmind
      05.12.2022 07:43

      Требования Gitlab:

      • 4 cores is the recommended minimum number of cores and supports up to 500 users

      • 4GB RAM is the required minimum memory size and supports up to 500 users

      Требования Gitea:

      • 2 CPU cores and 1GB RAM is typically sufficient for small teams/projects.

      Так что гитеа можно спокойно запустить на дешевом vps или вообще одноплатнике.


      1. screwer
        05.12.2022 16:53

        Сам git кушает вполне прилично ресурсов. Конечно, это от размера репозиториев зависит. Я видел цифры в 60-70Gb отожранной гитом памяти, на задачах клонирования/пуша. Но у меня и некоторые репозитории реально огромные.


    1. dancheg Автор
      05.12.2022 08:34

      Добрый!

      На работе использую гитлаб, и если сравнивать с гити, то есть следующие плюсы:

      • интегрированный CI/CD, это часто удобнее

      • более популярная платформа, бизнес чаще выбирает гитлаб

      Из плюсов гити:

      • работает быстрее, не провисает практически совсем (от части тк написана на го, а гитлаб на рубях)

      • Очень не требовательна к мощностям (весь описанный в статье стек крутится на селероне с 4-я ядрами)

      • Больше инструментов для миграции с других сервисов

      Стоит пробовать обе системы, у меня больше душа лежит к гити, тк большая часть стека - инструменты на С и go, не хочется сильно разбавлять.


      1. ckpunT
        05.12.2022 18:56
        +1

        github тоже частично на рубях писан и работает вполне быстро. Он как и gitlab под капотом использует libgit2. Gitea и Gogs по сути обертки для си-шного бинаря git.

        не провисает практически совсем

        Попробуйте поиграться с репой Kubernetes. У Gitea и Gogs нет кэширования истории коммитов, потому они на больших репах, с длинной историей, будут сильно проигрывать по производительности Gitlab-у, но будут значительно быстрее Gitflic))


        1. dancheg Автор
          05.12.2022 21:18

          На четырехядерном минипк (старый селерон), репу куба получилось отгрузить ~ за 7 минут, в интерфейсе (комиты, бранчи, таги, изменения, тд) никаких лагов не заметил.

          Хотел по возможности уточнить в каком месте интерфейс должен провисать? Постараюсь проверить.


          1. ckpunT
            06.12.2022 08:43

            Беру свои слова назад, оказывается уже давно добавили кэширование. На каталогах cluster и third_party первое чтение чуть больше секунды (mac mini i7 2012), остальные 60 мс. Как раз последний раз смотрел Gitea не за долго до этого коммита и там было сильно печально.


  1. velon
    05.12.2022 07:18
    +2

    Gitea - git with a cup of tea. Мммм, чашка чая - то чего не хватает любому проекту.

    Мы Gogs используем, но, возможно, ради чашки чая, посмотрим на Gitea. На википедии пишут что это форк гогса, наврно проблем с миграцией не будет.


    1. dancheg Автор
      05.12.2022 08:35

      Да, в описании есть примеры как безболезненно мигрировать с gogs


  1. LeKovr
    05.12.2022 10:45
    +1

    Для reverse-proxy и сертификатов с динамическим добавлением хостов можно посмотреть на Traefik. Рабочий пример, где все это собрано вместе - dcape


  1. ShefEr
    05.12.2022 23:29

    Не хватает описания настройки доступа к gitea по ssh.

    Upd: А нет, вижу.


  1. subvillion
    06.12.2022 22:08

    А для чего тут swarm?