Только обнаружил, что уже год Forgejo поддерживает экшены на подобии Github Actions для автоматического запуска ci/cd пайплайнов. Пайплайны по синтаксису совместимы с Github и поддерживают готовые Github экшены https://github.com/marketplace?type=actions.

У меня изначально ci/cd был реализован на Forgejo + Drone, потом Drone был заменен на Woodpecker (форк Drone), ну а затем собственно увидел, что появился встроенный механизм и перешел на него.

Для работы экшен модуль должен быть включен в конфиге Forgejo:

[actions]
ENABLED = true
DEFAULT_ACTIONS_URL = github
ZOMBIE_TASK_TIMEOUT = 10m
ENDLESS_TASK_TIMEOUT = 3h
ABANDONED_JOB_TIMEOUT = 24h
SKIP_WORKFLOW_STRINGS = [skip ci],[ci skip],[no ci],[skip actions],[actions skip]

Так же как в Github за работу экшен отвечают ранеры, которые могут быть запущены как обычные приложения, либо в Docker-контейнере. Во втором случае в контейнер монтируют docker.sock хоста для запуска ранером контейнеров с задачами. Всё это прекрасно работало пока не решил отказаться от Docker и перейти на Podman.

Зачем? У Podman есть несколько плюсов:

  • нет демона который работает с правами root
  • контейнеры могут запускать непривилегированные пользователи в rootless режиме
  • пользователи хоста не видят контейнеры друг друга
  • интеграция с systemd и selinux
  • совместим с кубером

Из-за того, что контейнеры rootless - могут быть особенности с настройкой прав и доступом к ресурасам по сравнению с Docker. Так же у меня не получилось портировать docker-compose файл, podman-compose похоже больше мёртв чем жив, но для каких-то случаев его может хватить.

Еще мне надо чтобы в контейнерах которые запускаются для выполнения задачь тоже был docker.sock для сборки и загрузки контейнеров в приватный реестр.

Long story short

Для работы podman-сокета под пользователем включаем его:

systemctl --user enable podman.socket

Используем Quadlet который упрощает запуск контейнеров с помощью systemd и делает unit файлы проще.

Создаем модуль для запуска контейнера $HOME/.config/containers/systemd/forge-runner.container

[Unit]
Description=Forgejo Runner
After=local-fs.target

[Container]
ContainerName=forge-runner
Image=code.forgejo.org/forgejo/runner:3.4.1
User=1001
Group=1001
UserNS=keep-id
Volume=/home/runner/data:/data:z
Volume=/run/user/1001/podman/podman.sock:/run/user/1001/podman/podman.sock:z
Exec=forgejo-runner --config config.yaml daemon

Перезагружаем демон systemd

systemctl --user daemon-reload

В конфиге ранера config.yaml в секции [container] указываем

options: "--security-opt label=disable"
docker_host: "unix:///var/run/user/1001/podman/podman.sock"

Запускаем ранер:

systemctl --user start forge-runner

Посмотреть логи

journalctl --user -u forge-runner -f

В итоге в контейнере самого ранера сокет подмана доступен в /var/run/user/1001/podman/podman.sock, а при запуске контейнеров с задачами ранер монтирует его в них в /var/run/docker.sock.

После настройки можно сделать workflow типа такого в .forgejo/workflows/build.yaml

name: Build and Push

on:
  push:
    tags:
      - "*"

jobs:
  build:
    runs-on: ubuntu-latest
    container:
      image: catthehacker/ubuntu:act-latest
    steps:
      - name: Checkout submodule
        uses: actions/checkout@v4
        with:
          submodules: true
          token: ${{ secrets.GIT_SECRET }}

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          registry: code.coyotle.ru
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_SECRET }}

      - name: Build and Push image
        uses: build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            code.coyotle.ru/${{ github.repository }}:${{ github.ref_name }}            

После пуша тэга