Skip to content
  • MangoFly

    A self-hosted WireGuard mesh. Devices connect straight to each other; the coordination server is one binary and a SQLite file, and never sees their traffic.

    encrypted WireGuard · peer to peerLaptopbehind home NATServerin a datacentrePhoneon mobile datacoordination serverone binary · one SQLite filecontrol plane only (TLS)keys · tunnel addresses · peer lists · sealed ICE candidatesholds no private keys · carries no traffic · cannot decryptdatacontrol
  • MangoDock

    Docker management with nothing on the hosts. Reaches each daemon over an ordinary SSH session — no agent to install, no port to open.

    The MangoDock dashboard showing three host cards with container state counts, CPU and memory gauges, a usage history and recent events
  • MangoWiFi

    A Wi-Fi 6/7/8 test bench. One binary runs as Console or Agent either side of the access point under test, measuring latency under real load.

    AP under testWi-Fi 6 / 6E / 7Agentstation side · real radioLAN receiveriperf3 -sConsoleUI · orchestrates · probes
  • Blog
  • Nothing phones home

    No telemetry, no analytics, no crash reporter, no account login. Check it with a packet capture on your own network.

    Download MangoSSH
  • Project
  • Download
  • Running it

    Backing up MangoDock

    Backing up the tool itself — as distinct from the Backups feature inside it, which protects what you run.

    Everything — the database, every stored credential, and the encryption key that protects them — lives in the mangodock_data volume. Back up the volume itself, not just the container. Losing it without a backup means losing every stored credential, not just the running containers.

    Taking a backup

    bash
    docker run --rm -v mangodock_data:/data -v "$PWD":/backup alpine \
      tar czf /backup/mangodock-backup.tar.gz -C /data .

    This works while MangoDock is running: the project's backup test takes twenty copies this way under constant writes and every one restores cleanly, including those taken mid-write. Copying a database file in use is never guaranteed consistent, though — stop the container for the few seconds the copy takes if you need certainty.

    Restoring

    bash
    docker stop mangodock && docker rm mangodock
    docker volume create mangodock_restored
    docker run --rm -v mangodock_restored:/data -v "$PWD":/backup alpine \
      tar xzf /backup/mangodock-backup.tar.gz -C /data
    docker run -d --name mangodock -p 3100:3100 \
      -v mangodock_restored:/app/data \
      -v /var/run/docker.sock:/var/run/docker.sock \
      ghcr.io/mangossh/mangodock:latest

    Restore into a new, empty volume rather than over the old one, so the old one is still there if anything goes wrong. With compose, point the service's volume at mangodock_restored and declare it under volumes: with external: true.

    What comes back

    • Users and their passwords, two-factor sign-in, and every host with its stored credentials and pinned identity.
    • Stacks and their secrets, schedules, and Git, notification and registry settings.
    • The dial-in listener's identity, so dial-in agents pinned to it reconnect with no changes.
    • Sign-in sessions that had not expired — anyone signed in when the backup was taken is signed in again after a restore. Treat backups like the credentials they contain.

    The key and the database travel together

    secret.key decrypts every stored credential. Restore a mangodock.db without it and MangoDock refuses to start, naming the file it needs — it will not start with a new key that cannot read anything, which would otherwise surface later as a decryption error on every host. The same applies if MANGODOCK_SECRET_KEY changes between starts; if you supply the key that way, back that value up alongside the volume.

    On Postgres the database is not in the volume. Back it up with Postgres's own tools, and keep backing up the volume too — the key and the dial-in listener's identity still live there.

    Air-gapped

    • Both commands are local Docker operations against a local volume. Neither needs a network.