I run a few Docker containers on a small server. Every time something felt off, it was the same routine:
ssh me@server docker ps -a # Restarting (1) 12 seconds ago. Again? docker logs --tail 50 app # scroll, squint nano compose.yml # which port was it? docker compose up -d # did it work? Five commands to answer three questions: is everything up, what broke, and why?
So I built Server Explorer, a calm web UI that sits on top of Docker and Compose. It doesn't replace them: everything it shows comes from Docker's API, deploys run the real docker compose up, and the stacks it creates are plain compose.yml files.
Small on purpose
Whoever controls Docker controls the whole server, so I kept the attack surface tiny. It only listens on 127.0.0.1 and is reached through an SSH tunnel, never from the network. One admin, an audit log of every change, and stacks built in the app can't use privileged mode, host networking or bind mounts.
Less convenient than a URL on your phone? Yes. That's the trade-off.
What it does
- A status board: one sentence, one square per container, and a Needs you list with fix buttons
- Live logs and CPU/RAM per container
- Stacks from a form: image, ports, storage, env, command, run-as user, then Save & deploy
- Docker Hub search and pulls with live progress
What building it taught me
- New volumes belong to root. An image that runs as another user can't write to them, so stacks now have a Run as field.
- The container port has to match the app. A wrong number fails silently, so reading it from the image is next on the list.
- Polling can make a page blink. Docker's status text counts seconds, so every refresh looked like new data. Rendering from memos, and rounding the seconds, fixed it.
- Leptos
view!and>:disabled=move || n > 0closes the tag early. Use braces. -
()in a reactive block can break hydration. An empty<span hidden>renders the same on server and client.
Built with
Leptos 0.8 (SSR + hydration), Axum, bollard and embedded SurrealDB 3.
What's next
Smarter port checks, Cloudflare Tunnel as a built-in wrapper (the explorer itself stays SSH-only), deleting stacks, and a storage browser.
Try it
Open source (MIT): https://github.com/AeonLogics/aeon-server-explorer
If you self-host: would an SSH-tunnel-only dashboard put you off, or is that exactly why you'd trust it?




