
For system administrators, DevOps engineers, and self-hosting practitioners, Docker Compose represents the undisputed standard for declarative container definitions. Storing service topologies in plain text compose.yaml files enables version control, predictable deployments, and painless migrations. However, managing dozens of standalone Compose stacks across one or more production servers or homelab nodes purely via SSH commands quickly becomes tedious. Checking container statuses, tailing log streams, updating image tags, and editing environment variables requires constant terminal context-switching.
To solve this operational friction, many administrators turn to web management suites like Portainer. Yet Portainer fundamentally abstracts Docker away behind proprietary databases, complex internal state layers, and heavy permission graphs. If Portainer crashes or corrupts its internal database, recovering or modifying your running stacks outside its UI can be challenging. Furthermore, Portainer often stores Compose definitions in opaque database blobs rather than keeping standard directory-based YAML files directly on the host filesystem.
Enter Dockge, created by Louis Lam (the mastermind behind the widely acclaimed Uptime Kuma). Dockge is a lightweight, blazing-fast, responsive web interface built exclusively around native Docker Compose. Unlike traditional container managers, Dockge treats your host filesystem as the single source of truth. Each stack in Dockge is simply a standard folder containing a compose.yaml file and an optional .env file. You can edit configurations in Dockge’s browser UI, switch to an SSH terminal and run docker compose up -d, or push changes via Git—Dockge reflects the state in real time without synchronization lag.
In this comprehensive guide, you will learn how to deploy Dockge in Docker Compose, configure a clean stacks directory structure, integrate multi-host agent instances, enforce security isolation with a Docker socket proxy, and implement automated Git backups for disaster recovery.
Architecture and How Dockge Works
Dockge’s design philosophy hinges on minimalism and non-intrusive operations. It does not replace the Docker CLI; instead, it executes standard docker compose subcommands under the hood and streams stdout/stderr directly to the web client via WebSockets. It also provides an interactive, full-featured web terminal powered by xterm.js, allowing you to run interactive shells inside any service container or execute host-level Docker maintenance.
The following diagram illustrates how Dockge orchestrates local stacks and communicates with remote Dockge agents across an isolated network:
+-----------------------------------------------------------------------+
| Admin Workstation |
| (Web Browser: Port 5001) |
+-----------------------------------+-----------------------------------+
|
| HTTPS / WSS (WebSocket)
v
+-----------------------------------------------------------------------+
| Primary Server Node (Host A) |
| |
| +-----------------------------------------------------------------+ |
| | Dockge Primary Instance (Container) | |
| | - Web UI & Real-Time Reactive Terminal Engine | |
| | - Multi-Host Central Dashboard Controller | |
| +----------------+-------------------------------+----------------+ |
| | | |
| v (Direct or Proxy) v (Volume Mount) |
| /var/run/docker.sock /opt/stacks/ |
| | | |
| | +-- /nextcloud/ |
| | | +-- compose.yaml|
| | | +-- .env |
| | +-- /monitoring/ |
| | | +-- compose.yaml|
| | +-- /vaultwarden/ |
| | +-- compose.yaml|
| v |
| [Docker Engine (Host A)] <=== Managed Container Workloads |
+-----------------------------------+-----------------------------------+
|
| Encrypted Agent RPC (Port 5001)
v
+-----------------------------------------------------------------------+
| Secondary Server Node (Host B) |
| |
| +-----------------------------------------------------------------+ |
| | Dockge Remote Agent (Container) | |
| | - Controlled by Primary Node | |
| | - Local Socket: /var/run/docker.sock | |
| | - Local Stacks: /opt/stacks/ | |
| +-----------------------------------------------------------------+ |
| |
| [Docker Engine (Host B)] <=== Managed Container Workloads |
+-----------------------------------------------------------------------+
Key highlights of this architectural model include:
- Zero Vendor Lock-in: If you stop or delete the Dockge container, all your applications continue running uninterrupted. Every stack remains a clean, human-readable directory on disk.
- Interactive Reactive Editing: When you modify environment variables or port allocations in the web editor, Dockge automatically parses the YAML structure, validates syntax errors, and updates container status indicators instantly.
- Integrated Terminal Emulation: Built-in terminal sessions allow immediate debugging, log inspection, and shell access without opening separate SSH connections.
- Native Multi-Agent Support: Manage multiple physical or virtual Docker hosts from a single unified web dashboard without running complex Kubernetes or Swarm overlays.
Prerequisites and Storage Preparation
Before launching Dockge, ensure your host environment meets the following baseline requirements:
- A modern Linux server (Ubuntu 24.04/22.04 LTS, Debian 12, or AlmaLinux 9 recommended).
- Docker Engine v24.0+ and Docker Compose v2.20+ installed.
- A dedicated directory designated as the root parent folder for all your application stacks (e.g.,
/opt/stacks). - Basic knowledge of network routing and reverse proxy mechanics.
To ensure robust file permissions and structured directory separation, initialize the root directories on your Linux server:
# Create primary directories for Dockge internal data and user stacks
sudo mkdir -p /opt/dockge/data
sudo mkdir -p /opt/stacks
# Ensure appropriate ownership and permissions
sudo chown -R $USER:$USER /opt/dockge
sudo chown -R $USER:$USER /opt/stacks
chmod -R 750 /opt/dockge
chmod -R 750 /opt/stacks
In this architecture, /opt/dockge/data stores Dockge’s configuration files, session tokens, and local database cache, while /opt/stacks serves as the parent directory where all individual Compose applications reside.
Deploying Dockge with Docker Compose
Navigate to your Dockge installation directory and create the initial deployment specification:
cd /opt/dockge
nano compose.yaml
Paste the following complete production configuration:
services:
dockge:
image: louislam/dockge:1
container_name: dockge
restart: unless-stopped
ports:
# Expose on localhost or specify server IP; port 5001 is default
- "5001:5001"
volumes:
# Docker daemon socket for executing docker compose commands
- /var/run/docker.sock:/var/run/docker.sock
# Dockge persistent application data
- /opt/dockge/data:/app/data
# Primary directory where all managed compose stacks reside
- /opt/stacks:/opt/stacks
environment:
# Tell Dockge where the stacks directory is mounted inside the container
- DOCKGE_STACKS_DIR=/opt/stacks
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5001/api/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
Start the Dockge container using the native Compose plugin:
docker compose up -d
Verify that the container is healthy and actively listening on port 5001:
docker compose ps
docker compose logs -f
Open your browser and navigate to http://<your-server-ip>:5001. On your first visit, Dockge prompts you to create an administrator account. Enter a strong username and password, then proceed to the main dashboard.
Managing Stacks: Hands-On Walkthrough
Once authenticated, the dashboard presents a clean split-view interface. On the left sidebar, all discovered stacks appear grouped by status: Active, Inactive, or Updating. The central pane features an interactive Monaco code editor alongside a visual service graph.
Creating a New Stack
To create a new service stack, click the + Compose button in the top navigation bar. Enter a stack name, such as uptime-monitoring. Dockge immediately initializes the directory /opt/stacks/uptime-monitoring on your host filesystem.
In the editor, paste the following sample deployment for Uptime Kuma:
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: always
ports:
- "3001:3001"
volumes:
- uptime-kuma-data:/app/data
security_opt:
- no-new-privileges:true
volumes:
uptime-kuma-data:
driver: local
Click Deploy. Dockge triggers docker compose up -d in real time. The bottom terminal drawer automatically slides up, streaming the live image pull progress and container initialization logs. Within seconds, the stack badge changes to a vibrant green dot indicating healthy execution.
Live Environment Variable (.env) Management
Dockge includes dedicated support for .env key-value pairs directly adjacent to your compose.yaml. When you define parameters like POSTGRES_PASSWORD=${DB_PASS}, Dockge creates an interactive UI table where you can view, edit, and safely store variables without hardcoding secrets directly inside the YAML file.
Interactive Container Terminal Execution
Need to run a database migration or inspect filesystem contents inside an active container? You no longer need to look up container IDs via docker ps. In the Dockge stack overview, click on any running container name and select Terminal. An interactive bash or sh session immediately opens within your web browser, complete with full ANSI color support, tab auto-completion, and copy-paste shortcuts.
Multi-Host Management: Adding Remote Agents
One of Dockge’s most powerful capabilities is seamless multi-host management. If you manage an edge server, a secondary VPS, or an offsite backup machine, you do not need to install separate dashboards or maintain multiple browser bookmarks.
To connect a remote host to your primary Dockge instance:
- Deploy Dockge on the Remote Host: On your secondary server (Host B), create
/opt/dockge/compose.yamland rundocker compose up -dexactly as shown in the primary setup. - Access the Primary Controller: Open your primary Dockge dashboard (Host A), click your username in the top right corner, and select Settings > Agents.
- Add New Agent: Click Add New Agent. Enter an identifiable name (e.g.,
Edge-VPS-Frankfurt) and the remote endpoint address:https://agent.yourdomain.comorhttp://10.0.0.15:5001(if connecting over an encrypted Tailscale/WireGuard mesh). - Authorize Token: Copy the generated agent pairing token and enter it into the remote Dockge instance settings.
Once paired, the left sidebar displays a dropdown switcher allowing you to switch between localhost and your remote agents seamlessly. You can deploy, update, restart, and inspect stacks across your entire fleet from one pane of glass.
Automating Git Backup & Disaster Recovery
Because Dockge stores all stacks as standard files inside /opt/stacks, implementing automated version control and offsite backup is straightforward. By initializing a Git repository inside /opt/stacks, you can automatically track every change made via the Dockge UI or external scripts.
Initialize a private Git repository inside your stacks root:
cd /opt/stacks
git init
git config user.name "Dockge Automation"
git config user.email "dockge@yourdomain.com"
# Create a .gitignore to exclude sensitive .env secret files from public tracking
echo "*.env" >> .gitignore
echo "*.env.*" >> .gitignore
echo "*.secret" >> .gitignore
echo "secrets/" >> .gitignore
echo "data/" >> .gitignore
echo "*.log" >> .gitignore
git add .
git commit -m "chore: initial commit of dockge stacks"
To automate commits whenever changes occur, deploy a lightweight cron script or systemd timer that commits and pushes to your private Gitea or GitHub repository:
cat << 'EOF' > /opt/dockge/git-sync.sh
#!/usr/bin/env bash
set -e
cd /opt/stacks
if [[ -n $(git status --porcelain) ]]; then
git add -A
git commit -m "chore: automated stack backup $(date +'%Y-%m-%d %H:%M:%S')"
# git push origin main
fi
EOF
chmod +x /opt/dockge/git-sync.sh
Schedule this script to run hourly via crontab -e (e.g., 0 * * * * /opt/dockge/git-sync.sh >/dev/null 2>&1). If a hardware failure ever destroys your host server, rebuilding your entire container infrastructure on a fresh machine requires merely cloning your Git repo back to /opt/stacks and launching Dockge.
Security Hardening and Reverse Proxy Setup
Exposing a Docker management dashboard directly to the public internet carries severe operational risks. Anyone gaining unauthorized access to Dockge effectively gains root-level code execution on the underlying host. Follow these mission-critical hardening measures:
1. Terminate TLS with a Reverse Proxy (Caddy or Traefik)
Never expose port 5001 directly on a public IP address. Instead, bind Dockge to 127.0.0.1:5001 and route external traffic through a reverse proxy with automated SSL. Here is a production-ready Caddy block configured with WebSocket support:
dockge.yourdomain.com {
# Forward traffic to local Dockge instance
reverse_proxy 127.0.0.1:5001 {
# WebSocket streaming configuration
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
# Security headers
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
}
2. Implement Zero-Trust Network Boundaries
For optimal security, keep Dockge accessible exclusively through an overlay VPN mesh like Tailscale or NetBird, or gate access behind Cloudflare Access / Authentik SSO with multi-factor authentication (MFA). This ensures your management interface remains invisible to automated vulnerability scanners.
Troubleshooting Common Dockge Issues
Even with straightforward deployments, configuration discrepancies can arise. Here are three common issues and their tested solutions:
1. Permission Denied on /var/run/docker.sock
Symptom: Dockge starts up, but the web UI displays an error banner: connect EACCES /var/run/docker.sock, and no stacks can be managed.
Root Cause: The Docker daemon socket on the Linux host is restricted to the docker group, and the user namespace executing inside the container lacks permissions.
Fix: Ensure your host user belongs to the docker group and verify permissions on the socket:
# Verify socket permissions on host
ls -la /var/run/docker.sock
# Expected output: srw-rw---- 1 root docker ...
# Add current user to docker group if missing
sudo usermod -aG docker $USER
# If running rootless or custom GID, pass group ID to Dockge container
DOCKER_GID=$(getent group docker | cut -d: -f3)
echo "DOCKER_GID=$DOCKER_GID"
2. Missing Stacks or Inconsistent State After Manual CLI Edits
Symptom: You created a new folder and compose.yaml manually inside /opt/stacks via SSH, but it does not appear in the Dockge sidebar.
Root Cause: Dockge scans the filesystem on startup and listens for file events, but deep subdirectories or non-standard file naming (e.g., docker-compose.yml instead of compose.yaml) can occasionally delay detection.
Fix: In the Dockge UI, click the Scan Stacks button in the left sidebar menu to force an immediate directory re-index. Furthermore, ensure each stack directory contains exactly one valid Compose file named compose.yaml or docker-compose.yml directly at its root level (nested directories are ignored by design).
3. Container Name Collision Across Different Stacks
Symptom: Deploying a new stack fails with an error: The container name "/database" is already in use by container "...". You have to remove that container to be able to reuse that name.
Root Cause: Multiple Compose stacks utilize identical hardcoded container_name values (such as redis or db) across separate compose.yaml files.
Fix: Avoid generic hardcoded container names. Either remove the container_name attribute entirely (allowing Docker Compose to automatically prefix containers with the stack folder name, e.g., monitoring-db-1), or prefix container names explicitly with the stack identifier (e.g., container_name: uptime_postgres).
Conclusion and Next Steps
Dockge delivers the ideal middle ground between raw command-line scripting and bloated container orchestration platforms. By honoring your filesystem as the single source of truth, Dockge provides modern web conveniences—reactive YAML editing, real-time log streaming, and multi-agent visibility—without introducing vendor lock-in or proprietary abstraction layers.
To take your container infrastructure to the next level, consider combining Dockge with:
- Uptime Kuma: Automatically monitor the health endpoints of your newly created Dockge stacks with instant push alerts to Telegram, Discord, or Slack.
- BorgBackup or Restic: Schedule automated snapshot backups of your
/opt/stacksconfigurations and persistent container volumes to offsite S3 object storage. - CrowdSec & Caddy: Protect your management endpoints with automated IP ban lists and behavioral intrusion prevention.
Hi, I’m Mark, the author of Clever IT Solutions: Mastering Technology for Success. I am passionate about empowering individuals to navigate the ever-changing world of information technology. With years of experience in the industry, I have honed my skills and knowledge to share with you. At Clever IT Solutions, we are dedicated to teaching you how to tackle any IT challenge, helping you stay ahead in today’s digital world. From troubleshooting common issues to mastering complex technologies, I am here to guide you every step of the way. Join me on this journey as we unlock the secrets to IT success.


