-
Notifications
You must be signed in to change notification settings - Fork 76
Deployments
DockMon's deployment system provides a powerful, automated way to deploy single containers or multi-container stacks with real-time progress tracking, security validation, and rollback support.
- Overview
- Deployment Types
- Deployment Lifecycle
- Creating Deployments
- Deployment Templates
- Security Validation
- Progress Tracking
- Rollback and Recovery
- Best Practices
- Troubleshooting
The deployment system automates container lifecycle operations with:
- Automated Deployment: Pull images, create containers, start services
- Real-time Progress: Live updates via WebSocket during deployment
- Security Validation: Pre-deployment security checks with multiple severity levels
- Rollback Support: Automatic cleanup on failure
- Template System: Save and reuse configurations with variable substitution
- Stack Support: Deploy multi-container applications using Docker Compose
- 7-state deployment state machine with granular progress tracking
- Security validation for privileged access, dangerous mounts, and more
- Commitment point tracking for safe rollback operations
- Template variables for parameterized deployments
- Real-time WebSocket updates for progress and errors
- Support for both single containers and Docker Compose stacks
Deploy a single container with specified configuration.
Use Cases:
- Single-service applications (web servers, databases, etc.)
- Simple containerized tools
- Testing and development environments
Example Configuration:
{
"image": "nginx:1.25-alpine",
"name": "my-nginx",
"ports": ["8080:80"],
"environment": {
"NGINX_HOST": "example.com"
},
"volumes": [
"nginx-data:/usr/share/nginx/html:ro"
],
"restart_policy": {"Name": "unless-stopped"},
"mem_limit": "512m",
"cpus": 0.5
}Deploy multi-container applications using Docker Compose syntax.
Use Cases:
- Multi-service applications (web + database + cache)
- Complex microservice architectures
- Applications with service dependencies
Example Docker Compose YAML:
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- '8080:80'
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secretNote: In the deployment form, paste this YAML into the Compose YAML field.
Deployments progress through a well-defined state machine:
planning → validating → pulling_image → creating → starting → running
↓ ↓ ↓ ↓
+--------------+------------+-----------+
↓
failed
↓
rolled_back (optional)
| State | Description | Progress | Duration |
|---|---|---|---|
| planning | Deployment created, not started | 0% | Instant |
| validating | Security validation in progress | 0-10% | <1 second |
| pulling_image | Downloading container image(s) | 10-50% | Varies by image size |
| creating | Creating container in Docker | 50-70% | <5 seconds |
| starting | Starting container | 70-90% | <5 seconds |
| running | Container healthy and running | 100% | Terminal state |
| failed | Error occurred during deployment | 100% | Terminal state |
| rolled_back | Failed deployment cleaned up | 100% | Terminal state |
Once a container is successfully created in Docker, the deployment is marked as "committed". This prevents rollback operations from destroying successfully created containers, even if post-creation steps fail (like health checks).
Why This Matters:
- Prevents data loss from destroying containers that were successfully created
- Allows manual recovery when automated health checks fail
- Maintains consistency between Docker state and DockMon database
- Navigate to Deployments page
- Click New Deployment
- Select host from dropdown
- Choose deployment type: Container or Stack
- Configure deployment:
- Container: Fill in image, ports, environment, volumes, etc.
- Stack: Provide Docker Compose YAML
- Click Create Deployment
- Click Execute to start deployment
The deployment will begin executing and you'll see real-time progress updates in the UI.
| Field | Type | Required | Description |
|---|---|---|---|
image |
string | Yes | Docker image (e.g., nginx:alpine) |
name |
string | No | Container name (auto-generated if not provided) |
ports |
array | No | Port mappings (e.g., ["8080:80"]) |
environment |
object | No | Environment variables (key-value pairs) |
volumes |
array | No | Volume mounts (e.g., ["data:/app/data"]) |
networks |
array | No | Docker networks to connect to |
restart_policy |
object | No | Restart policy (e.g., {"Name": "unless-stopped"}) |
mem_limit |
string | No | Memory limit (e.g., "512m") |
cpus |
number | No | CPU limit (e.g., 0.5 for half CPU) |
privileged |
boolean | No | Run in privileged mode (triggers security warning) |
cap_add |
array | No | Add Linux capabilities |
cap_drop |
array | No | Drop Linux capabilities |
network_mode |
string | No | Network mode (e.g., "host", "bridge") |
hostname |
string | No | Container hostname |
user |
string | No | User to run as (e.g., "1000:1000") |
working_dir |
string | No | Working directory inside container |
command |
string/array | No | Command to run (overrides image CMD) |
entrypoint |
string/array | No | Entrypoint (overrides image ENTRYPOINT) |
labels |
object | No | Container labels (key-value pairs) |
| Field | Type | Required | Description |
|---|---|---|---|
compose_yaml |
string | Yes | Docker Compose YAML definition |
variables |
object | No | Template variable values (if using template) |
Templates allow you to save reusable deployment configurations with variable substitution.
- Reusability: Deploy the same configuration multiple times
- Parameterization: Customize deployments with variables
- Organization: Categorize templates (web-servers, databases, monitoring)
- Consistency: Ensure deployments follow standards
Via UI:
- Go to Templates page (from Deployments page)
- Click New Template
- Fill in template details:
- Name (e.g., "Nginx Web Server")
- Category (e.g., "web-servers")
- Description
- Deployment type (container or stack)
- Define template with variables using
${VARIABLE}syntax - Define variable schemas (default values, types, descriptions)
- Save template
Example Template:
{
"name": "PostgreSQL Database",
"category": "databases",
"deployment_type": "container",
"template_definition": {
"image": "postgres:${VERSION}",
"environment": {
"POSTGRES_PASSWORD": "${DB_PASSWORD}",
"POSTGRES_DB": "${DB_NAME}",
"POSTGRES_USER": "${DB_USER}"
},
"ports": ["${PORT}:5432"],
"volumes": ["${VOLUME_NAME}:/var/lib/postgresql/data"],
"mem_limit": "${MEMORY_LIMIT}",
"restart_policy": {"Name": "unless-stopped"}
},
"variables": {
"VERSION": {
"default": "16-alpine",
"type": "string",
"description": "PostgreSQL version"
},
"DB_PASSWORD": {
"default": "",
"type": "password",
"required": true,
"description": "Database root password"
},
"DB_NAME": {
"default": "mydb",
"type": "string",
"description": "Initial database name"
},
"DB_USER": {
"default": "postgres",
"type": "string",
"description": "Database user"
},
"PORT": {
"default": 5432,
"type": "integer",
"description": "Host port to expose"
},
"VOLUME_NAME": {
"default": "postgres-data",
"type": "string",
"description": "Volume name for data persistence"
},
"MEMORY_LIMIT": {
"default": "2g",
"type": "string",
"description": "Memory limit"
}
}
}- From Deployments page, click New Deployment
- Click From Template button
- Select a template
- Fill in variable values (or use defaults)
- Review generated configuration
- Create and execute deployment
Template variables use ${VARIABLE_NAME} syntax and are replaced at deployment time.
Variable Types:
-
string: Text value -
integer: Numeric value -
boolean: True/false -
password: Sensitive string (hidden in UI)
Variable Rules:
- Variable names must be UPPERCASE with underscores (e.g.,
DB_PASSWORD) - Variables can have default values
- Variables can be marked as
required(must be provided) - Undefined variables in templates will keep the
${VAR}placeholder
After creating a successful deployment, you can save it as a template for reuse:
- From Deployments list, click Save as Template icon
- Enter template name and category
- Optionally mark fields as variables (e.g., replace
8080with${PORT}) - Save template
All deployments undergo security validation before execution. The system checks for common security issues and categorizes them by severity.
| Level | Numeric | Behavior | Description |
|---|---|---|---|
| CRITICAL | 4 | Blocks deployment | Must be explicitly overridden |
| HIGH | 3 | Strong warning | Deployment allowed but discouraged |
| MEDIUM | 2 | Warning | User should review |
| LOW | 1 | Informational | Best practice recommendation |
| INFO | 0 | Note | No action required |
Privileged Containers:
privileged: true
- Risk: Disables all security isolation, grants full host access
-
Recommendation: Use specific capabilities instead (
cap_add)
Dangerous Volume Mounts:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /:/host
- Risk: Container escape, full Docker API access
- Recommendation: Mount only specific directories needed
-
Note: Read-only mounts (
:/path:ro) reduce severity to HIGH
Host Network Mode:
network_mode: "host"
- Risk: Bypasses network isolation, exposes all host ports
- Recommendation: Use port mappings instead
Dangerous Linux Capabilities:
cap_add:
- SYS_ADMIN
- SYS_MODULE
- SYS_RAWIO
- Risk: Container escape, kernel module loading, hardware access
- Recommendation: Use minimal capabilities or none
Dangerous Mount Paths:
volumes:
- /etc:/host-etc
- /proc:/host-proc
- /sys:/host-sys
- /boot:/host-boot
- /dev:/host-dev
- Risk: Access to sensitive host configuration
- Recommendation: Mount only application-specific directories
Plaintext Secrets in Environment:
environment:
DB_PASSWORD: "my-password-123"
API_KEY: "secret-key"
- Risk: Secrets visible in Docker inspect, logs, and process lists
- Recommendation: Use Docker secrets or external secret management
Dangerous Network Capabilities:
cap_add:
- NET_ADMIN
- Risk: Network administration privileges
- Recommendation: Use only if absolutely necessary
Excessive Memory Limits:
mem_limit: "32g"
- Risk: Resource exhaustion
- Recommendation: Set reasonable limits based on application needs
Missing Resource Limits:
# No mem_limit, cpus, or cpu_shares specified
- Risk: Container can consume all available resources
- Recommendation: Set memory and CPU limits
Using :latest Tag:
image: "nginx:latest"
- Risk: Unpredictable updates, lack of reproducibility
-
Recommendation: Use specific version tags (e.g.,
nginx:1.25-alpine)
CRITICAL security issues will block deployment. There is currently no way to override these checks in the UI for safety reasons.
If you encounter a CRITICAL security violation:
- Fix the security issue (strongly recommended) - Remove privileged mode, dangerous mounts, etc.
-
Understand the risk - If you must proceed, manually deploy the container using
docker runcommands outside of DockMon
HIGH, MEDIUM, and LOW warnings will not block deployment but should be reviewed and addressed when possible.
Deployments provide real-time progress updates via WebSocket.
Validation (0-10%):
- Security validation
- Configuration validation
- Pre-flight checks
Image Pull (10-50%):
- Downloading container image layers
- Layer-by-layer progress tracking
- Progress varies by image size and network speed
Container Creation (50-70%):
- Creating container in Docker
- Resource allocation
- Network configuration
- Volume mounting
Container Start (70-90%):
- Starting container process
- Initial startup checks
Health Check (90-100%):
- Waiting for container to be healthy
- Running health check commands
- Verifying container is responsive
The Deployments page automatically receives real-time updates via WebSocket connection:
- Progress bar updates as deployment progresses
- Status badge changes as deployment transitions through states
- Stage description shows current operation (e.g., "Pulling image", "Starting container")
- Error messages appear immediately if deployment fails
You don't need to refresh the page - all updates happen automatically.
During image pull, DockMon tracks individual layer downloads:
Pulling image nginx:1.25-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: 0% [-------------------] 1.5 MB
Overall: 35% complete
When a deployment fails, DockMon automatically attempts to clean up:
Rollback Behavior:
- Removes created containers
- Cleans up resources (networks, volumes if not in use)
- Transitions deployment to
rolled_backstate
Rollback Conditions:
- Deployment has NOT reached commitment point
- Deployment is in a rollback-eligible state (validating, pulling_image, creating, starting, or failed)
The commitment point prevents rollback from destroying successfully created containers.
Example Scenario:
- Container created successfully in Docker ✓
- Deployment marked as "committed" ✓
- Health check fails (timeout) ✗
- Rollback is NOT performed (container preserved)
Why?
- Container was successfully created
- Failure might be temporary (slow startup)
- User can manually investigate and fix
- Prevents data loss from destroying working containers
For failed deployments with committed=true:
-
Check Container Logs:
docker logs <container-id>
-
Inspect Container:
docker inspect <container-id>
-
Restart Container:
docker restart <container-id>
-
Fix and Redeploy:
- Update deployment configuration
- Delete failed deployment
- Create new deployment with fixes
| State | Committed | Rollback Performed | Container Status |
|---|---|---|---|
| failed | No | Yes (automatic) | Removed |
| failed | Yes | No (protected) | Exists, may be running |
| rolled_back | No | Yes | Removed successfully |
-
Use Specific Image Tags:
{"image": "nginx:1.25-alpine"} // Good {"image": "nginx:latest"} // Avoid -
Set Resource Limits:
{ "mem_limit": "512m", "cpus": 0.5 } -
Use Restart Policies:
{"restart_policy": {"Name": "unless-stopped"}} -
Avoid Privileged Mode:
{"privileged": false} // Default, secure {"cap_add": ["NET_BIND_SERVICE"]} // Use capabilities instead -
Mount Volumes with Minimal Permissions:
{"volumes": [ "app-data:/app/data", // Read-write for data "/path/to/config:/config:ro" // Read-only for config ]}
-
Parameterize Configuration:
- Use variables for ports, versions, credentials
- Provide sensible defaults
- Mark sensitive variables as
passwordtype
-
Document Variables:
{ "VERSION": { "default": "1.25", "type": "string", "description": "Application version to deploy" } } -
Organize with Categories:
- Use categories like
web-servers,databases,monitoring - Makes templates easier to find
- Use categories like
-
Test Templates:
- Deploy from template before sharing
- Verify all variables work correctly
- Test with default values
-
Review Security Warnings:
- Always review HIGH and MEDIUM warnings
- Fix CRITICAL issues before deployment
- Understand the risks before proceeding
-
Use Docker Secrets:
environment: DB_PASSWORD_FILE: /run/secrets/db_password # Good # DB_PASSWORD: "plaintext" # Avoid
-
Limit Network Exposure:
- Only expose ports that need to be public
- Use internal Docker networks for service communication
-
Drop Unnecessary Capabilities:
{ "cap_drop": ["ALL"], "cap_add": ["NET_BIND_SERVICE"] }
-
Watch Deployment Progress:
- Monitor real-time progress in UI
- Check for warnings or errors
- Review logs if deployment fails
-
Verify Deployment Success:
- Check container is running
- Test application endpoints
- Review container logs
-
Use Health Checks:
{ "healthcheck": { "test": ["CMD", "curl", "-f", "http://localhost/health"], "interval": "30s", "timeout": "10s", "retries": 3 } }
Cause: Large image or slow network
Solution:
- Wait for image download to complete
- Check network connectivity
- Consider deploying a smaller image variant
- Pull image manually first:
docker pull <image>
Cause: Invalid image name or tag
Solution:
- Verify image exists on Docker Hub or registry
- Check spelling and tag
- Use
docker pull <image>to test manually - Check registry credentials if using private registry
Cause: Another container using the same host port
Solution:
- Change host port in deployment configuration
- Stop conflicting container
- Check with:
docker psand look for port mappings
Cause: Container takes too long to start or health check misconfigured
Solution:
- Increase health check timeout in Settings
- Check container logs:
/logspage - Verify health check command is correct
- Container might need more resources (increase memory limit)
Cause: CRITICAL security issue detected
Solution:
- Review security error message
- Fix the security issue (recommended)
- Remove
privileged: true - Remove dangerous volume mounts
- Use specific capabilities instead
- Remove
- Or contact administrator for override
Cause: Post-creation step failed (health check, etc.)
Note: Container is preserved (commitment point protection)
Solution:
- Check container status:
docker ps -a - Check logs from Logs page or
docker logs <container-id> - Investigate and fix issue
- Option A: Fix and restart container
- Option B: Delete deployment and recreate with fixes
Cause: Deployment reached commitment point
Explanation:
- Container was successfully created
- Rollback would destroy working container
- This is intentional for data safety
Solution:
- Manually stop and remove container if needed
- Or investigate and fix the container
Cause: Services started in wrong order
Solution:
- Add
depends_onto Docker Compose YAML - Ensure dependency services are healthy before starting dependent services
Cause: Variable name mismatch or undefined variable
Solution:
- Check variable name matches exactly (case-sensitive)
- Verify variable is defined in template
variablessection - Use format:
${VARIABLE_NAME}(uppercase with underscores) - Ensure variable value provided when deploying from template
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