We detected you are likely not from a Russian-speaking region. Would you like to switch to the international version of the site?

  Назад к списку статей

Контейнеризация микросервисов в Termux через Podman: CI/CD‑pipeline с GitLab Runner и автоматическое масштабирование на Android‑устройствах

Termux в связке с Podman позволяет превратить Android‑устройство в удобную площадку для разработки, тестирования и развёртывания контейнерных микросервисов. В отличие от «одноразовых» команд, контейнеризация даёт повторяемость окружения: зависимости фиксируются в образе, поведение сервисов становится предсказуемым, а выпуск версий — контролируемым.

В этом материале показан практический подход к построению CI/CD‑pipeline на базе GitLab Runner и автоматизации деплоя в Termux. Отдельный акцент — на масштабирование (горизонтальное) и управляемость нескольких инстансов одного микросервиса на Android‑устройстве.

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

Архитектура решения

Типовой контур включает четыре слоя:

  • Слой разработки — репозиторий с микросервисами (Dockerfile/Containerfile, код, манифесты).
  • CI/CD слой — GitLab CI на раннере, который собирает и публикует образы.
  • Хранилище образов — registry (внутренний или облачный). Можно использовать GitLab Container Registry или приватный registry.
  • Слой исполнения на Android — Termux + Podman, где создаются и запускаются контейнеры, а также выполняется масштабирование.

Требования и подготовка Termux

1) Установите Termux и обновите пакеты:

pkg update && pkg upgrade -y

2) Установите зависимости (минимально нужно наличие контейнерного движка и утилит сборки/сети). В зависимости от версии Termux и репозиториев набор пакетов может отличаться, поэтому при практическом внедрении используйте актуальные названия пакетов:

pkg install -y podman git curl ca-certificates

3) Для комфортной работы часто добавляют runc/конфигурационные компоненты. При ошибках установки ориентируйтесь на подсказки менеджера пакетов.

4) Настройте пользователя и базовые директории проектов:

mkdir -p ~/projects ~/registry-scripts ~/manifests

Подготовка Podman в Termux

Podman в Termux обычно работает без «классического» системного сервиса. Поэтому важно корректно подготовить окружение и сетевые настройки.

Проверьте доступность Podman:

podman --version

Создайте рабочий префикс для данных (при необходимости). Пример — явная установка HOME и путей логов/контейнеров через переменные окружения:

export TMPDIR=$HOME/tmp
mkdir -p "$TMPDIR"

Если вы используете образы из приватного registry, потребуется вход:

podman login registry.example.com -u <user> -p <password>

Рекомендуемый вариант в реальном CI — передавать креды через переменные GitLab и использовать безопасные способы аутентификации, а не «жёстко» хранить секреты в файлах.

Контейнеризация микросервисов

Предположим, у вас есть сервисы service-a и service-b. Для сборки используйте Containerfile (аналог Dockerfile) — Podman поддерживает тот же подход.

Пример Containerfile для сервисов (общий шаблон):

# Containerfile
FROM alpine:3.20
RUN apk add --no-cache ca-certificates
WORKDIR /app
COPY ./dist/ ./dist/
EXPOSE 8080
CMD ["/app/dist/server"]

Соберите образ локально в Termux для проверки:

podman build -t registry.example.com/yourgroup/service-a:dev ./service-a

Запустите одиночный контейнер:

podman run --rm -p 8081:8080 --name service-a-dev registry.example.com/yourgroup/service-a:dev

На этом этапе вы валидируете образ, запуск и сетевую доступность.

Сетевая связность и «локальная сеть» для устройств

Если Android‑устройства должны взаимодействовать между собой (например, сервисы требуют сетевого взаимодействия или требуется единая точка доступа), используйте создание локальной сети внутри вашей инфраструктуры. Для этого вы можете поднимать VPN только для создания локальной сети, чтобы устройства «видели» друг друга на адресном уровне.

В рамках Podman на практике применяют:

  • Публикацию портов на устройстве (-p), если доступ одноузловой.
  • Использование пользовательских сетей Podman для изоляции и управления маршрутизацией внутри узла.

Пример создания сети для микросервисов на одном Android‑устройстве:

podman network create --driver bridge micro-net

Далее при запуске контейнеров указывайте сеть:

podman run -d --name service-a-dev --network micro-net -p 8081:8080 registry.example.com/yourgroup/service-a:dev
podman run -d --name service-b-dev --network micro-net -p 8082:8080 registry.example.com/yourgroup/service-b:dev

Внутри сети контейнеры могут обращаться друг к другу по имени контейнера (в зависимости от DNS‑поведения Podman в вашей конфигурации).

CI/CD на GitLab: сборка и публикация образов

Ниже — рабочая концепция pipeline:

  • На каждую ветку/merge request — сборка образов.
  • При теге или при merge в main — публикация «стабильных» тегов (например, latest или версионные).
  • Артефакты — только образы в registry, исходный код — в Git.

Пример .gitlab-ci.yml для сборки двух сервисов и публикации в registry:

stages:
  - build
  - push

variables:
  REGISTRY: registry.example.com
  IMAGE_A: $REGISTRY/yourgroup/service-a
  IMAGE_B: $REGISTRY/yourgroup/service-b

build_and_push:
  stage: push
  image: docker:27
  services:
    - docker:27-dind
  rules:
    - if: $CI_COMMIT_BRANCH
  before_script:
    - echo "Logging in to registry..."
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$REGISTRY"
  script:
    - docker build -t $IMAGE_A:$CI_COMMIT_SHA ./service-a
    - docker push $IMAGE_A:$CI_COMMIT_SHA
    - docker tag $IMAGE_A:$CI_COMMIT_SHA $IMAGE_A:branch-$CI_COMMIT_REF_SLUG
    - docker push $IMAGE_A:branch-$CI_COMMIT_REF_SLUG
    - docker build -t $IMAGE_B:$CI_COMMIT_SHA ./service-b
    - docker push $IMAGE_B:$CI_COMMIT_SHA
    - docker tag $IMAGE_B:$CI_COMMIT_SHA $IMAGE_B:branch-$CI_COMMIT_REF_SLUG
    - docker push $IMAGE_B:branch-$CI_COMMIT_REF_SLUG

Примечания:

  • В примере используется docker в GitLab CI. Если у вас сборка под Podman — можно адаптировать pipeline под Podman, но концепция останется прежней.
  • Теги: в продакшене лучше использовать семантическую версию или дайджест.

Деплой на Android (Termux) из GitLab

Варианты деплоя зависят от того, как вы подключаете устройства к CI. На практике используют:

  • SSH в Termux (если это допустимо вашей инфраструктурой),
  • HTTP/Webhook деплоя с агентом,
  • «pull model»: устройство само периодически забирает нужный тег и обновляет контейнеры.

Самый устойчивый подход для мобильных устройств — pull model: GitLab публикует версию в registry, а Termux‑агент берёт нужный тег по расписанию или по сигналу.

Допустим, вы реализуете простой скрипт обновления. Создайте ~/registry-scripts/deploy.sh:

#!/data/data/com.termux/files/usr/bin/bash
set -euo pipefail

REGISTRY="registry.example.com/yourgroup"
TAG="${1:-branch-main}"

NET="micro-net"

ensure_network() {
  if ! podman network inspect "$NET" >/dev/null 2>&1; then
    podman network create --driver bridge "$NET"
  fi
}

deploy_service() {
  local name="$1"
  local port="$2"

  local image="$REGISTRY/$name:$TAG"

  if podman container exists "$name"; then
    podman stop "$name" || true
    podman rm "$name" || true
  fi

  podman run -d 
    --name "$name" 
    --network "$NET" 
    -p "$port:8080" 
    "$image"
}

ensure_network
deploy_service "service-a" 8081
deploy_service "service-b" 8082

Сделайте его исполняемым:

chmod +x ~/registry-scripts/deploy.sh

Ручной тест:

~/registry-scripts/deploy.sh branch-main

Дальше вы можете организовать cron‑подобный сценарий в Termux (например, через termux-scheduler, если он установлен) или вызывать скрипт по webhook.

Автоматическое масштабирование микросервисов на Android

Под «масштабированием» обычно понимают увеличение числа инстансов контейнера. На уровне Podman это реализуют через запуск нескольких контейнеров с уникальными именами и (при необходимости) балансировку трафика.

Практический план:

  1. Задайте желаемое количество инстансов для сервиса (REPLICAS).
  2. Сделайте idempotent‑скрипт: он сравнивает текущие инстансы с требуемыми и приводит систему к нужному состоянию.
  3. Определите стратегию маршрутизации к инстансам: через разные порты устройства или через локальный reverse proxy (например, Nginx в контейнере).

Упрощённый вариант: каждый инстанс публикует свой порт на хосте Android. Тогда внешний клиент выбирает нужный порт, а «балансировка» может быть на уровне вашей системы.

Сценарий: масштабируем service-a до N инстансов. Скрипт ~/registry-scripts/scale-service-a.sh:

#!/data/data/com.termux/files/usr/bin/bash
set -euo pipefail

REGISTRY="registry.example.com/yourgroup"
TAG="${1:-branch-main}"
REPLICAS="${2:-1}"

NET="micro-net"
BASE_NAME="service-a"
BASE_PORT=8081

ensure_network() {
  if ! podman network inspect "$NET" >/dev/null 2>&1; then
    podman network create --driver bridge "$NET"
  fi
}

container_name() {
  local i="$1"
  echo "${BASE_NAME}-${i}"
}

