shinyhub

module
v0.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 9, 2026 License: MIT

README

ShinyHub

PyPI CI

Self-hosted platform for deploying and operating R and Python Shiny applications. Push an app from the CLI, get a clean URL behind a built-in reverse proxy, sign users in with OAuth or OIDC, and let idle apps hibernate and wake on demand. ShinyHub runs as a single Go binary backed by SQLite, with no external services to operate.

ShinyHub dashboard showing the app grid with running apps and per-app CPU and memory

Contents

Features

  • Deploy from the CLI. shinyhub deploy uploads a bundle and brings the app up.
  • Reverse proxy. One URL per app under /app/<slug>/, sticky-session aware.
  • Hibernation. Idle apps are stopped automatically and restarted on the next request.
  • Authentication. Username/password, GitHub OAuth, Google OAuth, or generic OIDC (Okta, Azure AD, Keycloak, Auth0).
  • Access control. Public, private, or shared apps, with per-app member roles.
  • Env vars and secrets. Per-app key-value store; secrets encrypted at rest with AES-256-GCM. See docs/environment.md.
  • Persistent data dir. Each app gets a data/ directory that survives deploys, with shinyhub data push|ls|rm and a UI tab. See docs/data.md.
  • Scheduled jobs and shared data. Per-app cron schedules and read-only cross-app data mounts for fetcher to consumer pipelines. See docs/schedules.md.
  • Horizontal scaling. Set replicas: N to run multiple load-balanced backends per app, recovered independently on crash. See docs/scaling.md.
  • Fleet reconcile. Declare a whole set of apps in one shinyhub-fleet.toml and converge the server to match, kubectl-apply style. See docs/fleet.md.
  • Observability. OpenTelemetry tracing (proxy, app, and control-plane spans), an opt-in Prometheus /metrics endpoint, and a structured access log with request-ID and trace correlation. See docs/tracing.md and docs/metrics.md.
  • Container isolation (optional). Run each app inside a Docker container with CPU and memory limits.
  • Branding (white-label). Customize the front door (title, logo, theme, landing page) without forking. See docs/branding.md.
  • Audit log. Mutating actions recorded for admin review.
  • Single binary, SQLite, no external dependencies.

Quick start

mkdir -p ./data
cp shinyhub.yaml.example ./shinyhub.yaml
# Edit shinyhub.yaml: set auth.secret to the output of `openssl rand -hex 32`.

docker run -d \
  --name shinyhub \
  -p 8080:8080 \
  -v "$PWD/shinyhub.yaml:/etc/shinyhub/shinyhub.yaml:ro" \
  -v "$PWD/data:/data" \
  -e SHINYHUB_ADMIN_USER=admin \
  -e SHINYHUB_ADMIN_PASSWORD=change-me \
  ghcr.io/rvben/shinyhub:latest

The mount target /data matches the example YAML's ./data/... paths (database, bundles, and app data dir all land there). Open http://localhost:8080 and log in with the admin credentials you set.

PyPI

ShinyHub is published to PyPI, so uv or pip can install the CLI and server:

uv tool install shinyhub        # isolated tool venv
uvx shinyhub deploy ./my-app --slug demo   # one-shot, without installing
pip install shinyhub            # or via pip
Binary
curl -fsSL https://raw.githubusercontent.com/rvben/shinyhub/main/scripts/install.sh | sh
# Or download from https://github.com/rvben/shinyhub/releases

cp shinyhub.yaml.example shinyhub.yaml
# Set auth.secret to a 32-byte random value.

SHINYHUB_CONFIG=./shinyhub.yaml \
  SHINYHUB_ADMIN_USER=admin SHINYHUB_ADMIN_PASSWORD=change-me \
  shinyhub serve
From source
git clone https://github.com/rvben/shinyhub.git
cd shinyhub
go build -o bin/shinyhub ./cmd/shinyhub

Configuration

Every key is documented inline in shinyhub.yaml.example. Environment variables (prefixed SHINYHUB_) override the YAML.

The server resolves its config file in this order: the --config flag (shinyhub serve --config /path/to/shinyhub.yaml, also honored by backup and restore), then the SHINYHUB_CONFIG environment variable, then ./shinyhub.yaml.

