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

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

Разработка и отладка микросервисов на Rust в Termux: кросс‑компиляция, тесты и публикация в Docker‑реестре

Практический гайд по разработке микросервисов на Rust в Termux: настройка среды, кросс‑компиляция, запуск тестов, сборка Docker-образов и публикация в реестре, с акцентом на воспроизводимость и контроль зависимостей.

Termux — удобная среда на Android для разработки: здесь можно собирать проекты, прогонять тесты и готовить артефакты для контейнеризации. Rust хорошо подходит для микросервисов благодаря безопасности памяти, производительности и удобной системе сборки cargo. В этой статье рассмотрим практичный путь от локальной разработки до публикации Docker-образа в реестре: кросс‑компиляция, запуск тестов и сборка контейнеров.

Цель материала — сделать процесс воспроизводимым: чтобы “проект на телефоне” превращался в образ, который корректно запускается в среде вашего окружения (CI/CD, тестовый стенд, прод). Все шаги будут описаны без “магии”, с фокусом на проверяемые команды.

Предпосылки и требования

Перед началом уточните:

  • Телефон с Android, установленный Termux.
  • Доступ к интернету (для загрузки зависимостей и публикации образов).
  • Аккаунт в Docker‑реестре (Docker Hub, GitLab Registry, Harbor, ECR и т.д.).
  • Понимание целевой архитектуры контейнера (чаще linux/amd64 или linux/arm64).

Вариант с локальной сетью возможен при помощи VPN, но только для создания локальной сети и доступа к ресурсам разработки внутри вашей сети — без обхода блокировок.

Подготовка Termux: базовые пакеты и Rust toolchain

Сначала обновим пакеты и поставим инструменты, которые пригодятся для сборки и упаковки.

pkg update -y
pkg upgrade -y
pkg install -y git curl ca-certificates tar openssl-tool clang make pkg-config

Установите Rust. На практике удобно использовать официальный установщик rustup (или пакетный вариант, если выбран он). Рекомендую rustup для гибкости версий.

curl https://sh.rustup.rs -sSf | sh -s -- -y
. $HOME/.cargo/env
rustc --version
cargo --version

Проверьте, что ~/.cargo/bin добавлен в PATH.

echo $PATH

Создание каркаса микросервиса на Rust

Для примера возьмём типичный стек: HTTP‑сервер на axum (или actix-web, без принципиальной разницы). Создадим проект и добавим зависимости.

cargo new ms-hello --bin
cd ms-hello

В Cargo.toml добавим зависимости. Пример ниже показывает минимальный набор для HTTP и тестов.

cat > Cargo.toml <<'EOF'
[package]
name = "ms-hello"
version = "0.1.0"
edition = "2021"

[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"

[dev-dependencies]
reqwest = { version = "0.12", features = ["json"] }
tower = "0.5"
EOF

Содержимое src/main.rs для запуска простого эндпоинта:

cat > src/main.rs <<'EOF'
use axum::{routing::get, Router};

async fn health() -> &'static str {
    "ok"
}

#[tokio::main]
async fn main() {
    let app = Router::new().route("/health", get(health));

    let listener = tokio::net::TcpListener::bind("0.0.0.0:8080")
        .await
        .expect("bind");

    println!("listening on http://0.0.0.0:8080");
    axum::serve(listener, app).await.unwrap();
}
EOF

Запустим на телефоне:

cargo run

Проверка из другого терминала (или через браузер):

curl -s http://127.0.0.1:8080/health

Локальные тесты в Termux: качество до сборки

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

Создадим тестовый файл:

mkdir -p tests
cat > tests/health.rs <<'EOF'
use axum::{routing::get, Router};

async fn health() -> &'static str {
    "ok"
}

#[tokio::test]
async fn health_returns_ok() {
    let app = Router::new().route("/health", get(health));

    // В минимальном примере проверим обработчик напрямую не поднимая реальный listener.
    // Для сложных сценариев используйте axum::Server на тестовом порту.
    let response = app
        .oneshot(())
        .await;

    let _ = response; // placeholder, чтобы фокус был на подходе.
}
EOF

Запуск тестов:

cargo test

Если вы предпочитаете полноценные HTTP‑интеграционные тесты (через reqwest и запуск сервера на локальном порту), напишите их по месту под вашу архитектуру. Ключевой принцип: тест должен подтверждать бизнес‑контракты, а не “только компиляцию”.

Кросс‑компиляция: собрать под Docker‑архитектуру

Если вы собираете образ для linux/amd64 или linux/arm64, а компилируете в Termux на Android, вам понадобится кросс‑компиляция. В Rust это решается целевыми тройками (target triples) и установкой соответствующих инструментов.

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

  • x86_64-unknown-linux-gnu (linux/amd64)
  • aarch64-unknown-linux-gnu (linux/arm64)

Добавьте target'ы:

rustup target add x86_64-unknown-linux-gnu
rustup target add aarch64-unknown-linux-gnu

Дальше — самый важный момент: вам нужно обеспечить линковщик и необходимые инструменты для этих целей. На Android это может быть нетривиально “в лоб”, поэтому практичный путь — собирать в Docker билд‑среде (чуть ниже это будет рассмотрено), либо использовать готовые toolchain‑решения.

Ниже приведён общий шаблон команд сборки под target:

cargo build --release --target x86_64-unknown-linux-gnu
cargo build --release --target aarch64-unknown-linux-gnu

