DEVLOG

python / tooling / build systems

Nuitka + GitHub Actions: standalone vs zip

2025-11-01 · 12 min read

Сравниваю два режима сборки Nuitka в CI: --onefile (standalone) и --module + zip-архив. Разбираю размер, время сборки, время запуска и поведение с C-расширениями.

Почему Nuitka

Nuitka компилирует Python в C, а затем в нативный бинарник. В отличие от PyInstaller (который просто пакует интерпретатор + байткод), Nuitka реально компилирует — это даёт:

GitHub Actions workflow

name: build
on:
  push:
    tags: ['v*']
  workflow_dispatch:

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        mode: [standalone, zip]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - name: Install Nuitka
        run: |
          pip install nuitka ordered-set zstandard
      - name: Build standalone
        if: matrix.mode == 'standalone'
        run: |
          python -m nuitka \
            --onefile \
            --enable-plugin=numpy \
            --include-package=app \
            --include-data-dir=config=config \
            --output-dir=dist \
            --output-filename=app \
            main.py
      - name: Build zip
        if: matrix.mode == 'zip'
        run: |
          python -m nuitka \
            --module \
            --enable-plugin=numpy \
            --include-package=app \
            --output-dir=dist \
            main.py
          cd dist
          zip -r app.zip *.so *.pyd 2>/dev/null || zip -r app.zip *
      - name: Upload
        uses: actions/upload-artifact@v4
        with:
          name: app-${{ matrix.os }}-${{ matrix.mode }}
          path: dist/

Сравнение

ПараметрStandalone (onefile)Zip (module)
Размер (Linux x86_64)~45 MB~12 MB
Время сборки (GHA runner)~4 min~2.5 min
Время запуска~800ms (распаковка)~150ms
Зависимости на целевойНет (всё внутри)Python 3.12 + glibc
C-расширенияВключаются автоматическиНужен --include-package
Кросс-компиляцияНетНет

Подводные камни

Standalone

Zip

Вывод

Для CLI-утилит, которые юзер скачивает один раз — standalone. Для библиотек/модулей, которые ставятся в существующее Python-окружение — zip. В CI лучше собирать оба и дать юзеру выбор.

← back to posts