Skip to content

Docker Build Modes - Complete Guide

[!NOTE] For Japanese documentation, see DOCKER_BUILD_MODES.md

Overview

EvoSpikeNet-Core supports 4 Docker image build modes that allow you to maintain existing development flows while offering progressively hardened release builds with reduced source exposure.

Mode Use Case Source Exposure Build Time Image Size Security
source Local development & testing ✅ All Short Large None
wheel Staging environments ❌ None Medium Medium Basic
cython Pre-production ❌ .so files Long Medium Medium
nuitka Production deployment ❌ Binary Longest Large High

1. Source Mode (Default)

Complete project source tree included in image. Compatible with all existing development workflows and tests.

Use Cases

  • ✅ Local development & debugging
  • ✅ CI/CD test pipelines
  • ✅ Internal development environments
  • ✅ Environments requiring backward compatibility

Build Command

# Implicit (default)
docker build -t evospikenet:source .

# Explicit
docker build -t evospikenet:source \
  --build-arg APP_IMAGE_MODE=source \
  --target runtime \
  .

Run Example

docker run --rm -p 18000:8000 evospikenet:source

2. Wheel Mode

Python packages installed as wheels only. Project source tree is not copied into runtime image.

Use Cases

  • ✅ Staging environment distribution
  • ✅ Internal registry deployment
  • ✅ License distribution requirements
  • ✅ Basic source protection needed

Build Command

docker build -t evospikenet:wheel \
  --build-arg APP_IMAGE_MODE=wheel \
  --target runtime-wheel \
  .

Security

  • Risk: Python bytecode (.pyc) can be decompiled
  • Mitigation: Project source tree excluded
  • Protection Level: Low-Medium (no reverse engineering prevention)

Verification

# Confirm source tree is excluded
docker run --rm evospikenet:wheel test -d /app/evospikenet && \
  echo "WARNING: Source tree found" || echo "✓ Source tree correctly excluded"

# Test module import
docker run --rm evospikenet:wheel python -c \
  "import evospikenet.api; print('✓ API module loaded')"

3. Cython Mode

Selected modules compiled to Cython .so (shared object) files. Original .py source files are removed after compilation.

Use Cases

  • ✅ Pre-production environments
  • ✅ Source obfuscation required
  • ✅ Performance optimization needed
  • ✅ License protection important

Build Command

docker build -t evospikenet:cython \
  --build-arg APP_IMAGE_MODE=cython \
  --target runtime-cython \
  .

Build Process

  1. Generate wheel in builder stage
  2. Install wheel
  3. Run Cython compilation: scripts/protect_with_cython.py
  4. Find target modules from site-packages
  5. Compile with cythonize -3 -i
  6. Generate .so files
  7. Delete original .py source files
  8. runtime-cython stage contains only protected modules

Cython Protected Modules

Defined in scripts/protect_with_cython.py:

evospikenet/api.py
evospikenet/api_modules/distributed_brain_api.py
evospikenet/models.py
controllers/placement_controller.py
controllers/resource_controller.py

Security

  • Risk: .so files are reverse-engineering resistant (but not impossible)
  • Mitigation:
  • Core modules converted to C extensions (.so)
  • Original .py source files removed
  • C debug symbols not available
  • Protection Level: Medium (resists casual inspection)

Build Time

Wheel compilation: ~5 min
+ Cython compilation: +10-15 min
= Total: 15-20 min

Verification

# Confirm compiled modules exist
docker run --rm evospikenet:cython find /opt/venv -name "*.so" | head -5

# Confirm source files removed
docker run --rm evospikenet:cython test -f /opt/venv/lib/python3.10/site-packages/evospikenet/api.py && \
  echo "WARNING: Source file still exists" || echo "✓ Source file correctly removed"

# Test module loading
docker run --rm evospikenet:cython python -c \
  "import evospikenet.api; print('✓ Cython-protected module loaded')"

4. Nuitka Mode

API server compiled to standalone Nuitka binary. Provides highest source protection level but has largest image size and longest build time.

Use Cases

  • ✅ Production environment maximum protection
  • ✅ Commercial deployment
  • ✅ Source code confidentiality critical
  • ✅ Regulatory environment distribution

Build Command

docker build -t evospikenet:nuitka \
  --build-arg APP_IMAGE_MODE=nuitka \
  --target runtime-nuitka \
  .

Build Process

  1. Generate wheel in builder stage
  2. Run Nuitka compilation: scripts/build_nuitka_api_binary.py
  3. Create small Python launcher script
  4. Compile with Nuitka: nuitka --onefile flags
  5. Generate standalone binary: /tmp/nuitka-dist/evospikenet-api
  6. runtime-nuitka stage contains only binary
  7. /app/launch.sh invokes binary

