A graphical control plane for Hauler, built by AlphaBravo.
A graphical, single-container control plane for Rancher Government Hauler — manage isolated airgap content stores and serve them to disconnected clusters, no CLI required.
NOTE: This project is in ALPHA while we test it. We will release a stable version in the coming weeks.
Wagon is a single-container web application that provides full operational parity with the Hauler CLI. It wraps the power of Hauler's command-line interface in an intuitive graphical experience, making airgap operations accessible to users of all skill levels.
- Multi-Haul Workspaces — First-class isolated hauls, each with its own content store; operate on them independently
- Store Operations — Add images, charts, and files to your store; sync registries; save/load archives; extract content
- Registry Management — Login/logout to Docker Hub, GHCR, and other container registries
- Publishing — Expose every published haul through a single host-routed registry front door (plus direct file serving at
/h/), with TLS; registries start on demand and idle-reap - Serve Operations — Start an embedded container registry or HTTP fileserver
- Job Management — Background task execution with streaming logs and job history
- Manifest Management — Create and edit Hauler manifests with Monaco editor
- Authentication — Optional password-based UI access control
- Observability — Prometheus metrics at
/metrics, liveness/healthz+ readiness/readyzprobes, and structured JSON logging - Single Container — Everything packaged in one Alpine-based image for simple deployment
# Run with default configuration
docker run -d \
--name wagon \
-p 8080:8080 \
-v wagon-data:/data \
ghcr.io/alphabravo-oss/wagon:latest
# Or use Docker Compose
docker-compose -f deploy/docker-compose.yml up -dAccess the UI at http://localhost:8080
- Open the UI — Navigate to
http://localhost:8080in your browser - Configure Hauler — Set global flags in Settings if needed
- Login to a Registry — Use the Registry page to authenticate (e.g., Docker Hub)
- Add Content — Go to Store → Add, and add an image, chart, or file
- Save Your Store — Use Store → Save to create a portable archive
- Go 1.24+
- Node.js 20+
- Make (optional, for convenience commands)
wagon/
├── backend/ # Go backend server
│ └── internal/ # Internal packages
│ ├── auth/ # Authentication & sessions
│ ├── config/ # Configuration management
│ ├── hauler/ # Hauler CLI integration
│ ├── jobrunner/ # Background job execution
│ ├── manifests/ # Manifest CRUD operations
│ ├── registry/ # Registry login/logout
│ ├── serve/ # Registry & fileserver serving
│ ├── settings/ # Global settings management
│ ├── sqlite/ # Database operations
│ └── store/ # Store operations
├── web/ # React frontend
│ └── src/
│ ├── components/ # Reusable UI components
│ ├── contexts/ # React Context providers
│ ├── pages/ # Page components
│ └── lib/ # Utilities and API client
└── deploy/ # Deployment configurations
# Install dependencies
make deps
# Run backend (terminal 1)
cd backend && go run .
# Run frontend (terminal 2)
cd web && npm run dev
# Access at http://localhost:5173# Build everything
make build
# Build backend only
make build-backend
# Build frontend only
make build-frontend
# Run tests
make test
# Lint code
make lintWagon is configured via environment variables.
HAULER_UI_*names remain supported as the stable configuration interface for compatibility with existing deployments; they now configure Wagon.
| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
HTTP UI/API server port (now honored in code) |
HAULER_UI_PASSWORD |
(empty) | Optional shared password for UI login; empty disables auth |
HAULER_UI_LOGIN_RATE |
5 |
Max login attempts per minute per client IP (429 beyond) |
HAULER_UI_TRUST_PROXY |
false |
When true, trust the rightmost X-Forwarded-For hop for login rate-limit IP keying (only behind a trusted reverse proxy) |
| Variable | Default | Description |
|---|---|---|
HAULER_UI_REGISTRY_PORT |
5000 |
Single host-routed port serving all published haul registries |
HAULER_UI_REGISTRY_DOMAIN |
(empty) | Base domain for <slug>.<domain> registry routing |
HAULER_UI_REGISTRY_IDLE |
5m |
Idle timeout before a published registry subprocess is reaped (Go duration) |
HAULER_UI_REGISTRY_TLS_CERT |
(empty) | Path to a TLS cert for the registry port (self-signed if unset) |
HAULER_UI_REGISTRY_TLS_KEY |
(empty) | Path to the TLS key |
HAULER_UI_PUBLISH_USER |
(empty) | HTTP Basic auth username guarding the published registry and /h/ file endpoints. If both user & password are empty the endpoints are OPEN (a startup WARNING is logged) |
HAULER_UI_PUBLISH_PASSWORD |
(empty) | Basic auth password for the above |
| Variable | Default | Description |
|---|---|---|
HAULER_UI_MAX_CONCURRENT_JOBS |
2 |
Max background jobs run at once |
HAULER_UI_LOG_FORMAT |
json |
UI server log format: json or text |
HAULER_UI_LOG_LEVEL |
info |
UI server log level: debug | info | warn | error |
| Variable | Default | Description |
|---|---|---|
HAULER_BINARY |
hauler |
Hauler binary name/path |
HAULER_LOG_LEVEL |
info |
Hauler CLI log level |
HAULER_IGNORE_ERRORS |
false |
Continue operations despite errors |
HAULER_RETRIES |
0 |
Retries for hauler ops (also settable in the Settings UI) |
HAULER_DIR |
/data |
Hauler working directory |
HAULER_STORE_DIR |
/data/store |
Store directory path |
HAULER_TEMP_DIR |
/data/tmp |
Temporary files directory |
DOCKER_CONFIG |
/data/.docker |
Docker auth config directory |
DATABASE_PATH |
/data/app.db |
SQLite database path |
Source of truth: See
deploy/.env.examplefor the complete list of documented environment variables.
All persistent data is stored in /data:
- Hauler store — Container images, charts, and files
- SQLite database — Jobs, settings, and manifests (
app.db) - Docker config — Registry authentication (
.docker/config.json)
Mount this directory as a volume to persist data across container restarts.
services:
wagon:
image: ghcr.io/alphabravo-oss/wagon:latest
ports:
- "8080:8080" # Main UI
- "5000:5000" # Registry serve
- "5001:5001" # Fileserver serve
volumes:
- wagon-data:/data
environment:
- HAULER_UI_PASSWORD=your-password # Optional
volumes:
wagon-data:You can deploy Wagon to Kubernetes using the Docker image. Ensure to:
- Create a PersistentVolumeClaim for
/data - Set environment variables as needed
- Expose the service on your desired port
Example deployment configuration is available in deploy/kubernetes/.
# Build multi-stage Docker image
make docker-build
# Tag for your registry
docker tag wagon:latest your-registry/wagon:latest
# Push to registry
docker push your-registry/wagon:latest- Standard library HTTP server — No external web framework
- SQLite (WAL mode) — Embedded database for persistence
- SSE (Server-Sent Events) — Real-time log streaming
- Async job runner — Background process execution
- Lazy publish registries — Published haul registries start on demand and are idle-reaped
- React 19.1 — Modern React with hooks
- Vite 8 — Fast build tool and dev server
- React Router 7 — Client-side routing
- Monaco Editor — VS Code editor for manifests
- Custom CSS — Lightweight styling without frameworks
We welcome contributions! Please follow these guidelines:
- Write tests for new functionality
- Run
make lintbefore committing - Follow existing code style and patterns
- Update documentation as needed
Copyright © 2025 Rancher Government, Inc.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
- Issues: GitHub Issues
- Documentation: Hauler Docs
- Community: Rancher Government Slack
- Issues: GitHub Issues
- Documentation: Documentation
AlphaBravo is a SDVOSB Company providing DevSecOps / Cloud / AI solutions to Government and Commercial organizations. We are committed to delivering secure and innovative technology solutions tailored to your needs.
For more information visit us at https://alphabravo.io.
