A containerized hosting platform for Shiny applications, built in Go. Blockyard manages the deployment, scaling, and reverse-proxying of isolated R Shiny app containers using Docker.
Blockyard acts as a reverse proxy and application server that spawns an isolated worker per user session. Workers run in one of two backends:
- Docker/Podman (default) — each worker is a container with a private bridge network and cgroup resource limits.
- Process (bubblewrap) — each worker is a
bwrap-sandboxed child process with PID/mount/user namespaces and capability dropping, no container runtime required.
The server is generic over a Backend interface, so the two runtimes are interchangeable. See Backend Security for the trade-offs.
Key design choices:
- One content type: Shiny / blockr apps (not Plumber APIs, static sites, or scheduled tasks)
- Linux host required (bubblewrap is Linux-only; Docker/Podman usable on macOS via Docker Desktop)
- Per-session worker isolation by default
graph LR
Client[Client Request] --> Router[Chi Router]
Router --> Auth["Auth (OIDC)"]
Auth --> Proxy[Reverse Proxy]
Proxy --> Worker["Worker<br>(Docker container or<br>bwrap process)"]
Router --> DB["SQLite/Postgres<br>(app & bundle metadata)"]
Worker --> Bao["OpenBao<br>(credentials)"]
- Go 1.25 with standard library
net/http - Chi — HTTP router with middleware support
- Docker SDK — Docker API client (
github.com/docker/docker), used by the Docker backend - bubblewrap —
bwrapsandbox helper, used by the process backend - modernc.org/sqlite — pure-Go SQLite driver
- Redis — optional shared state for rolling updates and multi-server coordination (
redis/go-redis) - OIDC — OpenID Connect authentication (
coreos/go-oidc/v3) - OpenBao — credential management (Vault-compatible)
- Prometheus — metrics (
prometheus/client_golang) - OpenTelemetry — distributed tracing
- log/slog — structured JSON logging
- Go 1.25+
- A Linux host (Windows and macOS supported for the Docker backend via Docker Desktop)
- Either:
- Docker backend: Docker or Podman with a Docker-compatible socket, or
- Process backend:
bubblewrapandRon the host. See Process Backend (Native).
- SQLite 3 (bundled in-binary via
modernc.org/sqlite)
Copy and edit the example configuration:
cp blockyard.toml blockyard.toml.localAll settings can be overridden with environment variables using the
BLOCKYARD_<SECTION>_<FIELD> pattern (uppercased). For example,
server.bind becomes BLOCKYARD_SERVER_BIND.
# Build
go build -o blockyard ./cmd/blockyard
# Run tests
go test ./...A devcontainer configuration is included for VS Code / GitHub Codespaces:
# Open in VS Code with the Dev Containers extension
code .
# Then: Reopen in ContainerNative mode (go run ./cmd/blockyard directly) requires that Docker
container IPs on bridge networks are routable from the host. This is the
case on Linux and with some macOS Docker runtimes, but not all. If
container IPs are not routable from your host, run the server inside a
container (e.g. the devcontainer) instead.
cmd/blockyard/— Server entry point.cmd/by/— CLI client (by) for deploying apps, managing access, and server administration.cmd/by-builder/— Helper binary mounted into build containers to run dependency restores.cmd/seccomp-compile/— Build-time tool that compiles JSON seccomp profiles to the BPF blob shipped inside theblockyard-processimage.docker/— Dockerfiles for the three image variants (server.Dockerfile,server-process.Dockerfile,server-everything.Dockerfile).internal/— All application code, organized by domain:api/— HTTP handlers for the management API (apps, bundles, users, tags, admin update, etc.)auth/,authz/— OIDC authentication, session management, RBAC, and per-app ACLs.proxy/— Reverse proxy, WebSocket forwarding, cold-start, session routing, autoscaling.backend/— Worker runtime abstraction:docker/— Docker/Podman backend.process/— bubblewrap process backend.mock/— in-memory backend for tests.
bundle/— Bundle archive storage, unpacking, and R dependency restoration.db/— SQLite/PostgreSQL database layer, migrations, and CRUD queries.drain/— Graceful drain mode used by the rolling-update orchestrator.integration/— OpenBao (Vault) client, bootstrapping, and credential enrollment.orchestrator/— Rolling-update state machine with Docker (container clone) and process (fork+exec) variants.preflight/— Shared startup-check plumbing; backend-specific checks live under each backend.redisstate/— Redis-backed implementations of session/worker/resource stores.seccomp/— Embedded seccomp profiles (outer-container and bwrap-inner) and the merge tool.config/,server/— TOML/env configuration and shared server state.ops/— Health polling, log capture, orphan cleanup.audit/,telemetry/— Audit logging, Prometheus metrics, OpenTelemetry tracing.
migrations/— SQL migration files.
Operator and user documentation lives under docs/content/docs/ and is rendered with Hugo. Highlights:
- Installation, Quick Start
- Deploying an app
- Authorization, Credential management
- Backend Security — Docker vs. process backend trade-offs
- Process Backend (Native) / (Containerized)
- Observability
- Reference: configuration, CLI, REST API
See blockyard.toml for a commented example
configuration and Configuration File
for the full field-by-field reference.
Blockyard is in early development. See docs/design/roadmap.md for the full plan.
This project is licensed under the GNU General Public License v3.0.