Skip to content

Containerised dev deployment (hot-reload, restart-on-boot) - #1

Open
lightspeed-internal-1[bot] wants to merge 1 commit into
mainfrom
docker-dev-deployment
Open

lightspeed-internal-1[bot] wants to merge 1 commit into
mainfrom
docker-dev-deployment

Conversation

@lightspeed-internal-1

Copy link
Copy Markdown

Adds an optional Docker setup for running Imaginator on a long-lived dev/demo box, where two things matter: the app should come back after a reboot, and it should be editable in place.

Approach

Source is bind-mounted rather than baked into the image, and the server runs under tsx watch. Editing packages/server or packages/core reloads in ~4s with no rebuild; packages/web edits need ./ctl.sh web (~3s), since the server already serves packages/web/dist whenever it exists — so the UI stays on the same single port.

Files

  • Dockerfile.dev — node:22-bookworm-slim, build tools for the native deps, pnpm 10.15.1
  • docker-compose.ymlrestart: always, publishes 8080, env_file: .env, healthcheck on /api/health
  • docker-entrypoint.sh — installs deps and builds web when missing, then starts the server in watch mode
  • ctl.shstatus|logs|web|restart|up|down|shell|reinstall
  • .gitignore — ignore .pnpm-store/

Notes

  • node_modules live in named volumes, not on the host. better-sqlite3 and sharp are native and must be built against the container rather than the host's Node. ./ctl.sh reinstall wipes those volumes and reinstalls.
  • The data dir stays a host bind-mount, so the SQLite DB and generated assets sit outside the container layer and survive rebuilds and down/up. Verified by migrating a running instance from bare-metal into the container with assets intact.
  • ctl.sh takes the public URL from IMAGINATOR_PUBLIC_URL and otherwise checks localhost only, so nothing environment-specific is committed.
  • Nothing existing changes behaviour: all new files, plus one .gitignore line. run.sh is untouched and still the right tool for local work.

Caveat

restart: always restores the container on daemon start, which covers reboots given an enabled docker.service. This has not been verified against a real VM stop/start yet. Note also that docker kill/docker stop are treated as manual stops and deliberately do not trigger the restart policy, so they are not valid tests of it.

Runs Imaginator in Docker with the source bind-mounted, so the server
hot-reloads on edit instead of needing an image rebuild. Aimed at
long-lived dev/demo boxes where the app should come back by itself after
a reboot.

- Dockerfile.dev: node:22 + pnpm, source not baked in
- docker-compose.yml: restart=always, port 8080, node_modules in named
  volumes (better-sqlite3 and sharp are native and must match the
  container, not the host), healthcheck on /api/health
- docker-entrypoint.sh: install deps and build web when missing, then run
  the server under tsx watch
- ctl.sh: status/logs/web/restart/up/down/shell/reinstall

The data dir stays a host bind-mount, so the SQLite DB and generated
assets live outside the container layer and survive rebuilds.

Server and core edits reload in ~4s; web edits need ./ctl.sh web.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants