onlyn00bs-badge

OnlyN00bs: a DEF CON 34 friend-finder badge. ESP32 firmware, Web Bluetooth setup app, printable case
git clone https://git.virtualshack.io/onlyn00bs-badge.git
Log | Files | Refs | README | LICENSE

docker.md (3931B)


      1 # Docker: reproducible build environment
      2 
      3 Spin up the firmware build toolchain on any machine without installing
      4 PlatformIO, the pioarduino platform, or the xtensa toolchain by hand. The
      5 [`Dockerfile`](../Dockerfile) at the repo root bakes all of that in, pinned, so
      6 a build on your laptop and a build in CI produce the same artifacts.
      7 
      8 > **Scope:** this containerizes **building**. It does **not** containerize
      9 > flashing or provisioning — those touch host hardware (USB serial, Bluetooth)
     10 > that Docker Desktop can't reach on macOS/Windows. See *Flashing* below.
     11 
     12 ## What's pinned
     13 
     14 | Layer | Pin | Where |
     15 |---|---|---|
     16 | PlatformIO Core | `6.1.19` | `ARG PLATFORMIO_VERSION` in the Dockerfile (matches the dev machine) |
     17 | Arduino platform | pioarduino `55.03.38` (core 3.x / IDF 5.x) | `[core3x]` in `firmware/platformio.ini` |
     18 | Base image | `python:3.13-slim` | Dockerfile |
     19 | Libs | NimBLE-Arduino `^2.1.0`, U8g2 `^2.35.30` | `firmware/platformio.ini` |
     20 
     21 The image build **self-verifies**: it compiles `esp32dev_v3` + `oled_v3` as its
     22 final step, so `docker build` failing means the firmware doesn't compile.
     23 
     24 ## Build the image
     25 
     26 ```sh
     27 # from the repo root
     28 docker build -t badge-fw .
     29 ```
     30 
     31 First build pulls the base image + pioarduino platform + xtensa toolchain (a few
     32 hundred MB, one time); they're cached in the image afterwards, so later container
     33 builds are fast and need no network.
     34 
     35 ## Build firmware
     36 
     37 Two modes:
     38 
     39 **A) Baked-in source** (self-contained — good for CI / a clean checkout):
     40 ```sh
     41 docker run --rm badge-fw pio run -e oled_v3        # the badge build (default env)
     42 docker run --rm badge-fw pio run -e esp32dev_v3    # serial dev build (deprecated)
     43 ```
     44 
     45 **B) Live working tree** (iterate on the host, build in the container):
     46 ```sh
     47 docker run --rm -v "$PWD/firmware:/project" badge-fw pio run -e oled_v3
     48 ```
     49 The mount shadows the baked-in source with your edits; the toolchain cache
     50 (`/opt/pio`) is separate, so builds still run offline. Build artifacts land in
     51 `firmware/.pio/build/<env>/` on the host (already git-ignored).
     52 
     53 > On Linux, a bind-mounted build writes `.pio` as root. Add `--user "$(id -u):$(id -g)"`
     54 > if you want host-owned artifacts.
     55 
     56 ## Get the binary out (baked-in mode)
     57 
     58 ```sh
     59 id=$(docker create badge-fw)
     60 docker cp "$id:/project/.pio/build/oled_v3/firmware.bin" ./firmware.bin
     61 docker rm "$id"
     62 ```
     63 (Mode B writes it straight to `firmware/.pio/build/...` on the host — no copy needed.)
     64 
     65 ## Flashing
     66 
     67 Flashing needs a USB serial port, which **Docker Desktop on macOS/Windows cannot
     68 pass into a container**. So:
     69 
     70 - **macOS / Windows:** build in the container, **flash from the host** with your
     71   local PlatformIO (`cd firmware && pio run -e oled_v3 -t upload`), or flash the
     72   extracted `firmware.bin` with esptool. (Host serial notes live in the
     73   `esptool-serial-access` memory.)
     74 - **Linux host:** you *can* flash from the container by passing the device:
     75   ```sh
     76   docker run --rm --device=/dev/ttyUSB0 -v "$PWD/firmware:/project" \
     77       badge-fw pio run -e oled_v3 -t upload --upload-port /dev/ttyUSB0
     78   ```
     79   (`/dev/ttyACM0` for native-USB boards.)
     80 
     81 ## Provisioning
     82 
     83 The Web-Bluetooth provisioning page (`provisioning/index.html`) is a **host +
     84 browser** task — BLE doesn't cross the container boundary, and it needs
     85 Chrome/Edge with Web Bluetooth. Serve it on the host:
     86 `cd provisioning && python3 -m http.server 8000`.
     87 
     88 ## Maintaining
     89 
     90 - **Bump PlatformIO Core:** change `ARG PLATFORMIO_VERSION` and rebuild. Keep it
     91   matched to the dev machine's `pio --version`.
     92 - **Bump the Arduino platform:** edit the pioarduino tag in
     93   `firmware/platformio.ini` (`[core3x]`) — the Dockerfile picks it up, no Docker
     94   edit needed.
     95 - **A new env that pulls new libs:** the warm layer installs deps for
     96   `esp32dev_v3` + `oled_v3`; if you add an env you want pre-warmed, add it to the
     97   `pio pkg install` line. Other envs still build, they just fetch their platform
     98   on first use.