Skip to content

Production vs Development Mode

OneSeventyFour edited this page May 14, 2026 · 2 revisions

Production vs Development mode

Backyard Hero ships two ways to run the host stack. Both produce an identical web UI on http://localhost:1776; the difference is where the container's contents come from.

TL;DR

Property Production (start_prod.sh / .bat) Development (start_dev.sh / start.sh / start.bat)
Image Pulls os4ivmb/backyardhero:latest from Docker Hub Builds from host/Dockerfile against the local source tree
First-run time ~2 minutes (pull) ~10–15 minutes (npm ci + next build + python deps)
Disk footprint ~600 MB image, no source needed Source tree + image + node_modules (~3 GB)
Hot reload No — code lives inside the image Yes — byh_app/, pythings/ mounted as volumes
Recommended for Operators, field deployments, Pi installs Active development, contributors, anyone tweaking firmware integration
Compose file docker-compose-prod.yml docker-compose-dev.yml (or the legacy docker-compose.yml)

Production mode

This is what you want unless you're modifying the codebase.

What it actually does

  1. Starts the TCP-to-serial bridge as a host-native Python process (talks to /dev/tty.usbmodem* / /dev/ttyACM* / COMn).
  2. docker compose -f docker-compose-prod.yml pull — fetches the prebuilt image from Docker Hub.
  3. docker compose -f docker-compose-prod.yml up — starts the container.

The image embeds:

  • The pre-built Next.js app (next build already done at image build time).
  • The Python daemon, websocket server, and dependencies.
  • supervisord wiring everything together.

Pinning a specific version

The default tag is :latest. To pin to a specific build:

BYH_IMAGE=os4ivmb/backyardhero:v0.08 ./start_prod.sh

Available tags are listed at https://hub.docker.com/repository/docker/os4ivmb/backyardhero/general.

Updating

Just re-run ./start_prod.sh. The launcher always does a docker compose pull before bringing the stack up, so you'll automatically get the newest :latest (or your pinned tag).

To roll back: pin a previous version with BYH_IMAGE=....

Development mode

For when you're editing the UI, the daemon, or hooking in changed firmware behavior.

What it actually does

The dev compose file (host/docker-compose-dev.yml) is identical to production except:

  • build: . instead of image: ... — the image is built locally from host/Dockerfile.
  • ./pythings:/app/pythings and ./byh_app/backyardhero:/app/byh_app/ are bind-mounted into the container, so your local changes are visible immediately.
  • supervisord.dev.conf is used instead of supervisord.conf. The dev variant runs npm run dev (Next.js dev server with HMR) instead of npm run start (production build).
  • NODE_ENV=development.

When you change Python daemon code

The daemon (pythings/pc_daemon/pc_daemon.py) does not auto-reload. Restart the daemon process inside the container:

docker exec firework-system supervisorctl restart firework-daemon

(The Next.js app under npm run dev does auto-reload — saved JSX changes show up in the browser within a second.)

When you change firmware

Firmware (devices/os4_*/...) does not affect the Docker image at all. Build & flash separately:

devices/utils/build_receiver.sh
devices/utils/flash_receiver.py        # routine app-only update

For the dongle: see Flashing a Dongle.

Pushing your changes back to Docker Hub (maintainers)

If you've made changes you want to publish as the next :latest:

host/build_and_push_docker.sh                 # multi-arch build + push :latest and :v<host_version>
host/build_and_push_docker.sh --tag rc1       # add an extra :rc1 tag
host/build_and_push_docker.sh --no-push       # build locally only (single arch)

The script reads host_version from host/config/systemcfg.json and auto-tags :v<version>. You must docker login to the Docker Hub account that owns os4ivmb/backyardhero first.

Switching modes

Just run the other launcher script. The two compose files use the same container name (firework-system), so docker will refuse to bring up one stack while the other is running. docker compose down (or Ctrl-C the running launcher) first.

The on-disk state — host/data/backyardhero.db, host/config/systemcfg.json, host/data/state — is shared between modes. Receiver definitions, shows, and inventory carry over.

Clone this wiki locally