Skip to content

Cloud Commander

Web-based dual-pane orthodox file manager (Total/Midnight Commander style) co-located with Filebrowser on LXC 126. Shares the same four storage bind-mounts.

Overview

LXC 126 (apps-pool) — co-located with Filebrowser
IP 192.168.1.126
URL https://cmd.eva-00.network
Image coderaiser/cloudcmd:19.16.0
Port 8000 (host) -> 8000 (container)
Auth oauth2-proxy (LXC 119, port 8597) + PocketID OIDC, via Caddy forward_auth
Vault path secret/external-oauth2-proxies (cloudcmd_* keys)
Playbook ansible/playbooks/filebrowser.yml (shared with Filebrowser)
Workflow .forgejo/workflows/filebrowser.yml

Why Cloud Commander?

Filebrowser Quantum is great for general browsing and sharing, but lacks a dual-pane workflow for moving/copying files between directories. Cloud Commander recreates the Midnight/Total Commander UX in the browser — without needing KasmVNC or a full desktop streaming stack.

Architecture

Browser → Caddy (cmd.eva-00.network)
            ↓ forward_auth
        oauth2-proxy-cloudcmd (192.168.1.119:8597)
            ↓ on success
        Cloud Commander (192.168.1.126:8000)
            ↓ /mnt/fs
        /data/{unohana,urahara,filedump,dlbox} (bind-mounts)

Cloud Commander itself has auth: false — authentication is enforced entirely at the Caddy/oauth2-proxy layer. The container runs as root to match Filebrowser's access pattern across the four bind-mounts.

Disabled features (hardening)

  • Terminal — disabled. Use code-server or SSH for shell.
  • Console — disabled. Server-side command execution is a foot-gun.
  • Config dialog — disabled. Config is managed via IaC, not the UI.

Deployment

Co-located with Filebrowser. Pushing changes to services/cloudcmd/** triggers the filebrowser workflow which re-runs the full playbook (idempotent).

First Deploy

The filebrowser playbook deploys Cloud Commander after Filebrowser is up:

  1. Creates /opt/cloudcmd/
  2. Drops .cloudcmd.json config
  3. Drops docker-compose.yml
  4. docker compose up -d
  5. Health-checks http://localhost:8000

Prerequisites

Before first deploy, the following must exist:

  1. PocketID OIDC client
  2. Name: cloudcmd
  3. Callback URL: https://cmd.eva-00.network/oauth2/callback
  4. Logout URL: https://cmd.eva-00.network

  5. Vault secret at secret/external-oauth2-proxies with keys:

  6. cloudcmd_client_id
  7. cloudcmd_client_secret
  8. cloudcmd_cookie_secret (32 random bytes, base64-encoded — generate with openssl rand -base64 32 | tr -- '+/' '-_')

  9. infra-apps redeploy (LXC 119) — the new oauth2-proxy-cloudcmd container needs to come up before the Caddy block has a working backend.

File Layout on LXC 126

/opt/cloudcmd/
  docker-compose.yml
  .cloudcmd.json      # Mounted into container at /root/.cloudcmd.json
/data/                # Shared with Filebrowser; mounted into Cloud Commander at /mnt/fs
  unohana/
  urahara/
  filedump/
  dlbox/

Usage tips

  • Dual-pane is on by default (oneFilePanel: false).
  • Vim keys are enabled — hjkl to navigate, gg/G to jump.
  • F-keys (classic Norton Commander):
  • F3: view
  • F4: edit
  • F5: copy (between panels)
  • F6: move
  • F7: mkdir
  • F8: delete
  • Start directory is /mnt/fs which contains the four storage roots as folders.

References