-
Notifications
You must be signed in to change notification settings - Fork 76
Stacks
DockMon's stack management system uses Docker Compose to create, manage, and deploy container stacks with real-time progress tracking, security validation, and rollback support.
- Overview
- Key Concepts
- The Stacks Page
- Creating Stacks
- Importing Stacks
- Deploying Stacks
- Deployment Lifecycle
- Security Validation
- Progress Tracking
- Managing Stacks
- Best Practices
- Troubleshooting
DockMon v2.2.7+ uses a stack-based deployment model. All deployments are Docker Compose stacks - there is no separate "single container" deployment type.
- Stacks are compose configurations stored on the DockMon filesystem
- Deployments reference a stack and target a specific host
- The same stack can be deployed to multiple hosts
- Stacks are managed separately from deployments
- Docker Compose-based deployments with full compose.yaml support
- Import existing stacks from running containers
- Import stacks by browsing host filesystems (with batch import)
- Real-time progress tracking with layer-by-layer download status
- Security validation before deployment
- Automatic rollback on failure (before commitment point)
- Redeploy with image pull to update running stacks
| Concept | Description | Location |
|---|---|---|
| Stack | A compose.yaml configuration (and optional .env) | Stored in DockMon filesystem |
| Deployment | An instance of a stack running on a host | References a stack by name |
Example:
- Stack
nextcloudcontains compose.yaml for Nextcloud + MariaDB + Redis - Deployment
nextcloud on server1runs that stack on server1 - Deployment
nextcloud on server2runs the same stack on server2
Stacks are stored in persistent directories that support relative bind mounts.
Default: /app/data/stacks/{name}/
/app/data/stacks/
├── nextcloud/
│ ├── compose.yaml
│ ├── .env (optional)
│ └── data/ # Created by relative bind mount ./data
├── monitoring/
│ ├── compose.yaml
│ └── .env
└── homelab/
└── compose.yaml
Override with STACKS_DIR environment variable.
Default: $DATA_PATH/stacks/ (e.g., /data/stacks/ for Docker agents, /var/lib/dockmon-agent/stacks/ for systemd agents)
Override with AGENT_STACKS_DIR environment variable.
Stacks support relative bind mounts like ./data:/app/data. These resolve to the stack's directory, allowing data to persist across redeployments.
services:
app:
image: myapp
volumes:
- ./data:/app/data # Resolves to /app/data/stacks/mystack/data
- ./config:/config # Resolves to /app/data/stacks/mystack/configStack names must be:
- Lowercase alphanumeric characters
- Can contain hyphens (
-) and underscores (_) - Must start with a letter or number
- Maximum 100 characters
Valid: nextcloud, home-assistant, my_stack_v2
Invalid: My Stack, NEXTCLOUD, -invalid
Access the Stacks page from the sidebar navigation. The page uses a two-column master-detail layout:
- New button - Create a new stack from scratch
- Import button - Import existing stacks (opens modal with multiple import methods)
- Search - Filter stacks by name
- Stack list - Shows all stacks with a badge indicating how many hosts each is deployed to
Click a stack to select it and view/edit in the right panel.
When a stack is selected:
- Stack name (editable for new stacks, rename available for existing)
- compose.yaml editor with syntax highlighting
- .env editor (expandable section)
- Host selector - Choose which host to deploy to
- Deploy/Redeploy button - Deploy to selected host
- Actions: Rename, Clone, Delete
The button shows "Deploy" for new deployments or "Redeploy" if the stack is already deployed to the selected host.
- Navigate to Stacks from the sidebar
- Click New in the left panel
- Enter stack name (e.g.,
nextcloud) - Paste your Docker Compose YAML
- Optionally expand the .env section to add environment variables
- Select a host and click Deploy, or save as draft
name: nextcloud
services:
app:
image: nextcloud:latest
ports:
- "8080:80"
volumes:
- nextcloud_data:/var/www/html
environment:
- MYSQL_HOST=db
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=${DB_PASSWORD}
depends_on:
- db
restart: unless-stopped
db:
image: mariadb:10
volumes:
- db_data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=${DB_PASSWORD}
restart: unless-stopped
volumes:
nextcloud_data:
db_data:With .env:
DB_PASSWORD=secure_password_here
DB_ROOT_PASSWORD=root_password_here
DockMon can import stacks that are already running or from compose files on disk.
Click the Import button in the left panel of the Stacks page to open the import modal.
The import modal has three tabs:
Paste compose.yaml content directly or upload a file:
- Select the Paste / Upload tab
- Paste your compose.yaml or click Upload File
- Optionally click + Add .env content to include environment variables
- Click Import Stack
Scan a host's filesystem for compose files. Supports batch import of multiple stacks:
- Select the Browse Host tab
- Choose a host from the dropdown (local or agent-based hosts only)
- Optionally add custom paths to scan (comma-separated)
- Click Scan for Compose Files
- Use checkboxes to select one or more discovered compose files
- Click Import Selected (N) for batch import
Default scan paths: /opt, /srv, /home, ~/docker
Note: For containerized DockMon or agents, mount the directories you want to scan into the container.
Adopt existing Docker Compose projects into DockMon management:
- Select the From Running tab
- DockMon displays running projects (detected via
com.docker.compose.projectlabel) - Click a project to preview the generated compose.yaml
- Review and edit the generated configuration if needed
- Click Import Stack
How it works:
- DockMon inspects running containers with compose labels
- Generates a compose.yaml from the container configuration
- Extracts: image, environment, ports, volumes, networks, restart policy, healthcheck
- Filters out internal Docker/DockMon labels
Limitations:
-
build:context cannot be recovered (only the built image is available) -
depends_on:relationships are not preserved - Some complex configurations may need manual adjustment
If a stack with the same name already exists:
- Use existing stack content: Create deployment using the compose.yaml already on disk
- Overwrite with new content: Replace existing stack files with imported content
- Navigate to Stacks from the sidebar
- Select a stack from the list (or create a new one)
- In the right panel, select a Host from the dropdown
- Click Deploy (or Redeploy if already deployed to that host)
To update a running stack with the latest images:
- Select the stack from the list
- Select the host where it's deployed
- Click Redeploy
- DockMon will:
- Pull latest images
- Recreate containers with new images
- Preserve volumes and data
To change the compose.yaml:
- Select the stack from the list
- Edit the compose.yaml in the right panel
- Save changes
- Select a host and click Redeploy
planning → validating → pulling_image → creating → starting → running
↓ ↓ ↓ ↓
+--------------+------------+-----------+
↓
failed
↓
rolled_back (optional)
| State | Description | Progress |
|---|---|---|
| planning | Deployment created, not started | 0% |
| validating | Security validation in progress | 0-10% |
| pulling_image | Downloading container images | 10-50% |
| creating | Creating containers | 50-70% |
| starting | Starting containers | 70-90% |
| running | All containers healthy | 100% |
| partial | Some services running, others failed | 100% |
| failed | Deployment failed | 100% |
| rolled_back | Failed and cleaned up | 100% |
| stopped | Imported stack with no running containers | - |
Once containers are successfully created, the deployment is "committed". After this point:
- Rollback will NOT destroy created containers
- This prevents data loss from removing working containers
- Manual intervention may be needed for partial failures
All deployments undergo security checks before execution.
| Level | Behavior | Examples |
|---|---|---|
| CRITICAL | Blocks deployment | Privileged mode, Docker socket mount |
| HIGH | Strong warning | Host network, dangerous capabilities |
| MEDIUM | Warning | Plaintext secrets, excessive resources |
| LOW | Informational | Missing resource limits, :latest tag |
CRITICAL (Blocked):
# Privileged mode - full host access
privileged: true
# Docker socket mount - container escape risk
volumes:
- /var/run/docker.sock:/var/run/docker.sockHIGH (Warning):
# Host network - bypasses isolation
network_mode: host
# Dangerous capabilities
cap_add:
- SYS_ADMINRecommendations:
- Use specific capabilities instead of privileged mode
- Avoid mounting sensitive host paths
- Use Docker networks instead of host networking
- Set resource limits on all containers
The Stacks page shows live deployment progress:
- Progress bar with percentage
- Current stage (pulling, creating, starting)
- Layer-by-layer download progress for images
- Speed indicator for downloads
Pulling nginx:alpine
├─ Layer 1/5: 100% [====================] 2.8 MB
├─ Layer 2/5: 100% [====================] 1.2 MB
├─ Layer 3/5: 45% [==========>---------] 5.1 MB
├─ Layer 4/5: 0% [--------------------] 12.3 MB
└─ Layer 5/5: waiting
Overall: 35% @ 12.5 MB/s
| Action | Description |
|---|---|
| New | Create a new stack from scratch |
| Import | Import existing stacks via multiple methods |
| Edit | Modify compose.yaml and .env in the editor |
| Rename | Change the stack name |
| Clone | Duplicate a stack with a new name |
| Delete | Remove stack (only if no deployments reference it) |
You cannot delete a stack that has active deployments. First delete the deployment(s), then delete the stack.
Why? This prevents orphaned deployments that reference non-existent stacks.
If a stack is deleted outside of DockMon (e.g., manually removing files), deployments become "orphaned". DockMon will show a warning banner with repair options:
- Reassign: Point the deployment to a different stack
- Delete: Remove the deployment record
- Recreate: Generate a new stack from running containers
-
Always set the
name:field:name: my-stack services: ...
-
Use specific image tags:
image: nginx:1.25-alpine # Good image: nginx:latest # Avoid
-
Set resource limits:
services: app: deploy: resources: limits: memory: 512M cpus: '0.5'
-
Use restart policies:
services: app: restart: unless-stopped
-
Use environment files for secrets:
services: db: environment: - MYSQL_PASSWORD=${DB_PASSWORD}
With
.env:DB_PASSWORD=secure_password
To deploy the same stack to multiple hosts:
- Create the stack once
- Select different hosts from the dropdown and deploy
- Each deployment references the same stack
- Updates to the stack affect all deployments on next redeploy
Docker Compose names containers as {project}-{service}-{replica}.
For simple stacks, you can set explicit names:
services:
app:
container_name: myapp # Will be named "myapp" not "mystack-app-1"Note: Explicit container names prevent scaling (--scale) and replicas.
Cause: Large image or slow network
Solution:
- Wait for download to complete
- Check network connectivity
- Pre-pull images:
docker pull <image>
Cause: Another container using the same port
Solution:
- Check running containers:
docker ps - Change port mapping in compose.yaml
- Stop conflicting container
Cause: Stack files not saved properly
Solution:
- Check
/app/data/stacks/directory - Verify compose.yaml exists
- Check DockMon logs for errors
Cause: Some services started, others failed
Solution:
- Check container logs for failed services
- Verify all images exist and are pullable
- Check resource availability (memory, disk)
Cause: Deployment(s) still reference this stack
Solution:
- Remove deployments using this stack first
- Return to the stack and delete it
Cause: Containers don't have compose labels
Explanation: Only containers created by docker-compose or docker compose have the required com.docker.compose.project label.
Solution:
- Use "Paste / Upload" to manually create the stack
- Or recreate containers using docker-compose
Cause: Some settings can't be recovered from running containers
Known limitations:
-
build:context (only final image available) -
depends_on:relationships - Original variable substitutions
Solution:
- Review and edit the generated compose.yaml before importing
- Add missing configuration manually
Cause: Directory scanning only works with local or agent-based hosts
Explanation: Remote mTLS hosts don't have filesystem access for scanning.
Solution:
- Use an agent-based host for scanning
- Or use "Paste / Upload" to import manually
Related Pages:
Getting Started
User Guide
- Dashboard
- Managing Hosts
- Container Operations
- Container Tagging
- Bulk Operations
- Stacks
- Auto-Restart
- Event Viewer
- Container Logs
Configuration
- Alert Rules
- Notifications
- Blackout Windows
- Automatic Updates
- Private Registry Credentials
- Health Checks
- Settings
Remote Monitoring
Access Control
Advanced
Development
Help