CI/CD в мобильной среде давно перестал быть экзотикой: Termux позволяет воспроизводимо собирать артефакты, формировать Docker‑образы, готовить релизы и запускать сборочные шаги на удалённых инфраструктурах. В этой статье показано, как построить «облачный» CI/CD‑pipeline, где Termux выступает как рабочая среда для подготовки контейнеров и конфигураций, а основная сборка/исполнение управляется GitLab и Kubernetes.
Архитектура решения
Мы предлагаем следующую схему:
- Termux — формирование Dockerfile, тестовых артефактов, генерация/подготовка конфигураций и запуск локальных команд подготовки (например, lint/build) при необходимости.
- GitLab — CI/CD оркестрация: определяем
.gitlab-ci.yml, используем переменные окружения и сохраняем секреты в GitLab Variables. - GitLab‑Runner — исполняет job’ы в изолированной среде (чаще всего в Kubernetes). Runner регистрируется в GitLab и получает доступ к namespace и секретам.
- Kubernetes — целевой кластер для деплоя. Мы используем
kubectlили Helm (по ситуации) и применяем манифесты/чарты.
Ключевая идея: Termux не заменяет CI‑сервер, а помогает готовить воспроизводимый build и инфраструктурные артефакты. Реальный пайплайн выполняется там, где есть ресурсы и права — в GitLab/Runners и Kubernetes.
Подготовка окружения в Termux
Начните с базовой установки пакетов и привязки к вашей задаче (пример ниже универсален для большинства сценариев).
pkg update
pkg upgrade -y
pkg install -y git curl wget tar
Далее ставим Docker‑инструменты. В Termux есть варианты работы с контейнерами: от rootless‑подходов до сборки образов «на стороне» CI. Для практичной схемы CI/CD часто достаточно собирать образ в пайплайне, а в Termux держать только Dockerfile/контекст. Тем не менее, для проверки логики локальной сборки можно использовать Docker CLI‑подходы в зависимости от вашей среды.
Рассмотрим вариант, когда Termux используется для подготовки Docker‑контекста (код, конфиги, Dockerfile), а сборка запускается в Runner’е.
Пример структуры репозитория:
.
├── Dockerfile
├── k8s
│ ├── deployment.yaml
│ └── service.yaml
└── .gitlab-ci.yml
Построение Docker‑контейнера
Создайте Dockerfile. Ниже пример для простого сервиса (подставьте ваш стек).
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Важно:
- делайте сборку воспроизводимой (фиксируйте версии зависимостей);
- минимизируйте размер образа (multi-stage при необходимости);
- не кладите секреты в Dockerfile — используйте переменные окружения и секреты на стороне CI/Kubernetes.
Конфигурации Kubernetes для деплоя
Подготовьте манифесты. Пример Deployment и Service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 2
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: "registry.example.com/app:${IMAGE_TAG}"
ports:
- containerPort: 3000
apiVersion: v1
kind: Service
metadata:
name: app
spec:
selector:
app: app
ports:
- port: 80
targetPort: 3000
type: ClusterIP
Примечание: переменная ${IMAGE_TAG} будет подставляться на этапе CI (через envsubst или Helm).
Запуск GitLab‑Runner в Kubernetes
Рекомендуемый подход — запуск Runner в вашем Kubernetes‑кластере. Это позволяет:
- изолировать job’ы по namespace;
- использовать ресурсы кластера;
- безопасно внедрять секреты (через Kubernetes Secrets/ServiceAccount).
Регистрация Runner в GitLab
В GitLab откройте раздел Settings > CI/CD > Runners и создайте Runner. Получите токен регистрации.
Далее в Kubernetes разворачиваете Runner согласно официальной методике GitLab (через Helm chart gitlab-runner или манифестами). Ниже — концептуальная схема (адаптируйте под вашу конфигурацию кластера).
# Вариант: установка через Helm (пример, без подстановки всех параметров)
helm repo add gitlab https://charts.gitlab.io/
helm repo update
helm install gitlab-runner gitlab/gitlab-runner \
--namespace ci \
--create-namespace \
--set gitlabUrl="https://gitlab.example.com/" \
--set runnerRegistrationToken="YOUR_TOKEN" \
--set runners.kubernetes.namespace="ci" \
--set runners.privileged=false
Если в вашем пайплайне нужен Docker build, есть два распространённых пути:
- Kaniko (без Docker daemon внутри pod’а);
- Docker-in-Docker (обычно требует privileged и повышает риски).
Для прод‑сценариев чаще выбирают Kaniko или buildpacks.
CI‑pipeline: сборка образа и публикация в registry
Добавьте .gitlab-ci.yml. Пример пайплайна с Kaniko и деплоем в Kubernetes.
stages:
- build
- deploy
variables:
# Registry, куда публикуем образы
REGISTRY_IMAGE: "registry.example.com/app"
build-image:
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
- export IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
- echo "IMAGE_TAG=$IMAGE_TAG"
# Создаём auth для registry (секрет лучше хранить в GitLab CI Variables)
# Предполагается, что вы завели переменную $DOCKER_CONFIG_JSON или $REGISTRY_AUTH.
- mkdir -p /kaniko/.docker
- echo "${DOCKER_CONFIG_JSON}" > /kaniko/.docker/config.json
- /kaniko/executor \
--context "${CI_PROJECT_DIR}" \
--dockerfile "${CI_PROJECT_DIR}/Dockerfile" \
--destination "${REGISTRY_IMAGE}:${IMAGE_TAG}" \
--cache=true
only:
- main
deploy-to-k8s:
stage: deploy
image:
name: bitnami/kubectl:1.30
script:
- export IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
- echo "Deploying ${REGISTRY_IMAGE}:${IMAGE_TAG}"
# kubeconfig лучше передавать через переменную/секрет GitLab.
# Например: $KUBE_CONFIG (base64 или готовый kubeconfig).
- echo "${KUBE_CONFIG}" | base64 -d > kubeconfig
- export KUBECONFIG="$(pwd)/kubeconfig"
# Подстановка тега в манифесты.
- apt-get update && apt-get install -y gettext-base || true
- export IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
- mkdir -p /tmp/k8s
- envsubst < k8s/deployment.yaml > /tmp/k8s/deployment.yaml
- cp k8s/service.yaml /tmp/k8s/service.yaml
- kubectl apply -n default -f /tmp/k8s/deployment.yaml
- kubectl apply -n default -f /tmp/k8s/service.yaml
only:
- main
Что важно настроить в GitLab Variables:
- DOCKER_CONFIG_JSON — JSON для авторизации Kaniko к вашему registry (например, Docker config JSON).
- KUBE_CONFIG — kubeconfig, который имеет права на
applyв нужном namespace. - при необходимости — переменные для выбора namespace/окружения.
Как Termux помогает в этом процессе
Termux удобен как «подготовительная лаборатория»:
- быстро править Dockerfile и проверять lint/тесты;
- готовить манифесты и шаблоны (например, окруженческие параметры для
envsubst); - собирать контекст проекта и пушить в GitLab, чтобы пайплайн сработал автоматически.
Пример простого сценария в Termux: обновить код, закоммитить и отправить.
git status
git add .
git commit -m "chore: update app"
git push origin main
После push GitLab автоматически выполнит стадии build и deploy, а Runner в Kubernetes примет задачи.
Секреты и доступы: безопасная практика
- не храните токены в репозитории;
- храните секреты в GitLab CI/CD Variables (или в External Secrets, если вы управляете ими через Kubernetes);
- выдавайте Runner только минимальные права (ServiceAccount с ограничениями);
- ограничивайте namespace и включайте RBAC.
Локальная сеть через VPN (только для внутренней связности)
Если вам нужно управлять доступом между вашим Termux и локальными компонентами разработки (например, внутренним registry или тестовым кластером), используйте VPN только для создания локальной сети, чтобы обеспечить адресацию и безопасность канала. Не используйте VPN для обхода ограничений доступа.
Заключение
Построение «облачного» CI/CD‑pipeline в Termux сводится к правильному разграничению ролей: Termux подготавливает воспроизводимый build‑контекст и конфигурации, GitLab CI оркестрирует стадии, GitLab‑Runner исполняет их в Kubernetes, а деплой выполняется в целевой кластер. Такой подход даёт повторяемость, изоляцию и управляемость при росте нагрузки.
Хотите собрать это под ваш проект (Docker‑сборка, Kaniko/Helm, RBAC в Kubernetes, настройка Runner и шаблоны .gitlab-ci.yml)? Обращайтесь в РыбинскЛАБ — мы поможем спроектировать и внедрить пайплайн под ваши требования.