- Dockerfile: use --flash_size 4MB and drop OTA data from merge_bin (OTA data at 0xc10000 inflated binary to 12.6MB, exceeding 4MB chip flash) - main.go: seedFirmwareDir now overwrites when source size differs, fixing PVC staleness where old 1.6MB app-only binary was never replaced - onboard.js: renderFlashFirmware() rewritten so all elements (button, progress bar, status text, retry help, log panel) are inline in one container — no separate floating modal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
67 lines
2.2 KiB
Docker
67 lines
2.2 KiB
Docker
# Spaxel Mothership Dockerfile
|
|
# Multi-stage build: ESP32 firmware → Go binary → minimal runtime image
|
|
|
|
# Stage 1: Build ESP32-S3 firmware
|
|
FROM espressif/idf:v5.2 AS firmware-builder
|
|
|
|
WORKDIR /project
|
|
COPY firmware/ ./
|
|
|
|
# Source export.sh to activate IDF toolchain (entrypoint is not called in build stages).
|
|
# set-target must be run explicitly before build even when CONFIG_IDF_TARGET is in sdkconfig.defaults.
|
|
# idf.py build produces build/spaxel-firmware.bin
|
|
SHELL ["/bin/bash", "-c"]
|
|
RUN . $IDF_PATH/export.sh && idf.py set-target esp32s3 && idf.py build && \
|
|
python -m esptool --chip esp32s3 merge_bin \
|
|
--flash_mode dio --flash_freq 80m --flash_size 4MB \
|
|
--output build/spaxel-firmware-merged.bin \
|
|
0x0 build/bootloader/bootloader.bin \
|
|
0x8000 build/partition_table/partition-table.bin \
|
|
0x10000 build/spaxel-firmware.bin
|
|
|
|
# Stage 2: Build the Go binary
|
|
FROM golang:1.25-bookworm AS builder
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy Go module files first for better caching
|
|
COPY mothership/go.mod mothership/go.sum ./
|
|
RUN go mod download
|
|
|
|
# Copy source code
|
|
COPY mothership/ ./
|
|
|
|
# Build the binary
|
|
# CGO_ENABLED=0 because we use pure-Go SQLite (modernc.org/sqlite)
|
|
ARG VERSION=dev
|
|
RUN CGO_ENABLED=0 GOOS=linux go build \
|
|
-ldflags="-s -w -X main.version=${VERSION}" \
|
|
-o spaxel ./cmd/mothership
|
|
|
|
# Stage 2: Minimal runtime image
|
|
FROM debian:12-slim
|
|
|
|
# Install wget for health check
|
|
RUN apt-get update && apt-get install -y --no-install-recommends wget ca-certificates && rm -rf /var/lib/apt/lists/*
|
|
|
|
# Copy the binary
|
|
COPY --from=builder /app/spaxel /spaxel
|
|
|
|
# Copy dashboard static files (served from filesystem at runtime)
|
|
COPY dashboard/ /dashboard/
|
|
|
|
# Bake ESP32 firmware into the image so the mothership can seed it on first run.
|
|
# The mothership copies /firmware/*.bin → /data/firmware/ at startup if not present.
|
|
COPY --from=firmware-builder /project/build/spaxel-firmware-merged.bin /firmware/spaxel-firmware.bin
|
|
|
|
VOLUME ["/data"]
|
|
|
|
# Expose HTTP/WebSocket port
|
|
EXPOSE 8080
|
|
|
|
# Health check — verifies service responds with status=ok
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
|
|
CMD wget -qO- http://localhost:8080/healthz | grep -q '"status":"ok"' || exit 1
|
|
|
|
# Run as non-root
|
|
ENTRYPOINT ["/spaxel"]
|