Skip to content
DockMon Bot edited this page Jan 22, 2026 · 2 revisions

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.

Table of Contents

  1. Overview
  2. Key Concepts
  3. The Stacks Page
  4. Creating Stacks
  5. Importing Stacks
  6. Deploying Stacks
  7. Deployment Lifecycle
  8. Security Validation
  9. Progress Tracking
  10. Managing Stacks
  11. Best Practices
  12. Troubleshooting

Overview

DockMon v2.2.7+ uses a stack-based deployment model. All deployments are Docker Compose stacks - there is no separate "single container" deployment type.

How It Works

  1. Stacks are compose configurations stored on the DockMon filesystem
  2. Deployments reference a stack and target a specific host
  3. The same stack can be deployed to multiple hosts
  4. Stacks are managed separately from deployments

Key Features

  • 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

Key Concepts

Stacks vs Deployments

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 nextcloud contains compose.yaml for Nextcloud + MariaDB + Redis
  • Deployment nextcloud on server1 runs that stack on server1
  • Deployment nextcloud on server2 runs the same stack on server2

Stack Storage

Stacks are stored in persistent directories that support relative bind mounts.

DockMon Server (Local/mTLS Hosts)

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.

Agent Hosts

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.

Relative Bind Mounts

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/config

Stack Naming

Stack 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

The Stacks Page

Access the Stacks page from the sidebar navigation. The page uses a two-column master-detail layout:

Left Panel - Stack List

  • 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.

Right Panel - Stack Editor

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.

Creating Stacks

Via the Stacks Page

  1. Navigate to Stacks from the sidebar
  2. Click New in the left panel
  3. Enter stack name (e.g., nextcloud)
  4. Paste your Docker Compose YAML
  5. Optionally expand the .env section to add environment variables
  6. Select a host and click Deploy, or save as draft

Example Stack

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

Importing Stacks

DockMon can import stacks that are already running or from compose files on disk.

Accessing Import

Click the Import button in the left panel of the Stacks page to open the import modal.

Import Methods

The import modal has three tabs:

1. Paste / Upload

Paste compose.yaml content directly or upload a file:

  1. Select the Paste / Upload tab
  2. Paste your compose.yaml or click Upload File
  3. Optionally click + Add .env content to include environment variables
  4. Click Import Stack

2. Browse Host

Scan a host's filesystem for compose files. Supports batch import of multiple stacks:

  1. Select the Browse Host tab
  2. Choose a host from the dropdown (local or agent-based hosts only)
  3. Optionally add custom paths to scan (comma-separated)
  4. Click Scan for Compose Files
  5. Use checkboxes to select one or more discovered compose files
  6. 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.

3. From Running

Adopt existing Docker Compose projects into DockMon management:

  1. Select the From Running tab
  2. DockMon displays running projects (detected via com.docker.compose.project label)
  3. Click a project to preview the generated compose.yaml
  4. Review and edit the generated configuration if needed
  5. 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

Import Conflict Handling

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

Deploying Stacks

Creating a Deployment

  1. Navigate to Stacks from the sidebar
  2. Select a stack from the list (or create a new one)
  3. In the right panel, select a Host from the dropdown
  4. Click Deploy (or Redeploy if already deployed to that host)

Redeploying (Updating)

To update a running stack with the latest images:

  1. Select the stack from the list
  2. Select the host where it's deployed
  3. Click Redeploy
  4. DockMon will:
    • Pull latest images
    • Recreate containers with new images
    • Preserve volumes and data

Editing Stack Content

To change the compose.yaml:

  1. Select the stack from the list
  2. Edit the compose.yaml in the right panel
  3. Save changes
  4. Select a host and click Redeploy

Deployment Lifecycle

State Machine

planning → validating → pulling_image → creating → starting → running
              ↓              ↓            ↓           ↓
              +--------------+------------+-----------+
                             ↓
                          failed
                             ↓
                       rolled_back (optional)

States

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 -

Commitment Point

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

Security Validation

All deployments undergo security checks before execution.

Security Levels

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

Common Security Issues

CRITICAL (Blocked):

# Privileged mode - full host access
privileged: true

# Docker socket mount - container escape risk
volumes:
  - /var/run/docker.sock:/var/run/docker.sock

HIGH (Warning):

# Host network - bypasses isolation
network_mode: host

# Dangerous capabilities
cap_add:
  - SYS_ADMIN

Recommendations:

  • 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

Progress Tracking

Real-time Updates

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

Layer Progress Example

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

Managing Stacks

Stack Actions

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)

Deleting Stacks

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.

Orphaned Deployments

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

Best Practices

Compose File Design

  1. Always set the name: field:

    name: my-stack
    services:
      ...
  2. Use specific image tags:

    image: nginx:1.25-alpine  # Good
    image: nginx:latest       # Avoid
  3. Set resource limits:

    services:
      app:
        deploy:
          resources:
            limits:
              memory: 512M
              cpus: '0.5'
  4. Use restart policies:

    services:
      app:
        restart: unless-stopped
  5. Use environment files for secrets:

    services:
      db:
        environment:
          - MYSQL_PASSWORD=${DB_PASSWORD}

    With .env:

    DB_PASSWORD=secure_password
    

Multi-Host Deployments

To deploy the same stack to multiple hosts:

  1. Create the stack once
  2. Select different hosts from the dropdown and deploy
  3. Each deployment references the same stack
  4. Updates to the stack affect all deployments on next redeploy

Container Naming

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.

Troubleshooting

Deployment Stuck on "pulling_image"

Cause: Large image or slow network

Solution:

  • Wait for download to complete
  • Check network connectivity
  • Pre-pull images: docker pull <image>

"Port already in use" Error

Cause: Another container using the same port

Solution:

  • Check running containers: docker ps
  • Change port mapping in compose.yaml
  • Stop conflicting container

"Stack not found" After Import

Cause: Stack files not saved properly

Solution:

  • Check /app/data/stacks/ directory
  • Verify compose.yaml exists
  • Check DockMon logs for errors

Deployment Shows "partial" Status

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)

Cannot Delete Stack (Button Disabled)

Cause: Deployment(s) still reference this stack

Solution:

  1. Remove deployments using this stack first
  2. Return to the stack and delete it

Import From Running Shows "No projects found"

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

Generated Compose Missing Configuration

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

Browse Host Shows "No agent hosts available"

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:

Clone this wiki locally