🔧 Кросс-сборка CLI и GUI-приложения на Rust — проблемы и решения
DotPlus — это Rust-приложение с графическим и консольным интерфейсом. Изначально оно разрабатывалось под Windows, но в планах была сборка под Linux и Docker.
Решение: добавить полноценные Linux-сборки с поддержкой GUI и CLI и обеспечить стабильную доставку под несколько архитектур.
❗ Почему не просто cargo build?
Если хочется стабильную сборку не только под x86_64, но и под ARM (Raspberry Pi, серверы), одной команды cargo build
недостаточно. Возникают проблемы:
Нужны кросс-компиляторы (
gcc-aarch64-linux-gnu
и др.)Требуется ручная настройка sysroot, musl, glibc
При использовании GUI (через
eframe
иegui
) иногда всплывают платформозависимые проблемы с OpenGL, зависимостями илиrfd
(файловые диалоги)
🛠 Решение: cross-rs
Чтобы не городить окружения вручную и не писать десятки --target
-флагов с настройкой toolchain, я решил использовать cross
— это официальный инструмент от сообщества Rust, который:
Использует Docker-образы с преднастроенным окружением для каждой архитектуры
Упрощает кросс-компиляцию одной командой:
cross build --release --target aarch64-unknown-linux-gnu
Работает из коробки как с CLI, так и с GUI (если система сборки внутри контейнера поддерживает нужные dev-пакеты)
⚙️ Конфигурация: cross.toml
Вот пример моего cross.toml
, где перечислены поддерживаемые архитектуры:
[target.aarch64-unknown-linux-gnu]
image = "ghcr.io/cross-rs/aarch64-unknown-linux-gnu:edge"
[target.armv7-unknown-linux-gnueabihf]
image = "ghcr.io/cross-rs/armv7-unknown-linux-gnueabihf:edge"
[target.x86_64-unknown-linux-gnu]
image = "ghcr.io/cross-rs/x86_64-unknown-linux-gnu:edge"
Образы edge
— это свежие контейнеры с последними версиями компилятора и зависимостей. Именно они обеспечивают корректную сборку egui
, eframe
и rfd
в Linux-окружении.
🧱 GUI + CLI: архитектура фич
[features]
default = ["gui"]
gui = ["eframe", "egui", "rfd", "egui_extras"]
notifications = ["notify-rust"]
Благодаря этому:
Сборка CLI-версии возможна без GUI (
--no-default-features
)На Linux можно собирать оба варианта одновременно, включая полноценное GTK/Wayland GUI через
eframe
Такой подход оказался крайне удобным: в одном проекте можно выпускать и headless-бинарник, и полноценное графическое приложение.
🪓 От чего пришлось отказаться
Несмотря на успех с cross
, не обошлось без потерь:
musl-сборки (статически линкуемые) были отброшены —
eframe
иrfd
плохо работают в таком окруженииWindows ARM MIPS и прочие экзотические платформы — слишком нестабильны и слабо поддерживаются в
cross
Слишком "чистая" сборка без Docker — пришлось отказаться от идеи собирать без контейнеров, так как зависимостей GUI слишком много, и они не всегда есть на GitHub Actions runner'ах
✅ Что в итоге получилось
В результате, с помощью cross
теперь собираются полноценные GUI+CLI бинарники под Linux для трёх платформ:
Архитектура | Поддержка | Назначение |
| ✅ GUI/CLI | Десктопы и серверы |
| ✅ GUI/CLI | ARM64 серверы, RPi 4 и новее |
| ✅ GUI/CLI | RPi 3 и другие ARMv7 SBC |
✅ Итог: благодаря cross
DotPlus теперь полноценно работает на Linux с графическим интерфейсом и CLI. Одинаковый UX, стабильные сборки, возможность использовать на Raspberry Pi и сервере — всё это стало реальностью.
🚀 CI/CD: автоматизация сборки, кросс-компиляции и релизов
После успешной настройки cross
для локальной кросс-компиляции стало ясно: ручной процесс не масштабируется. Хотелось воспроизводимой, полностью автоматизированной системы, которая при любом обновлении могла бы:
Собрать DotPlus под несколько архитектур
Подготовить установочные пакеты
.deb
и.rpm
Собрать и опубликовать Docker-образ
Сформировать релиз и прикрепить артефакты
Так родился CI/CD-процесс на базе GitHub Actions, который покрывает весь цикл сборки и доставки.
📂 Общая структура
CI/CD реализован в одном workflow-файле 📄 build-multiarch.yml:
name: Build dotplus (.deb/.rpm) for all architectures
on:
push:
branches: [linux]
tags: ["v*"]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
env:
CROSS_SKIP_VERSION_CHECK: "1"
steps:
- name: 🧾 Checkout
uses: actions/checkout@v4
- name: ⚡️ Cache Cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/bin
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: 🧬 Enable QEMU for multi-arch RPM
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: 🦀 Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
components: rustfmt
- name: 🎯 Add targets
run: |
rustup target add \
x86_64-unknown-linux-gnu \
aarch64-unknown-linux-gnu \
armv7-unknown-linux-gnueabihf
- name: 🐳 Install Docker & Cross
run: |
sudo apt update
sudo apt install -y docker.io containerd
if ! command -v cross &>/dev/null; then
cargo install cross
else
echo "✅ cross уже установлен, пропускаем"
fi
- name: 📦 Install deb/rpm tools
run: |
sudo apt install -y \
dpkg-dev debhelper rpm rpm2cpio fakeroot \
qemu-user-static binfmt-support \
gcc-multilib libc6-dev-i386 pkg-config \
libssl-dev libstdc++-12-dev
- name: 🔧 Make script executable
run: chmod +x tools/generate.sh
- name: 🛠 Run build script
run: ./tools/generate.sh
- name: ☁️ Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dotplus-packages
path: |
build/**/dotplus_*.deb
build/**/RPMS/**/*.rpm
docker:
runs-on: ubuntu-latest
needs: build
steps:
- name: 🧾 Checkout
uses: actions/checkout@v4
- name: 🦀 Install Rust + cross
run: |
rustup update
rustup target add x86_64-unknown-linux-musl
cargo install cross
- name: 🛠 Build static binary (musl, CLI-only)
run: cross build --release --target x86_64-unknown-linux-musl --no-default-features
- name: 🧰 Prepare Docker context
run: |
if [[ -f target/x86_64-unknown-linux-musl/release/dotplus ]]; then
cp target/x86_64-unknown-linux-musl/release/dotplus docker/dotplus
else
echo "❌ Static binary not found"
exit 1
fi
- name: 🐳 Build Docker image
run: docker build -t dotplus-cli -f docker/Dockerfile.cli ./docker
- name: ☁️ Save Docker image as archive
run: docker save dotplus-cli | gzip > dotplus-cli.tar.gz
- name: ☁️ Upload Docker image artifact
uses: actions/upload-artifact@v4
with:
name: dotplus-cli-docker
path: dotplus-cli.tar.gz
📄 build-multiarch.yml запускается при пуше в ветки release-linux
или release-docker
и выполняет сборку, упаковку, публикацию и деплой.
⚙️ Этапы пайплайна
Дата: 01.07.2025
Файл Workflow: build-multiarch.yml
Триггер: Push в ветку linux
📦 Этап 1: build
(⏱ ~16 минут)
Шаг | Описание |
⚙️ | Инициализация задания |
📥 | Клонирование репозитория |
⚡ | Кэширование зависимостей |
🧩 | Эмуляция архитектур |
🦀 | Установка Rust |
🎯 | Добавление целевых архитектур |
🐳 | Установка Docker и |
🧰 | Установка сборочных инструментов |
🔧 | Подготовка сборочного скрипта |
▶️ | Сборка |
⬆️ | Загрузка артефактов |
♻️ Post-steps | Очистка: откат QEMU, кэша и |