Security

  • Risk: Compiled binary is reverse-engineering resistant
  • Mitigation:
  • Python runtime standalone compilation
  • All dependencies embedded
  • Runtime .so files generated in temp area
  • Protection Level: High (source recovery nearly impossible)

Important Notes

1. Binary Portability

Nuitka binary is build system dependent. Different Ubuntu versions or architectures require rebuild.

# Rebuild for different target environment
docker build --build-arg BASE_IMAGE=ubuntu:20.04 \
  --build-arg APP_IMAGE_MODE=nuitka \
  --target runtime-nuitka \
  .

2. Patching Strategy

Security patches require rebuild. No in-place fixes possible.

# After dependency update, rebuild is mandatory
pip install --upgrade vulnerable-package
docker build ... --no-cache --target runtime-nuitka ...

3. Limited Debugging

Standalone binaries have limited debug capabilities. Increase log level for troubleshooting.

docker run --rm -e LOG_LEVEL=DEBUG evospikenet:nuitka

Build Time

Wheel compilation: ~5 min
+ Nuitka binary build: +30-45 min
= Total: 35-50 min

Image Size Profile

  • wheel: ~350MB
  • nuitka: ~600MB (binary + runtime)

Verification

# Test binary is executable
docker run --rm evospikenet:nuitka test -x /tmp/nuitka-dist/evospikenet-api && \
  echo "✓ Nuitka binary OK" || echo "ERROR: Binary not executable"

# Measure binary size
docker run --rm evospikenet:nuitka du -sh /tmp/nuitka-dist/

# Test API startup
docker run --rm -p 8000:8000 evospikenet:nuitka

Mode Selection Matrix

Is this local development?
├─→ YES: Use source mode
└─→ NO
    ├─→ Is source obfuscation needed?
    │  ├─→ YES: 
    │  │  ├─→ Is performance critical?
    │  │  │  ├─→ YES: Use cython mode
    │  │  │  └─→ NO: Use wheel mode
    │  │  └─→ NO: Next
    │  └─→ NO: Next
    └─→ Is this production/commercial?
       ├─→ YES: Use nuitka mode
       └─→ NO: Use wheel or cython mode

Build Commands Quick Reference

Mode Build Command Target Time
source docker build . (default) ~2 min
wheel docker build --build-arg APP_IMAGE_MODE=wheel --target runtime-wheel . runtime-wheel ~7 min
cython docker build --build-arg APP_IMAGE_MODE=cython --target runtime-cython . runtime-cython ~20 min
nuitka docker build --build-arg APP_IMAGE_MODE=nuitka --target runtime-nuitka . runtime-nuitka ~50 min

Performance Impact

Metric source wheel cython nuitka
Startup Time <1s <1s <1s 3-5s
Runtime Speed 100% 100% 105% 105%
Memory Usage 1GB 1GB 1GB 1.5GB
Debug-friendly ⚠️
Hot-reload

Docker Compose Usage

source mode (development)

version: '3.8'
services:
  api:
    image: evospikenet:source
    ports:
      - "18000:8000"
    volumes:
      - ./logs:/opt/venv/var/logs
    environment:
      - LOG_LEVEL=DEBUG

wheel mode (staging)

version: '3.8'
services:
  api:
    image: evospikenet:wheel
    ports:
      - "18000:8000"
    read_only: true
    security_opt:
      - no-new-privileges:true

nuitka mode (production)

version: '3.8'
services:
  api:
    image: evospikenet:nuitka
    ports:
      - "18000:8000"
    read_only: true
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /tmp
      - /var/tmp
    deploy:
      resources:
        limits:
          memory: 3G

Best Practices

1. Development Flow

# Local: source mode
docker compose up -d api

# Test environment: wheel mode
docker build -t registry.azurecr.io/evospikenet:wheel \
  --build-arg APP_IMAGE_MODE=wheel \
  --target runtime-wheel \
  .
docker push registry.azurecr.io/evospikenet:wheel

2. Release Process

# Staging validation: wheel
# → OK then move to cython
# → OK then move to nuitka
# → Deploy to production

docker build -t evospikenet:v1.0-nuitka \
  --build-arg APP_IMAGE_MODE=nuitka \
  --target runtime-nuitka \
  .

3. Registry Tag Strategy

# Clear mode indication in tags
docker tag evospikenet:wheel myregistry/evospikenet:latest-wheel
docker tag evospikenet:cython myregistry/evospikenet:latest-cython
docker tag evospikenet:nuitka myregistry/evospikenet:latest-nuitka

# Version + mode combination
docker tag evospikenet:nuitka myregistry/evospikenet:v1.0.0-nuitka