The one required setting is auth.secret: a random 32+ character string (openssl rand -hex 32). The server refuses to start with the placeholder value.

Guides

Guide Topic
Environment and secrets Per-app env vars, encrypted secrets, and when to use them instead of files.
Persistent data dir Pushing data, the app-visible path, authorization, quota, and concurrency.
Scheduled jobs and shared data Per-app cron schedules and read-only cross-app data mounts.
Horizontal scaling Per-app replicas, load balancing, and session admission.
Fleet reconcile Declaring and converging a whole set of apps from one file.
Deploy manifest The shinyhub.toml bundle manifest.
Tracing OpenTelemetry propagation, app spans, and control-plane spans.
Metrics and logs The /metrics endpoint, exposed series, and the structured access log.
Branding White-label title, logo, theme, landing page, and footer links.
Reverse-proxy auth - Caddy Authenticate users via Caddy forward_auth and forward the identity to ShinyHub.
Reverse-proxy auth - nginx Authenticate users via nginx auth_request and forward the identity to ShinyHub.
OIDC bridge for LDAP/SAML Wrap an LDAP or SAML source with an OIDC bridge (Authelia, Authentik, Keycloak) and use ShinyHub's built-in OIDC login.

Architecture

┌────────────┐    HTTPS    ┌──────────────────┐
│  Browser   │────────────▶│    ShinyHub      │
└────────────┘             │                  │
                           │  ┌────────────┐  │
┌────────────┐    CLI      │  │  API + UI  │  │
│  shinyhub  │────────────▶│  ├────────────┤  │
│  deploy    │             │  │   Proxy    │──┼──▶  app processes
└────────────┘             │  ├────────────┤  │     (native or Docker)
                           │  │   SQLite   │  │
                           │  └────────────┘  │
                           └──────────────────┘

ShinyHub is one Go binary. shinyhub serve runs the HTTP API, the embedded dashboard UI, the reverse proxy, and the lifecycle watchdog against a single SQLite database; the same binary provides the developer subcommands (deploy, login, apps, env, data, and more). App processes run natively or inside Docker containers and are proxied per slug.

Status

Active development. ShinyHub is single-node and self-hosted (no clustering or HA) and is run in production by the maintainer, offered with no SLA or support guarantees. See CHANGELOG.md for the current release.

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md for development setup and conventions.

License

MIT

Directories