.deb
, .rpm
🐳 Этап 2: docker
(⏱ ~4 минуты)
Шаг | Описание |
⚙️ | Инициализация задания |
📥 | Клонирование репозитория |
🦀 | Установка Rust + кросс-компиляция |
🛠 | Сборка статичного бинарника (musl, CLI-only) |
🧳 | Подготовка контекста для Docker |
🔨 | Сборка образа |
💾 | Сохранение Docker-образа в архив |
⬆️ | Загрузка архива как артефакт |
♻️ Post-steps | Очистка: откат |


🔄 Кросс-сборка бинарников
Кросс-компиляция происходит с использованием cross
, который изолирует сборку в готовых Docker-образах:
- name: Build for aarch64
run: cross build --release --target aarch64-unknown-linux-gnu
- name: Build for armv7
run: cross build --release --target armv7-unknown-linux-gnueabihf
- name: Build for x86_64
run: cross build --release --target x86_64-unknown-linux-gnu
Это гарантирует одинаковые бинарники независимо от среды, включая GUI-часть на Linux.
📦 Пакетирование: .deb и .rpm из CI
dotplus_1.0.0_amd64.deb
dotplus_1.0.0_arm64.deb
dotplus_1.0.0_armhf.deb
dotplus-1.0.0-1.x86_64.rpm
Установка на стороне пользователя:
sudo dpkg -i dotplus_1.0.0_amd64.deb
# или
sudo rpm -i dotplus-1.0.0-1.x86_64.rpm
🔧 Как это устроено?
Проект включает шаблоны:
templates/
control.in
— шаблон для .deb
Package: dotplus
Version: {{VERSION}}
Section: utils
Priority: optional
Architecture: {{ARCH}}
Maintainer: Danil Nigmatullin <danil.communication@gmail.com>
Depends: {{DEPENDS}}
Description: QR and barcode generator with logo and CSV support (Rust CLI/GUI)
DotPlus is a Rust-based GUI and command-line tool for generating QR codes and barcodes.
It supports logo embedding, CSV import, and auto-update functionality.
Suitable for both terminal workflows and desktop users.
templates/
spec.in
— шаблон для .rpm
Name: dotplus
Version: {{VERSION}}
Release: 1%{?dist}
Summary: QR and barcode generator with logo and CSV support (Rust CLI/GUI)
License: Freeware (Proprietary)
URL: https://github.com/nigdanil/dotplus
Source0: dotplus
BuildArch: {{ARCH}}
Requires: {{REQUIRES}}
%description
DotPlus is a Rust-based GUI and CLI tool for QR/barcode generation with logo and CSV support.
%prep
# No preparation steps needed
%install
[ -f %{SOURCE0} ] || { echo "Missing binary dotplus in SOURCES"; exit 1; }
[ -f %{_sourcedir}/arialmt.ttf ] || { echo "Missing font file arialmt.ttf"; exit 1; }
mkdir -p %{buildroot}/usr/bin
mkdir -p %{buildroot}/usr/share/dotplus/fonts
install -m 0755 %{SOURCE0} %{buildroot}/usr/bin/dotplus
install -m 0644 %{_sourcedir}/arialmt.ttf %{buildroot}/usr/share/dotplus/fonts/arialmt.ttf
%files
/usr/bin/dotplus
/usr/share/dotplus/fonts/arialmt.ttf
%changelog
* Mon Jun 30 2025 Danil Nigmatullin <danil.communication@gmail.com> - {{VERSION}}-1
- Initial RPM build
А также вспомогательный скрипт 📄 tools/
generate.sh
:
# tools/generate.sh
#!/usr/bin/env bash
set -e
VERSION="1.0.0"
echo "🚀 Starting multi-arch build: version $VERSION"
START=$(date +%s)
ARCHS=(
"amd64" # x86_64-unknown-linux-gnu
"arm64" # aarch64-unknown-linux-gnu
"armhf" # armv7-unknown-linux-gnueabihf
)
TARGETS=(
"x86_64-unknown-linux-gnu"
"aarch64-unknown-linux-gnu"
"armv7-unknown-linux-gnueabihf"
)
DEB_ARCHS=(
"amd64"
"arm64"
"armhf"
)
RPM_ARCHS=(
"x86_64"
"aarch64"
"armv7hl"
)
ROOT_DIR="$(git rev-parse --show-toplevel)"
TEMPLATE_DIR="$ROOT_DIR/templates"
mkdir -p build
FAILED=()
for i in "${!ARCHS[@]}"; do
ARCH="${ARCHS[$i]}"
TARGET="${TARGETS[$i]}"
DEB_ARCH="${DEB_ARCHS[$i]}"
RPM_ARCH="${RPM_ARCHS[$i]}"
echo "🔧 Building for $ARCH ($TARGET)..."
CROSS_SKIP_VERSION_CHECK=1 cross build \
--release \
--target "$TARGET" \
--manifest-path Cargo.toml \
--verbose || { echo "⚠️ Build failed for $TARGET"; FAILED+=("$ARCH"); continue; }
BIN="target/$TARGET/release/dotplus"
ls -lh "target/$TARGET/release"
if [[ ! -f "$BIN" ]]; then
echo "❌ Build failed for $TARGET"
FAILED+=("$ARCH")
continue
fi
BUILD_DIR="build/$ARCH"
DEB_DIR="$BUILD_DIR/deb"
RPM_DIR="$BUILD_DIR/rpm"
mkdir -p "$DEB_DIR/DEBIAN"
mkdir -p "$DEB_DIR/usr/bin"
mkdir -p "$RPM_DIR/SOURCES"
cp "$BIN" "$DEB_DIR/usr/bin/dotplus"
cp "$BIN" "$RPM_DIR/SOURCES/dotplus"
cp src/tools/font/arialmt.ttf "$RPM_DIR/SOURCES/arialmt.ttf"
# Копируем ресурсные файлы (шрифты)
mkdir -p "$DEB_DIR/usr/share/dotplus/fonts"
cp src/tools/font/arialmt.ttf "$DEB_DIR/usr/share/dotplus/fonts/"
# === .deb ===
sed \
-e "s/{{VERSION}}/$VERSION/" \
-e "s/{{ARCH}}/$DEB_ARCH/" \
-e "s/{{DEPENDS}}/libc6 (>= 2.29)/" \
"$TEMPLATE_DIR/control.in" > "$DEB_DIR/DEBIAN/control"
dpkg-deb --build "$DEB_DIR" "$BUILD_DIR/dotplus_${VERSION}_${DEB_ARCH}.deb"
# === .rpm ===
SPEC_OUT="$RPM_DIR/dotplus.spec"
sed \
-e "s/{{VERSION}}/$VERSION/" \
-e "s/{{ARCH}}/$RPM_ARCH/" \
-e "s/{{REQUIRES}}/glibc >= 2.29/" \
"$TEMPLATE_DIR/spec.in" > "$SPEC_OUT"
RPM_BUILDROOT="$RPM_DIR/BUILDROOT/dotplus-${VERSION}-1.${RPM_ARCH}"
mkdir -p "$RPM_BUILDROOT/usr/bin"
cp "$BIN" "$RPM_BUILDROOT/usr/bin/dotplus"
chmod +x "$RPM_BUILDROOT/usr/bin/dotplus"
# Копируем ресурсные файлы (шрифты)
FONT_SOURCE="src/tools/font/arialmt.ttf"
FONT_DEST="$RPM_DIR/BUILDROOT/dotplus-${VERSION}-1.${RPM_ARCH}/usr/share/dotplus/fonts"
mkdir -p "$FONT_DEST"
if [[ -f "$FONT_SOURCE" ]]; then
cp "$FONT_SOURCE" "$FONT_DEST"
echo "✅ Шрифт скопирован: $FONT_SOURCE → $FONT_DEST"
else
echo "⚠️ WARNING: $FONT_SOURCE не найден — удаляем строку из .spec"
sed -i '/\/usr\/share\/dotplus\/fonts\/arialmt.ttf/d' "$SPEC_OUT"
fi
if [[ "$ARCH" == "amd64" ]]; then
echo "📦 Building RPM for $ARCH..."
rpmbuild \
--define "_topdir $ROOT_DIR/$RPM_DIR" \
--define "_sourcedir $ROOT_DIR/$RPM_DIR/SOURCES" \
--define "_builddir $ROOT_DIR/$RPM_DIR/BUILD" \
--define "_specdir $ROOT_DIR/$RPM_DIR" \
--define "_rpmdir $ROOT_DIR/$RPM_DIR/RPMS" \
--define "_buildrootdir $ROOT_DIR/$RPM_DIR/BUILDROOT" \
--target "$RPM_ARCH-redhat-linux" \
-bb "$SPEC_OUT" || {
echo "❌ RPM build failed for $TARGET"
FAILED+=("$ARCH")
continue
}
RPM_OUTPUT=$(find "$RPM_DIR/RPMS" -name "*.rpm")
if [[ -n "$RPM_OUTPUT" ]]; then
echo "✅ RPM built for $ARCH: $RPM_OUTPUT"
else
echo "❌ RPM not found for $ARCH"
FAILED+=("$ARCH")
fi
else
echo "⚠️ Skipping RPM build for $ARCH"
fi
echo "✅ RPM build completed for $ARCH"
echo "📁 RPM output dir listing:"
ls -lR "$RPM_DIR"
echo "📦 Checking built RPMs:"
find "$RPM_DIR/RPMS" -type f 2>/dev/null || true
done
END=$(date +%s)
DURATION=$((END - START))
if [[ ${#FAILED[@]} -gt 0 ]]; then
echo "❌ Failed builds: ${FAILED[*]}"
else
echo "✅ All target builds succeeded"
fi
echo "🎉 Build finished in $DURATION seconds."
# 🧪 Покажем, какие пакеты были созданы
echo "📦 Built package files:"
find build -type f \( -name "*.deb" -o -name "*.rpm" \)
# Подсчёт количества .deb и .rpm
PACKAGE_COUNT=$(find build -type f \( -name "*.deb" -o -name "*.rpm" \) | wc -l | tr -d '[:space:]')
echo "🧪 DEBUG: Found packages:"
FOUND_PACKAGES=$(find build -type f \( -name "*.deb" -o -name "*.rpm" \))
echo "$FOUND_PACKAGES"
# Если ни одного пакета не создано — ошибка
if [[ "$PACKAGE_COUNT" -lt 1 ]]; then
echo "❌ No packages were created (check target paths or build errors)"
echo "💡 Hint: verify that .deb and .rpm were written to expected build/**/ paths"
exit 1
fi
echo "✅ Total packages created: $PACKAGE_COUNT"
Он принимает бинарник и архитектуру, генерирует .deb
/.rpm
с помощью dpkg-deb
и rpmbuild
, и сохраняет итоговые пакеты для релиза.
🐳 Docker-сборка
После сборки бинарников запускается Docker-сборка CLI-варианта DotPlus:
- name: Build Docker image
run: |
docker build -f docker/Dockerfile.cli -t ghcr.io/nigdanil/dotplus:latest .
docker push ghcr.io/nigdanil/dotplus:latest
Простой Dockerfile.cli
использует минимальную базу и добавляет только бинарник:
FROM debian:bookworm-slim
COPY dotplus /usr/local/bin/dotplus
ENTRYPOINT ["dotplus"]
Публикация артефактов
Все собранные файлы (бинарники, .deb
, .rpm
) автоматически прикрепляются к GitHub Release. Это упрощает дистрибуцию: пользователи могут выбрать нужную архитектуру и просто скачать готовый пакет.
🧩 Что пришлось учесть
❌
musl
иarm64-darwin
не поддерживаются — нет стабильных образов или зависимости несовместимы⚠️
cross
не кеширует образы между пушами, поэтому Docker нужен как для сборки, так и для доставки
📌 Итоговая картина релиза
Формат | Архитектуры | Описание |
| x86_64, armhf, arm64 | Универсальная ручная установка |
| x86_64, armhf, arm64 | Ubuntu, Debian, Raspberry Pi |
| x86_64 | Fedora, RHEL, CentOS, openSUSE |
Docker | Любая (универсально) | Без установки, CI/CD, DevOps |
🐳 Docker: зачем он понадобился и как встроился в сборку
Изначально идея добавить Docker-образ DotPlus не стояла на первом месте. Основной упор делался на нативные бинарники и установочные пакеты. Однако в процессе развития проекта стало ясно: Docker — это не просто "в довесок", а необходимый инструмент, без которого:
невозможно обеспечить стабильную кросс-сборку в CI;
нельзя удобно использовать CLI в автоматических сценариях;
сложно дистрибутировать DotPlus в окружениях DevOps и серверов.
🔍 Зачем вообще нужен Docker?
Основные причины интеграции Docker:
✅ Надежная изоляция окружения в CI/CD
Дажеcross
работает внутри Docker-контейнеров. Если ты не контролируешь окружение сборки (например, на GitHub Actions), Docker становится стандартом.✅ Упрощённый запуск без установки
CLI-версия DotPlus можно использовать прямо из Docker без установки бинарников, зависимостей и пакетов. Это особенно ценно для DevOps и автоматизации.✅ Платформа-агностичный дистрибутив
Один образ — один результат. Его поведение одинаково в любой системе, будь то Windows, Linux или macOS (с установленным Docker).✅ Разделение GUI и CLI
Docker используется только для CLI. Это упрощает образ, делает его минимальным и не тянет GUI-библиотеки.
🛠 Структура Dockerfile
В проекте используется Dockerfile.cli
:
FROM debian:bookworm-slim
COPY dotplus /usr/local/bin/dotplus
ENTRYPOINT ["dotplus"]
Это минимальный образ (на базе slim-дистрибутива Debian), в который помещается только собранный бинарник dotplus
. Никаких дополнительных зависимостей, библиотек или окружения не требуется.
⚙️ Интеграция в CI
Сборка Docker-образа происходит автоматически, после компиляции CLI:
- name: Build Docker image
run: |
docker build -f docker/Dockerfile.cli -t ghcr.io/nigdanil/dotplus:latest .
docker push ghcr.io/nigdanil/dotplus:latest
Docker-образ публикуется в Docker Hub, откуда его может скачать любой пользователь:
docker pull nigdanil/dotplus-cli:latest
🚀 Как использовать Docker-версию DotPlus
Пример запуска CLI внутри Docker:
docker run --rm -v $(pwd):/out ghcr.io/nigdanil/dotplus:latest \
--text "Docker test" --format qrcode --output /out/code.png
Объяснение:
--rm
— удаляет контейнер после завершения-v $(pwd):/out
— монтирует текущую папку внутрь контейнера для вывода результата--text
,--format
,--output
— аргументы CLI DotPlus
Таким образом, можно использовать DotPlus в любом CI, на сервере, на macOS или даже в WSL — не устанавливая ничего, кроме Docker.
💻 Запуск DotPlus через Docker на Windows (.bat
-файлы)
👉 Для пользователей Windows подготовлены удобные .bat
-скрипты, которые вызывают CLI DotPlus внутри Docker-контейнера. Это позволяет запускать генерацию QR и штрихкодов без установки зависимостей.
📄 run-qr.bat
— генерация QR-кодов
@echo off
REM Генерация QR-кодов из CSV через Docker
docker run --rm -v "%cd%\examples:/examples" nigdanil/dotplus-cli:1.0.0 ^
--mode qr ^
--csv "/examples/magnit/data/qr/magnit.csv" ^
--logo "/examples/magnit/logo/v1.png" ^
--output "/examples/magnit/img/qr" ^
--cols 3 ^
--rows 3 ^
--qr-size 150 ^
--font-size 24 ^
--font-color "#000000"
pause
📄 run-barcode.bat
— генерация EAN-13 штрихкодов
@echo off
REM Генерация штрихкодов EAN-13 из CSV через Docker
docker run --rm -v "%cd%\examples:/examples" nigdanil/dotplus-cli:1.0.0 ^
--mode barcode ^
--csv "/examples/magnit/data/barcode/magnit-barcodes-EAN-13.csv" ^
--output "/examples/magnit/img/barcode" ^
--barcode-type EAN-13 ^
--cols 3 ^
--rows 4 ^
--width 300 ^
--height 100 ^
--font-size 22 ^
--label-height 40 ^
--offset-y 10 ^
--spacing-x 20 ^
--spacing-y 20
pause
📂 Структура проекта для скриптов
D:\dotplus-windows\
├── examples\
├── run-qr.bat
└── run-barcode.bat
📌 Скрипты монтируют папку examples
внутрь контейнера и сохраняют результат в удобное место. Всё, что нужно — это установленный Docker.
✅ Почему это удобно?
Не нужно устанавливать
Rust
, зависимости или самdotplus
Работает на любой машине с Docker
Можно интегрировать в автоматизацию, скрипты, CI/CD
📌 Что удалось благодаря Docker
Проблема | Решение через Docker |
Кросс-сборка в CI |
|
Использование без установки | Образ с CLI доступен публично |
Интеграция в shell-скрипты и пайплайны | CLI можно вызывать из любого скрипта |
Минимизация зависимости | Образ содержит только |
✅ Вывод: Docker стал неотъемлемой частью инфраструктуры DotPlus. Он используется и в процессе сборки, и как самостоятельный способ запуска CLI. Это позволяет дистрибутировать инструмент в любую среду — будь то сервер, CI/CD или чужой компьютер без установки зависимостей.
📜 Лицензия DotPlus: от исходников к закрытому дистрибутиву
В первой версии DotPlus проект поставлялся с открытым кодом. Однако с релизом стабильных версий и запуском сборок под Linux, стало ясно: пора пересмотреть подход к лицензированию. Причин этому — несколько, и они связаны как с техническими, так и с юридическими и практическими аспектами.
В результате было принято решение:
📌 Перейти на бесплатную, но проприетарную лицензию.
❓ Почему так?
Вот ключевые причины:
Минимизация рисков форков и переиспользования бренда
Когда проект становится узнаваемым, велик риск "серых" клонов, которые могут нарушать философию продукта или использовать имя DotPlus без разрешения.Снижение нагрузки на поддержку
Когда код открыт, пользователи часто создают собственные сборки, вносят изменения и потом задают вопросы, не относящиеся к официальной версии.Защита бизнес-модели и эксклюзивных алгоритмов
DotPlus использует внутренние техники вставки логотипов, оптимизации QR, компактного вывода и т. д. Их защита — ключ к качеству конечного продукта.Фокус на стабильных бинарниках, а не на доработках со стороны сообщества
Вся сборка и дистрибуция централизованы — это позволяет гарантировать качество и одинаковое поведение на всех системах.
✅ Что разрешено по новой лицензии?
🔓 Бесплатное использование для любых целей — как в личных, так и в коммерческих проектах
📦 Распространение неизменённых бинарников
👥 Использование в организациях, автоматизации, CI/CD и т. п.
❌ Что запрещено?
🚫 Изучение, анализ, декомпиляция и модификация бинарников
🚫 Распространение модифицированных версий
🚫 Попытки восстановить или раскрыть исходный код
📁 Как распространяется DotPlus сейчас?
✅ Только в виде бинарников (
.exe
,.deb
,.rpm
,.tar.gz
)✅ Через официальный GitHub Releases и Docker Registry
📄 Лицензионное соглашение (фрагмент)
Тип лицензии: Бесплатное ПО (проприетарное)
Исходный код: не распространяется
Использование: разрешено для личного и коммерческого применения
Обратная разработка: строго запрещена
Распространение: допустимо только в виде неизменённых бинарников с включением лицензионного соглашения
Авторские права: исходный код и все права на него остаются за автором
⚠️ Почему это всё равно честно?
Несмотря на закрытую лицензию, DotPlus остаётся:
полностью бесплатным;
стабильным и регулярно обновляемым;
совместимым с Linux, Windows, Docker;
понятным и удобным инструментом, который не требует онлайн-доступа или регистрации.
Более того, пользователь всё ещё получает CLI-инструмент, GUI-приложение и все опции (включая CSV, логотипы, экспорт) без ограничений функциональности.
✅ Вывод: лицензия DotPlus теперь закрытая, но прозрачная. Программа остаётся бесплатной, распространяется в виде готовых бинарников и полностью пригодна для реального применения — без страха перед юридическими подводными камнями.
📈 Итоги и планы развития DotPlus
DotPlus прошёл большой путь от простой Windows-программы до полноценного кроссплатформенного инструмента с поддержкой CLI, GUI, Docker и релизами под Linux. Этот этап развития был посвящён тому, чтобы сделать проект устойчивым, универсальным и легко доставляемым в любой среде.
✅ Что реализовано
Возможность | Статус | Комментарий |
🖥 GUI для Windows и Linux | ✅ Готово | На базе |
🧾 CLI-интерфейс | ✅ Готово | Генерация QR/штрихкодов через параметры |
📦 DEB и RPM-пакеты | ✅ В релизах | Для всех популярных дистрибутивов |
🐳 Docker-образ | ✅ Опубликован | Поддержка запуска без установки |
🔄 CI/CD-сборка и релизы | ✅ Автоматизировано | Публикация в GitHub Releases + GHCR |
🔐 Проприетарная лицензия | ✅ Введена | Бесплатно, без исходников, с разрешением на использование |
🛠 Технические особенности
Используется
cross
для мультиархитектурной сборки (x86_64, ARMv7, AArch64)Автоматическая генерация
.deb
и.rpm
через скриптtools/
generate.sh
CI/CD на GitHub Actions, один YAML управляет всем пайплайном
Распространение Docker-образа через Docker Hub:
docker pull nigdanil/dotplus-cli:latest
🔮 Что в планах?
Вот направления, над которыми планируется работать в следующих релизах:
План | Статус | Комментарий |
📄 Экспорт в PDF и SVG | 🔜 В процессе | Для векторной печати и типографий |
🌐 Web-версия на WASM | 🔜 Исследуется | Возможность запуска в браузере без сервера |
📄 Поддержка больших CSV | 🔜 Планируется | Пакетная генерация с логами и ошибками |
🔄 Автообновление для GUI | 🔜 Будет | Особенно для Windows-версии |
⚙️ Расширение CLI | 🔜 Постепенно | Больше форматов, управление шаблонами |
🔔 Интеграция уведомлений | 🔜 Через | Пока опциональная фича |
🤝 Обратная связь и участие
Если вам не хватает какой-то функции, формат не поддерживается, или вы хотите предложить идею — открывайте issue на GitHub:
📌 https://github.com/nigdanil/dotplus
✅ Финальный вывод
DotPlus стал стабильным, мощным и универсальным инструментом для генерации QR и штрихкодов.
Поддержка разных архитектур, нативные пакеты, Docker и офлайн-режим делают его отличным выбором для всех — от домашних пользователей до CI-инфраструктур.
Программа продолжит развиваться. Спасибо всем, кто использует, тестирует и даёт обратную связь.