Автономный CI/CD конвейер на мобильной платформе — это практичная задача: вы можете собирать и тестировать проекты буквально «в поле», не полагаясь на внешний сервер. В этом материале я, Денис Евгеньевич Усачёв (ведущий эксперт РыбинскЛАБ), покажу, как построить полностью автономный контур в Termux с GitLab Runner и Docker‑in‑Docker (DinD). Результат — runner, который регистрируется в вашем GitLab и выполняет пайплайны внутри контейнеров.
Важно: вы должны соблюдать актуальное законодательство РФ и правила вашей инфраструктуры. Подключения и сетевые настройки рассматриваются в рамках легального администрирования (в т.ч. локальная сеть при необходимости).
Архитектура решения
Схема проста:
- Termux на Android выступает как хост для раннера.
- GitLab Runner выполняет job’ы по конфигурации вашей GitLab-стороны.
- Docker-in-Docker поднимает Docker-демон внутри среды раннера, чтобы сборки выполнялись в контейнерах.
- Пайплайн в .gitlab-ci.yml использует образа и запускает сборку/тесты в Docker.
Ключевой момент: на Android Docker напрямую может быть ограничен, поэтому мы используем подход, который обычно реализуется через контейнеризацию «в контейнере» (DinD) и корректную подачу переменных окружения и ресурсов.
Предварительные условия
- Устройство Android с Termux.
- Доступ к вашему GitLab (cloud или self-hosted).
- Токен проекта/группы для регистрации GitLab Runner.
- Понимание, что CI внутри мобильного устройства будет ограничен CPU/RAM и сетью.
Рекомендуется подготовить USB-отладку/настройки Termux и обеспечить стабильность питания (иначе сборки могут быть прерваны).
Установка базовых пакетов в Termux
Начнём с обновления репозиториев и базовых утилит.
pkg update -y
pkg upgrade -y
pkg install -y git curl wget jq ca-certificates gnupg tar unzip
Установка Docker (для DinD) в Termux
В мире Termux/Android нет единого универсального «Docker из коробки» для всех устройств и версий Android, но рабочий путь — использовать DinD: запускаем контейнерный Docker-демон внутри контейнеров/сред, а затем в пайплайнах используем клиент Docker.
На практике чаще всего используется схема с пакетом proot-distro или специальными сборками Docker-окружения. Ниже приведён сценарий, который ориентирован на типовой подход: устанавливаем инструмент для контейнерного окружения и подготавливаем место под Docker.
pkg install -y proot-distro
proot-distro install ubuntu
proot-distro login ubuntu -- apt-get update
Далее, уже внутри Ubuntu, установим зависимости. Откройте shell внутри proot-среды:
proot-distro login ubuntu
Внутри Ubuntu выполните:
apt-get install -y docker.io ca-certificates curl
Если ваша среда или ядро Android ограничивают запуск демона, то вместо прямого запуска демона на хосте вы будете запускать Docker внутри контейнерного контекста (DinD) средствами привилегированного контейнера. Для этого в GitLab job’ах используйте privileged: true и подходящий образ для Docker-in-Docker.
Подготовьте также директорию под data:
mkdir -p /var/lib/docker
chmod 777 /var/lib/docker
Установка GitLab Runner в Termux
Ставим GitLab Runner. Для надёжности скачиваем бинарник актуальной версии для вашей архитектуры (в Termux обычно используется arm64/arm). Узнать архитектуру можно командой uname -m.
uname -m
Далее скачайте runner с официального GitLab Releases. В качестве примера ниже используем общий шаблон; замените версию при необходимости.
export RUNNER_VERSION="17.3.0"
curl -L -o gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/v${RUNNER_VERSION}/binaries/gitlab-runner-linux-arm64
chmod +x gitlab-runner
mv gitlab-runner ~/../usr/bin/gitlab-runner 2>/dev/null || mv gitlab-runner $HOME/gitlab-runner
hash -r
Проверим:
$HOME/gitlab-runner --version || gitlab-runner --version
Регистрация runner в GitLab
Создаём конфигурацию runner:
mkdir -p $HOME/gitlab-runner/config
mkdir -p $HOME/gitlab-runner/state
Регистрация выполняется интерактивно командой gitlab-runner register. Введите URL вашего GitLab, токен и описание.
cd $HOME
gitlab-runner register --config $HOME/gitlab-runner/config/config.toml
В ответ на вопросы укажите:
- GitLab instance URL — ваш URL GitLab, например
https://gitlab.example.com. - Registration token — токен проекта/группы.
- Description — например
termux-ruby-lab-runner. - Tags — например
termux,dind. - Executor — чаще всего используйте
docker, чтобы job’ы могли запускать контейнеры. Однако в DinD сценариях вы также можете использоватьshellилиdocker+machineв зависимости от доступности docker engine в окружении. - Default image — например образ для базовых операций (может быть пустым).
Если интерактивный режим неудобен, возможна регистрация через неинтерактивные параметры (но это зависит от версии runner).
Настройка конфигурации runner (config.toml)
Откройте файл конфигурации:
cat $HOME/gitlab-runner/config/config.toml
Нам важно обеспечить:
- Логи и директории.
- Адекватные лимиты по времени выполнения.
- Теги, чтобы пайплайны адресно попадали на этот runner.
Пример фрагмента (ориентир):
concurrent = 1
check_interval = 0
[[runners]]
name = "termux-dind-runner"
url = "https://gitlab.example.com/"
token = "REPLACE_ME"
executor = "docker"
[runners.docker]
tls_verify = false
image = "alpine:3.20"
privileged = true
volumes = ["/var/run/docker.sock:/var/run/docker.sock"]
Если в вашем DinD варианте нет доступа к /var/run/docker.sock снаружи, то лучше использовать privileged в самих job’ах и запускать Docker daemon через образ docker:dind.
Запуск GitLab Runner в Termux
Запускать runner можно в текущей сессии:
gitlab-runner run --config $HOME/gitlab-runner/config/config.toml
Чтобы runner работал после перезапуска Termux, можно настроить запуск через системные возможности Termux (например, через termux:boot или аналогичный механизм). Конкретная реализация зависит от политики вашего Termux-окружения.
Для базовой автоподгрузки команд можно поставить поддержку загрузки (по желанию):
pkg install -y termux-api
Дальше создайте автозапуск через возможности Termux (или менеджер задач Android). Я намеренно не привязываюсь к конкретному способу, чтобы не конфликтовать с настройками безопасности вашего устройства.
Настройка .gitlab-ci.yml под Docker-in-Docker
Теперь создадим pipeline. В этом примере пайплайн использует образ docker:latest и сервис docker:dind. Runner должен выполнять job в режиме, позволяющем запуск privileged-контейнера.
Пример .gitlab-ci.yml:
stages:
- test
- build
variables:
DOCKER_HOST: "tcp://docker:2375"
DOCKER_TLS_CERTDIR: ""
test:
stage: test
tags: ["termux","dind"]
image: docker:27
services:
- name: docker:27-dind
alias: docker
variables:
DOCKER_DRIVER: "overlay2"
script:
- docker info
- docker version
- echo "Run tests here"
build:
stage: build
tags: ["termux","dind"]
image: docker:27
services:
- name: docker:27-dind
alias: docker
script:
- docker build -t myapp:ci .
- echo "Build completed"
artifacts:
when: on_failure
paths:
- Dockerfile
Если ваш проект требует зависимости языка (например, Node, Python, Java), вы можете использовать официальный образ соответствующего языка, а Docker — только для этапа сборки образа (или наоборот). В DinD логика остаётся: docker:dind как сервис и установка переменных DOCKER_HOST.
Сетевые аспекты и локальная связность
В большинстве случаев runner просто инициирует исходящие подключения к вашему GitLab по HTTPS. Если же вам нужна локальная инфраструктура (например, внутренний GitLab или внутренний registry), используйте VPN исключительно для создания локальной сети между устройствами/узлами, а не для обхода блокировок. Типовой подход — поднять локальный туннель и обеспечить резолвинг имён.
Нежелательно открывать лишние порты. Держите доступ только к необходимым эндпоинтам GitLab, Container Registry и артефакт-хранилищу.
Безопасность: что важно не упустить
- Минимизируйте привилегии: используйте
privileged: trueтолько там, где это действительно нужно для DinD. - Не храните секреты в репозитории: используйте переменные GitLab CI/CD (Settings > CI/CD > Variables).
- Ограничьте теги: чтобы только ваши job’ы попадали на мобильный runner.
- Лимитируйте время: чтобы зависшие сборки не «съедали» батарею и ресурсы.
При необходимости включите аудит команд/логов в GitLab.
Troubleshooting: частые проблемы
- Runner не берёт job’ы: проверьте теги в GitLab UI и совпадение в
.gitlab-ci.yml. - Docker в DinD не запускается: убедитесь, что job выполняется с подходящими правами (privileged) и что переменные
DOCKER_HOST/DOCKER_TLS_CERTDIRкорректны. - Нехватка ресурсов: уменьшайте параллелизм, используйте более лёгкие базовые образы, сократите объём артефактов.
- Проблемы с DNS: проверьте доступность GitLab домена и registry; при необходимости используйте корректный resolv.conf в окружении.
Практический сценарий: как начать быстро
- Подготовьте runner, зарегистрируйте его в GitLab и убедитесь, что он «онлайн».
- Создайте тестовый pipeline с DinD и командой
docker info. - Добавьте сборку вашего проекта в контейнере.
- Проверьте логи job’ов и при необходимости настройте лимиты/таймауты.
Заключение
Мы собрали рабочий подход к созданию полностью автономного CI/CD конвейера в Termux с GitLab Runner и Docker‑in‑Docker. Такой сетап помогает запускать сборки и тесты в мобильных условиях, сохраняя управляемость через GitLab и гибкость контейнерного окружения.
Если захотите, в РыбинскЛАБ поможем: подберём конфигурацию под ваш Android/архитектуру, настроим runner, DinD и pipeline под ваши типы проектов, а также обеспечим безопасную эксплуатацию. Обращайтесь — сделаем CI/CD устойчивым и удобным.