PyInstaller Windows

A Docker-based build system for compiling Python applications into standalone Windows executables using PyInstaller. Runs PyInstaller builds inside a clean Windows container, avoiding the need for native Windows build machines or WSL workarounds.

Why It Exists

PyInstaller requires a matching OS to produce working binaries — you compile .exe files on Windows, .dmg on macOS, etc. This image gives you consistent, reproducible Windows builds from any environment (Linux CI, Mac, etc.) without needing an actual Windows box.

Usage

docker pull danleyb2/pyinstaller-windows:latest

The image includes PyInstaller, all common Python dependencies, and a build pipeline that outputs standalone .exe files ready for distribution.

Stats

  • Pulls: 486+
  • Architecture: amd64 / Linux
  • Image size: ~802 MB
  • First built: April 2021

Cross-Platform CI Pipeline

The project also powers a cross-platform installer pipeline using GitHub Actions. Each platform is built independently:

Windows & Linux (Containerized)

Both use Docker containers to isolate the build environment:

jobs:
  windows-installer:
    name: Windows
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build Installer
        run: docker run \
          -v $GITHUB_WORKSPACE/docker/platerec_installer:/src/ \
          danleyb2/pyinstaller-windows "pyinstaller platerec_installer.spec -F"
      - uses: actions/upload-artifact@v4
        with:
          name: Windows-Installer-unsigned
          path: docker/platerec_installer/dist

  linux-installer:
    name: Linux
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build Installer
        run: docker run \
          -v $GITHUB_WORKSPACE/docker/platerec_installer:/src/ \
          cdrx/pyinstaller-linux "pyinstaller platerec_installer.spec -F"
      - uses: actions/upload-artifact@v4
        with:
          name: PlateRecognizer-Installer-Linux
          path: docker/platerec_installer/dist/PlateRecognizer-Installer

Windows builds inside the danleyb2/pyinstaller-windows container; Linux uses cdrx/pyinstaller-linux. Both mount the source directory and output to dist/.

macOS (Native)

macOS runs natively since there’s no equivalent cross-platform Docker image:

  mac-installer:
    runs-on: macos-latest
    name: MacOS
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: 3.8.10
      - name: Build Installer
        run: |
          cd docker/platerec_installer
          pip install --upgrade pip
          pip install -r requirements.txt pyinstaller==6.15.0
          pyinstaller platerec_installer.spec
          chmod -R +x dist
      - uses: actions/upload-artifact@v4
        with:
          name: PlateRecognizer-Installer-MacOS
          path: docker/platerec_installer/dist/*

Windows Smoke Test

After building, the installer is validated on a real Windows runner:

  test-windows-installer:
    runs-on: windows-latest
    needs: windows-installer
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: Windows-Installer-unsigned
          path: dist
      - name: Test local API
        run: |
          cmd /c "START /b dist\PlateRecognizer-Installer.exe"
          ping 127.0.0.1 -n 6 > nul
          netstat -o -n -a | findstr 8050
          curl -X GET "http://localhost:8050"

This starts the installer in the background, waits for it to expose port 8050, then hits its local API endpoint. Anything that fails kills the build.