current_count() {
  # считает контейнеры BASE_NAME-i, которые существуют
  local count=0
  for i in $(seq 1 50); do
    if podman container exists "$(container_name $i)" &>/dev/null; then
      count=$((count+1))
    else
      # останавливаемся, если подряд нет (упрощение модели)
      # при необходимости можно сделать точнее
      :
    fi
  done
  echo "$count"
}

ensure_replicas() {
  ensure_network

  # Упрощённая логика: приводим ровно к REPLICAS, перезапуская недостающие
  for i in $(seq 1 "$REPLICAS"); do
    local name="$(container_name $i)"
    local port="$((BASE_PORT + i - 1))"
    local image="$REGISTRY/${BASE_NAME}:$TAG"

    if podman container exists "$name"; then
      podman stop "$name" || true
      podman rm "$name" || true
    fi

    podman run -d 
      --name "$name" 
      --network "$NET" 
      -p "$port:8080" 
      "$image"
  done

  # Удалим контейнеры выше REPLICAS (чтобы уменьшение работало)
  for i in $(seq $((REPLICAS+1)) 20); do
    local name="$(container_name $i)"
    if podman container exists "$name"; then
      podman stop "$name" || true
      podman rm "$name" || true
    fi
  done
}

ensure_replicas

Пример запуска:

~/registry-scripts/scale-service-a.sh branch-main 3

Теперь у вас появятся контейнеры service-a-1, service-a-2, service-a-3 и порты 8081, 8082, 8083 на Android.

Как автоматизировать масштабирование (модель политики)

Чтобы масштабирование было «автоматическим», нужен триггер. Часто используют:

  • Метрики нагрузки сервиса (RPS, latency, очередь задач) — через ваш мониторинг;
  • Наблюдение за потреблением CPU/RAM на устройстве;
  • Оценка очередей в вашей системе (например, Kafka/Redis Streams/очередь задач).

Далее агент на Android вызывает scale-service-a.sh с целевым числом инстансов. В простом случае политику можно хранить в переменных.

Пример агентной политики «если latency > X — увеличь, если < Y — уменьши» зависит от вашей системы метрик, поэтому конкретную интеграцию лучше делать под ваш стек.

На уровне Podman важно учитывать:

  • Ограничения ресурсов Android: тепловой режим, фоновые ограничения, доступ к сети.
  • Постоянство данных: если сервис пишет на диск, используйте volumes или внешнее хранилище.
  • Здоровье инстансов: при наличии healthcheck логика обновления должна не ломать рабочие контейнеры.

Рекомендуемый подход к конфигурации и секретам

Чтобы контейнеры были переносимыми, используйте:

  • env-файлы и шаблоны конфигурации;
  • Переменные окружения при запуске;
  • Внешние secret stores при наличии (в зависимости от вашей инфраструктуры).

Пример запуска с env:

podman run -d 
  --name service-a-1 
  --network micro-net 
  -p 8081:8080 
  -e "APP_ENV=prod" 
  -e "LOG_LEVEL=info" 
  registry.example.com/yourgroup/service-a:branch-main

Проверка целостности и откат

Для CI/CD важно иметь возможность отката. Минимальный подход:

  • Теги релизов неизменяемые (иммутабельные): v1.2.3 — навсегда указывает на один образ.
  • Agent на Android может переключать текущий тег (например, branch-main или release-stable).
  • При проблемах запускайте предыдущий тег.

В скрипте деплоя вы уже передаёте тег как параметр, поэтому откат сводится к повторному запуску с предыдущей версией.

Безопасность и эксплуатация

Практические меры:

  • Ограничивайте доступ к registry и используйте минимально необходимые учётные данные.
  • Разделяйте сети: контейнеры микросервисов — в отдельной podman-сети.
  • Не запускайте лишние порты без необходимости.
  • Следите за логами контейнеров и общим состоянием устройства.

Просмотр логов:

podman logs -f service-a-1

Проверка списка контейнеров:

podman ps -a

Заключение

Контейнеризация микросервисов в Termux через Podman — реальный и практичный способ организовать разработку и эксплуатацию на Android‑устройствах, сохраняя воспроизводимость и управляемость. Используя GitLab CI/CD для сборки и публикации образов, а на стороне устройств — idempotent‑скрипты деплоя и политики масштабирования, вы получаете надёжный контур обновлений и возможность масштабировать сервисы горизонтально.

Если вы планируете внедрение под вашу инфраструктуру (выбор registry, схема доступа устройств, настройка сети, модель метрик и конкретная политика масштабирования), РыбинскЛАБ поможет спроектировать и реализовать решение «под ключ»: от CI/CD до деплоя и сопровождения на Android‑платформе.

* Текст статьи подготовлен и структурирован с использованием технологий искусственного интеллекта. Проверен и доработан перед публикацией.

Нужна помощь с настройкой Termux, Linux и серверов?

Я оказываю ИТ-услуги: настройка серверов, автоматизация, безопасность, помощь с Linux и инфраструктурой. Материалы сайта — только в ознакомительных и образовательных целях.

Связаться со мной
Поддержать проект