Если сборка падает из‑за линковщика/системных библиотек, корректный промышленный подход — не пытаться “дотягивать” libc и линковку на устройстве, а переносить финальную сборку в контейнер (см. секцию “Docker: multi-stage сборка и воспроизводимость”). Это лучше для консистентности и повторяемости.

Оптимизация релизной сборки: размер и детерминизм

В микросервисах часто важны время старта и размер бинарника. Используйте настройку профилей в Cargo.toml:

cat >> Cargo.toml <<'EOF'

[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = true
EOF

Затем собирайте релиз:

cargo build --release

Для воспроизводимости полезно фиксировать зависимости версионным диапазоном и контролировать Cargo.lock (commit его в репозиторий).

Подготовка Dockerfile: multi-stage сборка

Чтобы гарантировать, что итоговый бинарник подходит к нужной платформе, лучше использовать multi-stage Dockerfile. Такой подход также облегчает multi-arch сборку (например, amd64/arm64) через buildx.

Создайте Dockerfile в корне проекта:

cat > Dockerfile <<'EOF'
# syntax=docker/dockerfile:1.6

# 1) Builder
FROM rust:1.78-bookworm AS builder
WORKDIR /app

# Кэш зависимостей
COPY Cargo.toml Cargo.lock ./
RUN mkdir -p src && echo "fn main() {}" > src/main.rs
RUN cargo build --release

# Собираем реальный проект
COPY src ./src
RUN cargo build --release

# 2) Runtime
FROM debian:bookworm-slim
WORKDIR /app

# Копируем бинарник
COPY --from=builder /app/target/release/ms-hello ./ms-hello

# Минимальные настройки (безопасность)
USER 65532:65532

EXPOSE 8080
CMD ["./ms-hello"]
EOF

Важно:

  • В образ переносится только бинарник — это снижает поверхность атаки и размер.
  • USER 65532:65532 повышает безопасность (при корректной поддержке в базовом образе).

Сборка образа локально в Termux

Для сборки Docker‑образов из Termux у вас есть несколько вариантов: сборка на CI, сборка на хосте с Docker или использование окружения, где Docker доступен из Termux. Практично и надёжно — выполнять docker buildx на рабочей станции/сервере или в CI.

Если Docker на вашей стороне доступен, базовая команда:

docker build -t rybinsklab/ms-hello:dev .

Проверка запуска (пример):

docker run --rm -p 8080:8080 rybinsklab/ms-hello:dev

Затем проверка:

curl -s http://127.0.0.1:8080/health

Публикация Docker-образа в реестре

Ниже — универсальный сценарий. Замените registry.example.com, USERNAME, IMAGE_NAME на свои значения.

1) Логин в реестр:

docker login registry.example.com -u USERNAME

2) Тегирование:

IMAGE=registry.example.com/IMAGE_NAME
TAG=0.1.0

docker tag rybinsklab/ms-hello:dev $IMAGE:$TAG

3) Публикация:

docker push $IMAGE:$TAG

Рекомендуется также вести “latest” или версионные теги согласно вашей стратегии (семвер, git‑sha, date‑tags). Для микросервисов чаще удобнее версионность и неизменяемость артефакта.

Multi-arch публикация (amd64/arm64) через buildx

Если ваш реестр и инфраструктура поддерживают multi-arch, можно публиковать единый тег, внутри которого будут варианты под разные архитектуры.

Пример команд (на машине, где доступен buildx):

docker buildx create --use --name rybxs

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t $IMAGE:$TAG \
  --push \
  .

Это избавляет от ручной кросс‑компиляции и повышает воспроизводимость: сборка происходит в стандартизированных средах Docker.

CI/CD: как встроить Termux‑процесс в промышленную цепочку

Хотя Termux удобен для локальной разработки, обычно “финальный” пайплайн лучше переносить в CI. Типовой сценарий:

  • На этапе PR: cargo test (быстро, без контейнеров).
  • На этапе merge/release: сборка релиза и docker build (в CI) с multi-arch.
  • Публикация в реестр и деплой на целевую среду.

Termux в таком случае остаётся отличным инструментом для черновой разработки, отладки, быстрой проверки и подготовки исходников.

Типовые проблемы и как их диагностировать

1) “Не собирается под target”
Кросс‑сборка на Android часто упирается в линковку и наличие совместимых библиотек. Практический совет: используйте Docker multi-stage сборку для финального бинарника.

2) Тесты “зависят от сети”
Сделайте тесты детерминированными: подменяйте внешние сервисы через mock или локальные тестовые серверы. Идеально — чтобы cargo test всегда давал одинаковый результат.

3) Бинарник не запускается в runtime‑образе
Проверьте базовый образ runtime (glibc/musl), совместимость ABI и наличие нужных переменных окружения. Multi-stage + одинаковая toolchain‑база обычно решает проблему.

Заключение

Разработка микросервисов на Rust в Termux позволяет быстро создавать и отлаживать сервисы прямо на устройстве: вы запускаете cargo run, прогоняете cargo test и готовите проект к контейнеризации. Для надёжной кросс‑платформенной публикации в Docker‑реестре практичнее использовать multi-stage сборку в Docker (и при необходимости buildx для multi‑arch), чтобы финальные бинарники были воспроизводимыми и соответствовали целевой архитектуре.

Нужна помощь с настройкой репозитория, пайплайна CI/CD, Docker‑архитектурой или подбором стратегии тэгирования/версий для микросервисов? Обратитесь в РыбинскЛАБ — поможем спроектировать процесс разработки и публикации под ваши цели.

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

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

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

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