Skip to content

feat(devcontainer): one-click osprey demo in github codespaces - #593

Draft
reitblatt wants to merge 3 commits into
mainfrom
reitblatt/codespaces-ux
Draft

reitblatt wants to merge 3 commits into
mainfrom
reitblatt/codespaces-ux

Conversation

@reitblatt

@reitblatt reitblatt commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds a devcontainer so anyone, including non-engineers, can click Open in GitHub Codespaces, wait a few minutes, and get the Osprey UI in their browser with demo data flowing, without typing any commands.

It requires a 4-core/16GB host, which is $0.36/hour.

Right now it takes a few (~3-5) minutes to spin up, but I've enabled a daily 'prebuild' in our codespaces, so it should be super fast next time!

This required a small change to osprey_ui to proxy '/api'. Previously we hardcoded REACT_APP_API_BASE_URL=http://localhost:5004, which doesn't behind Codespace forwarding. We know have an optional override (OSPREY_UI_API_PROXY_TARGET, default http://localhost:5004).

This PR also fixes a bug in the test-data producer where it would never recover after a Docker restart. Happy to spin that out to a separate PR if desired.

Adds documentation for developing on codespaces, and an 'Open in Github Codespaces' badge in the README.

Testing

Built and ran the devcontainer with @devcontainers/cli@0.80.2 (up) in a Coder workspace (8 cores, 51 GB, Docker 29.9). I didn't create a real Codespace.

Scenario Time to "Osprey is ready" (incl. fresh events)
Cold: no images or volumes cached 146 s: 52 s devcontainer image + feature, 18 s pull, 44 s build, 31 s start
Warm: container stopped and started again (codespace resume) 44–49 s

The workspace's network and CPUs are fast, so expect a cold start without a prebuild to take several times longer in a real codespace.

  • Browser walkthrough with headless Chromium (Playwright 1.52), loading the UI from a fake demo-codespace-5002.app.github.dev host to mimic the forwarded origin. It checked that no request leaves that origin (0 did) and that no request fails (0 did). It covered Submit Query, the event stream, the See Details popup, the RegexMatch(target=PostText, pattern="hello") query, the banner's pre-filled link (Top N by UserId), the user labels panel (meow), Rules Visualizer, Rules, Saved Queries and the UDF registry.
  • Resume: before the producer fix, no new events arrived after a restart (Kafka offsets unchanged for 4 minutes). After the fix, the producer restarts once and events reach Druid within seconds.
  • Memory once running: about 4.5 GiB across containers, 5.4 GiB for the devcontainer. Disk: about 6.5 GB images plus 2.3 GB build cache.
  • pre-commit run --all-files passes, except eslint-osprey-ui, which can't run here without osprey_ui/node_modules (CI skips that hook too). pnpm run lint (0 errors), typecheck and build pass, run inside the UI container.

Locally (not on Codespaces), the Docker-in-Docker feature's dockerd failed on this workspace's Linux 7.0 kernel (can't initialize iptables table 'nat': no legacy iptables). I switched the devcontainer to iptables-nft for testing. The guide's "For engineers" section mentions it.

Needs a real Codespace to confirm

  • The *.app.github.dev forwarding itself: private-port auth, openBrowserOnce with a port published by docker-proxy, HMR websocket through the proxy.
  • That a prebuild captures the Docker-in-Docker images (/var/lib/docker volume), so a prebuilt codespace skips prepare.sh's pulls.
  • Real cold and warm times on a 4-core machine, and whether anonymous Docker Hub pulls hit rate limits. prepare.sh signs in if DOCKERHUB_USERNAME/DOCKERHUB_TOKEN Codespaces secrets exist, and says what to do if a pull is rate-limited.
  • Whether only editor activity counts towards the idle timeout, so presenting from the UI tab for 30+ minutes could stop the codespace. The guide warns about it.

Recommended repository settings (not changed)

Settings → Codespaces → Set up prebuild:

  • Branch main, configuration .devcontainer/devcontainer.json.
  • Trigger: On configuration change. Code is bind-mounted into the worker, API and UI containers, so images only need rebuilding when the devcontainer, Dockerfiles or lockfiles change. Prebuilds can't trigger on those paths, so if uv.lock/pnpm-lock.yaml changes should land in prebuilds promptly, use Scheduled, daily instead.
  • Regions: US East (and Europe West if many users are in Europe). Each region stores its own copy of the snapshot.
  • Template history: 1 version, to keep storage down.
  • Failure notifications: a maintainer or team.

Org Codespaces policies, if roostorg pays for members' codespaces: allow the 4-core machine type, set a spending limit, and consider a max idle timeout around 60 minutes for demos.

Approval items

New third-party images and features (dependencies). ✅ Approved by mark on 2026-10-30:

Item Source License
mcr.microsoft.com/devcontainers/base:ubuntu-24.04 devcontainers/images MIT (image definition); bundles Ubuntu packages under their own licenses
ghcr.io/devcontainers/features/docker-in-docker:2 devcontainers/features MIT; installs Moby/Docker CE (Apache-2.0)

I used @devcontainers/cli and the Playwright image only for testing; neither is added to the repo.

Dependabot didn't cover these: .github/dependabot.yml only listed uv and github-actions. ✅ With mark's approval, this PR adds a devcontainers entry (weekly, 7-day cooldown, dependencies/dependabot labels, like the other ecosystems), so feature bumps such as docker-in-docker arrive on their own. It's appended at the end of the file and merges cleanly with the open #552 and #570. The devcontainers ecosystem only updates features; the mcr.microsoft.com/devcontainers/base:ubuntu-24.04 image tag isn't something it bumps, but that tag is a rolling Ubuntu 24.04 tag, so it picks up rebuilt images on its own.

Follow-ups (not in this PR)

  • ContainsHello == True matches nothing: Druid 34's schema discovery stores booleans as 0/1, and the query translator sends "value": true. Getting Started, demo.sh, concepts.md and rules/examples.md all suggest that query. fix(query): match boolean features the way Druid stores them #594 fixes it in the query translator; until it merges, the Codespaces guide uses RegexMatch(target=PostText, pattern="hello"), which works either way.
  • The Query page runs nothing on first load: there's no start/end in the URL, but it shows "Last Day". Codespaces can only auto-open the port's root, so the guide says to click Submit Query, and the banner prints a pre-filled link. With an empty range, /events/topn returns 400 and the client throws Cannot read properties of undefined (reading 'length').

claude-agent and others added 2 commits October 30, 2026 20:44
Add a devcontainer that runs the full demo stack with synthetic data in
GitHub Codespaces (or any devcontainer tool) with no commands to type:
Docker-in-Docker on a 4-core / 16 GB machine, images pulled and built in
updateContentCommand (prebuild-friendly), the stack started and checked
in postStartCommand on every start or resume, and status shown on attach.

- The UI dev server proxies /api to the UI API, and the devcontainer's
  compose override points the UI at /api, so the browser only talks to
  the forwarded UI port. Codespaces forwards each port as its own
  login-protected origin, so localhost:5004 can't work there.
- The test-data producer now exits when its Kafka producer dies, so its
  restart policy retries. Before, a Docker restart that started it before
  Kafka left it printing "Sending" forever with no events flowing.
- Docs: a step-by-step Codespaces guide for non-engineers, an "Open in
  GitHub Codespaces" badge in the README, and AGENTS.md run instructions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Covers the docker-in-docker feature in .devcontainer/devcontainer.json,
with the same weekly schedule, cooldown and labels as the other
ecosystems.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant