Sign inSign up

solivagvs/ghostdeck

By solivagvs

•Updated about 2 months ago

Web-based container manager for disposable browsers, messengers, Kali, and Ubuntu workspaces.

Image
Networking
Security
0

1.0K

solivagvs/ghostdeck repository overview

⁠GhostDeck

GhostDeck launches disposable browser, messenger, Kali and Ubuntu workspaces from a web interface. It manages project containers through the Docker socket and serves the dashboard and every workspace through a managed Caddy container with HTTPS.

Screenshots, Debian packages and full documentation: github.com/solivagvs-dev/ghostdeck⁠

⁠Tags

  • latest, <version> — multi-arch manifests for linux/amd64 and linux/arm64
  • <version>-amd64, <version>-arm64 — single-architecture images

⁠Quick Start

services:
  ghostdeck:
    image: solivagvs/ghostdeck:latest
    container_name: ghostdeck
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      # Must be the same absolute path inside and outside the container.
      # Named volumes will not work here.
      - /var/lib/ghostdeck:/var/lib/ghostdeck
    environment:
      TZ: Europe/Berlin
sudo mkdir -p /var/lib/ghostdeck
docker compose up -d
sudo cat /var/lib/ghostdeck/.initial-admin-password

Then open https://<host>/ and sign in at /admin/. Plain HTTP redirects to HTTPS, and the default certificate is issued by Caddy's internal CA, so browsers warn until you trust it.

No configuration is required to start. On first run the container writes /var/lib/ghostdeck/.env with a generated APP_SECRET, a generated admin password and every default listed below. That file is never rewritten afterwards; variables set on the container override it.

⁠Configuration

VariableDefaultPurpose
APP_SECRETgeneratedHMAC key for session and CSRF cookies. Changing it signs everyone out.
ADMIN_PASSWORDgeneratedAdmin login. Ignored when ADMIN_PASSWORD_HASH is set.
ADMIN_PASSWORD_HASHemptybcrypt hash instead of a plaintext password. Compose expands $, so double it.
REGISTRATION_TOKENemptyInvite code for /register. Empty leaves signup open to anyone who can reach the dashboard.
PROJECT_NETWORK_ISOLATIONtrueOne Docker network per project. false puts every workspace on the shared network.
DOCKER_NETWORKghostdeck-netBase network name. Per-project networks are <name>-p<id>.
PROJECT_UNCONFINEDfalseRuns workspaces with seccomp=unconfined. Only needed if an image will not start otherwise.
CADDY_HTTP_BIND80Host port for HTTP. off disables it. 127.0.0.1:8080 binds one address.
CADDY_HTTPS_BIND443Host port for HTTPS, same syntax.
TRUSTED_PROXIESnoneCIDRs whose X-Forwarded-For is trusted, so login rate limits see the real client address.
PUID / PGID1000uid and gid owning workspace files.
TZEurope/BerlinWorkspace timezone.
IMAGE_<NAME>_ENABLEDtrueCatalog toggles: FIREFOX, BRAVE, CHROME, CHROMIUM, TELEGRAM, SIGNAL, UBUNTU, KALI.

⁠Workspace Isolation

Each project container runs on its own Docker bridge network, <DOCKER_NETWORK>-p<project-id>. Only the managed Caddy container is attached to every project network, so one workspace cannot reach another workspace's container directly; reaching one through Caddy requires a session that owns it.

Isolation applies between workspaces only. Every workspace keeps normal outbound access to the internet, the host's LAN and ports published on the host. Kali workspaces run with NET_ADMIN and NET_RAW, and Ubuntu Webtop runs with apparmor=unconfined.

⁠Notes

  • GhostDeck publishes no ports itself. Its managed Caddy container publishes 80 and 443 on the host daemon.
  • Runtime state — the session database, generated Caddy config and every workspace home directory — lives in /var/lib/ghostdeck, created 0700.
  • Workspaces are served from the dashboard origin, so a compromised workspace image can act as the logged-in user.
  • Security events are in the container log: docker logs ghostdeck 2>&1 | grep 'audit event='.

Tag summary

Content type

Image

Digest

sha256:712007d73…

Size

74.9 MB

Last updated

about 2 months ago

docker pull solivagvs/ghostdeck