Compose Manager
    Docker

    Deploy Dockge on a VPS

    Self-host Dockge, a reactive Docker Compose stack manager, on a RamNode VPS — Docker install, localhost-bound UI, and Caddy TLS.

    Dockge is a self hosted, reactive Docker Compose stack manager from the author of Uptime Kuma. It gives you a clean web interface for creating, editing, starting, and monitoring compose.yaml stacks, converts docker run commands into compose files, and streams pull and up and down progress in real time. Crucially it does not hide your files: every stack stays on disk as a normal compose project you can still drive from the CLI.

    This guide installs Docker, deploys Dockge as a container, binds its web UI to localhost, and fronts it with Caddy for automatic TLS. Nothing here needs a mail service, which keeps the deployment inside RamNode's acceptable use policy. The only email address used is the ACME contact Let's Encrypt keeps for expiry notices, which involves no outbound SMTP from your VPS.

    One important caution up front: Dockge talks to the Docker socket and therefore has full control over Docker on the host. Anyone who reaches the Dockge UI effectively has root on the box. That is why this guide keeps the UI off the public internet and behind TLS with a strong password.

    Prerequisites

    • A RamNode VPS running Ubuntu 24.04 LTS (Debian 12 works with minor path differences)
    • Root or a sudo-enabled user
    • A domain or subdomain with an A record (and AAAA for IPv6) pointing at your VPS, if you want TLS access to the UI

    Replace dockge.example.com with your real hostname throughout.

    1. Prepare the system

    shell
    sudo apt update && sudo apt upgrade -y
    sudo apt install -y ca-certificates curl gnupg

    2. Install Docker Engine and the Compose plugin

    Use Docker's official repository rather than the distro package so you get current Engine and Compose V2, which Dockge requires:

    shell
    sudo install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
      | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    sudo chmod a+r /etc/apt/keyrings/docker.gpg
    
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
      https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
      | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
    
    sudo apt update
    sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    sudo systemctl enable --now docker
    docker --version && docker compose version

    On Debian 12, replace ubuntu with debian in both the GPG URL and the repository line.

    3. Create the Dockge directory structure

    Dockge keeps its own state in one directory and manages your stacks in another. The stacks path is deliberately identical inside and outside the container, which the compose file will enforce:

    shell
    sudo mkdir -p /opt/dockge /opt/stacks

    4. Write the Dockge compose file

    Rather than fetch the upstream file blindly, define it explicitly so you control the pinned image tag, the bound interface, and the stacks path. Note the 127.0.0.1: prefix on the port mapping: the UI listens only on localhost and is never published to the public interface.

    shell
    sudo tee /opt/dockge/compose.yaml >/dev/null <<'EOF'
    services:
      dockge:
        image: louislam/dockge:1
        container_name: dockge
        restart: unless-stopped
        ports:
          # Bind to localhost only; Caddy handles public TLS access
          - 127.0.0.1:5001:5001
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - ./data:/app/data
          - /opt/stacks:/opt/stacks
        environment:
          - DOCKGE_STACKS_DIR=/opt/stacks
    EOF

    The louislam/dockge:1 tag tracks the current major version and is the upstream recommended pin. The built in web terminal is disabled by default in recent releases, which is the safer posture. Leave it disabled unless you have a specific need, in which case you would add DOCKGE_ENABLE_CONSOLE=true to the environment.

    Bring Dockge up:

    shell
    cd /opt/dockge
    sudo docker compose up -d
    sudo docker compose ps

    5. Front Dockge with Caddy for TLS

    Caddy gives you automatic Let's Encrypt certificates and correct WebSocket proxying with a two line site block. Dockge relies on WebSockets, and Caddy handles the upgrade transparently.

    Install Caddy from its official repository:

    shell
    sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
      | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
      | sudo tee /etc/apt/sources.list.d/caddy-stable.list >/dev/null
    sudo apt update
    sudo apt install -y caddy

    Configure the reverse proxy in /etc/caddy/Caddyfile:

    shell
    sudo tee /etc/caddy/Caddyfile >/dev/null <<'EOF'
    dockge.example.com {
        reverse_proxy 127.0.0.1:5001
    }
    EOF
    
    sudo systemctl reload caddy

    Caddy obtains and renews the certificate automatically on first request. If you would rather ask for the cert email explicitly, add a global email you@example.com block at the top of the Caddyfile. That address is only a Let's Encrypt notification contact and does not start any mail service.

    If you already run Zoraxy or standalone Envoy on this VPS from the companion guides, point that proxy at 127.0.0.1:5001 instead of installing Caddy, and skip this section.

    6. Configure the firewall

    Allow SSH and the public web ports for Caddy. Dockge's own port 5001 is bound to localhost and never needs a firewall rule:

    shell
    sudo apt install -y ufw
    sudo ufw default deny incoming
    sudo ufw default allow outgoing
    sudo ufw allow 22/tcp
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw enable
    sudo ufw status verbose

    Port 80 stays open so Caddy can complete HTTP-01 ACME challenges and redirect plain HTTP to HTTPS.

    7. Create the admin account

    Browse to your hostname:

    shell
    https://dockge.example.com

    Dockge prompts you to create the first administrator account on initial launch. Choose a strong unique password. Because this account can control every container on the host through the Docker socket, treat it with the same care as a root login.

    8. Using Dockge

    Your stacks live under /opt/stacks, one subdirectory per stack, each containing a compose.yaml. Dockge reads and writes those files directly, so you can manage a stack from the UI and still run docker compose against it from the shell:

    shell
    /opt/stacks/
    ├── myapp/
    │   └── compose.yaml
    └── another-app/
        └── compose.yaml

    From the interface you can create a new stack, paste or edit compose YAML with live syntax help, convert a docker run command into a compose file, and start, stop, restart, and tail logs for each stack in real time.

    9. Backups

    Two directories hold everything: /opt/dockge/data is Dockge's own state and account, and /opt/stacks holds all your compose projects and their bind mounted data. Back both up:

    shell
    sudo tee /usr/local/bin/backup-dockge.sh >/dev/null <<'EOF'
    #!/bin/bash
    STAMP=$(date +%F)
    DEST=/var/backups/dockge
    mkdir -p "$DEST"
    tar czf "$DEST/dockge-${STAMP}.tar.gz" /opt/dockge/data /opt/stacks
    find "$DEST" -name 'dockge-*.tar.gz' -mtime +14 -delete
    EOF
    sudo chmod +x /usr/local/bin/backup-dockge.sh
    echo "0 3 * * * root /usr/local/bin/backup-dockge.sh" | sudo tee /etc/cron.d/backup-dockge

    If a managed stack stores large volumes of data (a database, for example), consider a stack aware backup for that data separately, since a plain tar of a live database directory can be inconsistent. Push /var/backups/dockge offsite to RamNode S3 storage or another remote target with rclone or restic.

    10. Updating Dockge

    Because the image is pinned to the major tag, updating is a pull and recreate:

    shell
    cd /opt/dockge
    sudo docker compose pull
    sudo docker compose up -d

    Review release notes before jumping across a major version, since the pin at :1 intentionally holds you on the current major line until you decide to move.

    Security checklist

    • Dockge UI bound to 127.0.0.1:5001 and never published to the public interface
    • Public access only through Caddy over TLS on your domain
    • Built in web terminal left disabled
    • Strong unique admin password, treated as root-equivalent because of Docker socket access
    • Image pinned to a major tag and updated deliberately
    • Docker installed from the official repository for current Engine and Compose
    • Both state directories backed up daily
    • No mail services involved, consistent with RamNode's AUP

    Where to go next

    Recent Dockge releases add multiple agent support, so you can manage stacks across several Docker hosts from one interface. If you grow into that, keep the primary instance as the one exposed through Caddy and connect additional hosts as agents rather than exposing each one directly. For heavier needs like GitOps, an API, RBAC, or vulnerability scanning, Dockge stays deliberately minimal and you would reach for a different tool, but for straightforward compose stack management on a RamNode VPS it is hard to beat on simplicity.