v1.0 · open source Proxmox VE 7 / 8 MIT licensed

Your homelab hired a goblin.

GoblinDock turns "spin up a fully-configured VM" into a few clear buttons. Stack Lego-style blocks into a golden image, hit deploy, and the goblin does the boring parts — cloud-init, Ansible, console and all.

One container · one SQLite file · no Redis, no Postgres, no moving parts.

The GoblinDock goblin operating a crane
VM deployed42s · agent reported IP
golden image4 blocks baked
console livenoVNC + serial

One container. Everything inside.

Python FastAPI Uvicorn SQLite · WAL proxmoxer ansible-runner cloud-init paramiko React CodeMirror xterm.js noVNC Docker
The flow

Three steps from a raw cloud image to a running VM.

Upload the raw material, bake it into something deployable, then summon as many copies as you like — each one configured on the way up.

01 · RAW MATERIAL

Add a base image

Give GoblinDock a public cloud image URL — Ubuntu 24.04 LTS, for example. It downloads and imports it into Proxmox as the starting point every build is cut from.

ISO · base image
02 · BAKE

Bake a golden image

Stack the blocks you want — packages, Docker, users, scripts — and GoblinDock runs them on a throwaway VM, cleans it up, and saves the result as a reusable Proxmox template.

golden image = base + blocks
03 · SUMMON

One-click deploy

Pick a golden image, choose a size and an optional recipe, and click deploy. GoblinDock clones it, finishes configuring it on first boot, and tells you the IP once it's up.

deploy ± a recipe
In the toolbox

Everything a homelab needs to stop hand-building VMs.

Provisioning, configuration, lifecycle and a real console — bundled into one panel your whole household (or team) can share.

Lego-style blocks

29 built-in blocks plus your own — install packages, write files, run scripts, add Docker, drop in Claude Code. Fork a built-in to customise it.

A real graphical console

The same noVNC console Proxmox uses, plus an xterm.js serial tab — proxied so the browser only ever talks to GoblinDock.

Live jobs over SSE

Every long action is a job with a step checklist, progress bar and a streaming log. Watch the goblin work in real time.

Multi-user, properly isolated

First-run admin setup, Admin / User roles, per-user VM isolation, per-target resource ceilings and an audit log. A non-admin only ever sees their own VMs and a redacted view of everything else.

Recipes on top, at deploy time

A recipe is an image-independent bundle of blocks applied per-deploy — AI Dev Box, MySQL node, whatever you name it. Same blocks, baked once into a golden or layered fresh onto every clone.

Full lifecycle, from the dashboard or the detail page

Start, stop, restart, rebuild or destroy — with live CPU / RAM / disk, full config, guest-agent OS & network info, and the deployment log all on one per-VM page. A rebuilt VM even keeps its static IP and VLAN.

The part people are curious about

Stack blocks. GoblinDock compiles them.

When you stack several blocks, GoblinDock doesn't run them one-by-one as separate executions — it merges them by phase. Same phase, one execution, in canvas order.

On the canvas — 4 blocks
Base OS Setup cloud-init
Install Packages ansible
Docker CE ansible
Run Script ansible
first boot — cloud-init runcmd 1 script · as root
# one script, runs as root
set -e
echo '>>> GoblinDock: Base OS Setup'
timedatectl set-timezone UTC
localectl set-locale LANG=en_US.UTF-8
post-boot — one ansible playbook 1 play · 3 tasks
- name: deploy-gd-vm
  hosts: all
  become: true
  tasks:
    - name: Install Packages   # task 1
    - name: Install Docker CE   # task 2
    - name: Run Script         # task 3

Three ansible blocks aren't three SSH sessions — they're three tasks in one playbook, run in order. See the exact generated YAML any time with View YAML in the builder.

Look inside the lair

A control room, not a config file.

A vendored React SPA — no build step — served straight from the container. Mono-forward, goblin-gold, dark by default.

The block builder

Drag blocks into sections. Watch the image take shape.

Compose a golden image from typed blocks — each tagged cloud-init or ansible — grouped into OS Setup, Install, Configure, Scripts and Cleanup.

  • Built-in palette plus My blocks — search, drag, drop.
  • Per-block inputs in the inspector — versions, packages, scripts.
  • View YAML to see exactly what gets compiled.
localhost:8080/build/golden
GoblinDock block builder
The dashboard

Every VM you're allowed to see, one screen.

Table or cards, filter by status, search by name. Auto-refreshing, role-filtered, and it names & tracks each VM for you.

  • Running / working / error counts at a glance.
  • Deploy VM from anywhere — it's always one click away.
  • Read-only state endpoint — no live-probing other users' VMs.
localhost:8080/operate/vms
GoblinDock dashboard
The block library

The Lego pieces of every recipe.

Built-in and custom blocks side by side, each tagged with its category and phase. Fork any built-in to make it yours.

  • 29 built-ins — packages, files, services, users, Docker, AI tools.
  • Inputs reference {{ secrets.NAME }} & variables.
  • Private blocks honour visibility — no forking by guessing an id.
localhost:8080/build/blocks
GoblinDock block library
Goblins guard their hoard

Self-hosted, and hardened end to end.

GoblinDock went through a security & correctness review, independently verified. Your tokens never leave the box.

Encryption at rest

Secrets and Proxmox tokens are Fernet-encrypted (HKDF-derived from your secret key) and masked in logs and previews.

Tenant isolation

/api/state is role-filtered. A non-admin only ever receives their own VMs and a redacted connection view — no host, no token id, no SSH paths.

Guard rails

A hard VMID-window check means GoblinDock can never touch a VM outside its range. Inputs are data, not code — every value is shell- and YAML-quoted.

Jobs fail loudly

A failed Proxmox task fails the job instead of logging success — so the database never advances past a VM that wasn't actually created.

Hardened container

Non-root, digest-pinned base, version-pinned deps and pinned Ansible collections. CSRF tokens, security headers, CSP, self-hosted fonts.

Rate-limited auth

Signed, httpOnly session cookies; password policy enforced; disabled accounts rejected on every path — including the console WebSockets.

Put the goblin to work.

Three commands and a browser tab. The first load asks you to create the admin account — then you're building golden images.

$ docker compose up --build -d