Path Synopsis
cmd
shinyhub command
cmd/shinyhub/worker.go
cmd/shinyhub/worker.go
internal
api
appenv
Package appenv turns an app's stored environment variables into the "KEY=VALUE" slices the runtime injects at start time.
Package appenv turns an app's stored environment variables into the "KEY=VALUE" slices the runtime injects at start time.
autoscale
Package autoscale provides a provider-agnostic replica autoscale controller.
Package autoscale provides a provider-agnostic replica autoscale controller.
backup
Package backup implements first-class snapshot and restore of all ShinyHub durable state: the SQLite database, deployed app bundles, and per-app data dirs.
Package backup implements first-class snapshot and restore of all ShinyHub durable state: the SQLite database, deployed app bundles, and per-app data dirs.
bundle
Package bundle defines the single source of truth for which files may appear inside a deploy bundle.
Package bundle defines the single source of truth for which files may appear inside a deploy bundle.
bundletoken
Package bundletoken mints and verifies short-lived capability tokens that authorise a single fetch of one content-addressed bundle.
Package bundletoken mints and verifies short-lived capability tokens that authorise a single fetch of one content-addressed bundle.
cli
data
Package data implements the persistent per-app storage area exposed via `PUT/DELETE/GET /api/apps/:slug/data[/*path]` and the `shinyhub data` CLI.
Package data implements the persistent per-app storage area exposed via `PUT/DELETE/GET /api/apps/:slug/data[/*path]` and the `shinyhub data` CLI.
db
dbtest
Package dbtest provides an env-aware store constructor for tests.
Package dbtest provides an env-aware store constructor for tests.
fargate
Package fargate provides a process.Runtime backend that runs each app replica as an AWS ECS task on the Fargate launch type.
Package fargate provides a process.Runtime backend that runs each app replica as an AWS ECS task on the Fargate launch type.
fleet
Package fleet implements the pure, I/O-free core of the fleet reconcile layer: manifest parsing, source-form classification, and the desired-vs- observed diff.
Package fleet implements the pure, I/O-free core of the fleet reconcile layer: manifest parsing, source-form classification, and the desired-vs- observed diff.
httproute
Package httproute propagates a matched HTTP route pattern through a request context as an immutable string.
Package httproute propagates a matched HTTP route pattern through a request context as an immutable string.
leader
Package leader elects a single owner control-plane instance via a fenced, DB-backed lease.
Package leader elects a single owner control-plane instance via a fenced, DB-backed lease.
logging
Package logging wires a process-wide slog.Logger based on env config.
Package logging wires a process-wide slog.Logger based on env config.
metrics
Package metrics exposes Prometheus instrumentation for the ShinyHub server process itself - HTTP request counts/latency for the control-plane API, the Go runtime and process collectors, and build/version + uptime gauges.
Package metrics exposes Prometheus instrumentation for the ShinyHub server process itself - HTTP request counts/latency for the control-plane API, the Go runtime and process collectors, and build/version + uptime gauges.
proxytrust
Package proxytrust centralises the trust gate that controls whether X-Forwarded-* request headers are honoured.
Package proxytrust centralises the trust gate that controls whether X-Forwarded-* request headers are honoured.
schedulespec
Package schedulespec defines schedule validation rules shared between the HTTP API and the deploy-manifest application path.
Package schedulespec defines schedule validation rules shared between the HTTP API and the deploy-manifest application path.
secrets
Package secrets encrypts and decrypts small values (env var secrets) using AES-256-GCM with a key derived from the server's auth secret via HKDF-SHA256.
Package secrets encrypts and decrypts small values (env var secrets) using AES-256-GCM with a key derived from the server's auth secret via HKDF-SHA256.
servertrace
Package servertrace adds optional OpenTelemetry tracing for the ShinyHub server process itself - spans for the control-plane API request handling, exported to the same OTLP endpoint the managed apps use.
Package servertrace adds optional OpenTelemetry tracing for the ShinyHub server process itself - spans for the control-plane API request handling, exported to the same OTLP endpoint the managed apps use.
slug
Package slug holds the canonical slug-validation regex shared by the API server, CLI, and any future surface that needs to validate or display the rules.
Package slug holds the canonical slug-validation regex shared by the API server, CLI, and any future surface that needs to validate or display the rules.
storage
Package storage owns ShinyHub's on-disk and pluggable storage concerns: the on-disk lifecycle helpers shared by the API and CLI (the slug-keyed convention for per-app directories, one under Storage.AppsDir for code and one under Storage.AppDataDir for persistent data), plus the DataVolume abstraction that provisions per-app mutable data on a single host's local disk (or, in a later phase, a shared backend).
Package storage owns ShinyHub's on-disk and pluggable storage concerns: the on-disk lifecycle helpers shared by the API and CLI (the slug-keyed convention for per-app directories, one under Storage.AppsDir for code and one under Storage.AppDataDir for persistent data), plus the DataVolume abstraction that provisions per-app mutable data on a single host's local disk (or, in a later phase, a shared backend).
tracing
Package tracing implements lightweight W3C-trace-context propagation through the reverse proxy and a per-app ring buffer of recent slow/error proxy spans for the UI's Traces tab.
Package tracing implements lightweight W3C-trace-context propagation through the reverse proxy and a per-app ring buffer of recent slow/error proxy spans for the UI's Traces tab.
ui
upgrade
Package upgrade wraps github.com/cloudflare/tableflip behind a small interface so ShinyHub can perform zero-downtime, listener-preserving restarts (SIGHUP handoff) and unit-test the wiring with a fake.
Package upgrade wraps github.com/cloudflare/tableflip behind a small interface so ShinyHub can perform zero-downtime, listener-preserving restarts (SIGHUP handoff) and unit-test the wiring with a fake.
worker
internal/worker/ca.go
internal/worker/ca.go
worker/agent
internal/worker/agent/agent.go
internal/worker/agent/agent.go
worker/api
Package api defines the JSON request/response types and the NDJSON streaming framing that form the wire contract between the ShinyHub control plane and a worker agent.
Package api defines the JSON request/response types and the NDJSON streaming framing that form the wire contract between the ShinyHub control plane and a worker agent.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL