Best Practices
This guide collects practical recommendations for using Dockform v0.8 safely and effectively across development, staging, and production environments.
Core Principles
- Treat the manifest file as the source of truth; avoid imperative Docker commands
- Use a clear, stable
identifier(e.g.,myapp,server-name) - Leverage automatic discovery—structure directories, minimize manifest config
- Prefer small, focused changes and review with
dockform planbeforeapply
Project Structure
Follow the discovery convention for automatic stack detection:
my-project/
├── dockform.yml
├── default/ # Context name
│ ├── traefik/ # Stack: default/traefik
│ │ ├── compose.yaml
│ │ └── volumes/
│ │ └── config/
│ ├── web/ # Stack: default/web
│ │ ├── compose.yaml
│ │ ├── environment.env
│ │ └── secrets.env
│ └── db/
│ └── compose.yaml
└── production/ # Another context
└── web/
└── compose.yaml
Recommendations:
- Name context directories to match Docker context names
- Keep one Compose file per stack (use profiles for variants)
- Store filesets in
volumes/subdirectories within each stack - Use
environment.envandsecrets.envfor auto-discovery
Contexts and Multi-Host
- Define one context per Docker daemon (local, staging, production)
- Use Docker contexts for remote daemons via SSH
- Keep context-specific resources (volumes, networks) under that context
contexts:
local:
volumes:
dev-data: {}
staging:
volumes:
staging-data: {}
production:
volumes:
prod-data: {}
networks:
traefik: {}
Creating remote contexts
Volumes
- Declare named volumes under
contexts.<name>.volumes: - Reference them as
external: truein Compose files - Avoid defining named volumes directly in Compose—let Dockform manage them
- Regularly backup volumes;
destroyandprunewill remove labeled volumes
Networks
- Declare networks under
contexts.<name>.networks: - Reference them as
external: truein Compose files - Use environment-specific network names for strict isolation
- Dockform detects drift and recreates networks when configuration changes
Filesets
- Use the
volumes/directory convention for auto-discovery - Keep filesets focused—configs, static assets, seeds (not large data)
- Use
.dockform-excludefiles to skip build artifacts, VCS metadata, OS files - Set ownership via
.dockform-ownership.yamlwhen needed
default/web/volumes/
├── config/
│ ├── .dockform-exclude
│ └── nginx.conf
└── static/
├── index.html
└── styles.css
Example exclude file:
Stacks and Discovery
- Let discovery find your stacks—minimize explicit
stacks:entries - Use
stacks:only for augmentation: profiles, extra env, secrets, project name - Set a stable
project.namefor predictable container naming
Environment and Secrets
- Use
environment.envin stack directories for auto-discovery - Add stack-specific overrides via
stacks.<key>.environment.inline - Keep secrets in
secrets.env(SOPS-encrypted) for auto-discovery - Never commit unencrypted secrets; always use SOPS
- Use
dockform doctorto verify SOPS and key configuration - For CI/CD, inject key files via secrets management
Deployments
Use deployment groups for targeting specific environments:
deployments:
dev:
description: Local development
contexts: [local]
staging:
description: Staging environment
contexts: [staging]
production:
description: Production services
stacks:
- production/web
- production/api
- production/traefik
CI/CD Recommendations
- Use
dockform planin PRs to preview changes; require approval beforeapply - Pin the Docker context and set a clear identifier per environment
- Provide required env vars (including SOPS keys) via CI secrets
- Run
dockform validateas a pre-check step
.github/workflows/deploy.yml
jobs:
deploy:
steps:
- uses: actions/checkout@v4
- name: Validate manifest
run: dockform validate
- name: Plan changes
run: dockform plan --deployment ${{ github.event.inputs.environment }}
- name: Apply changes
run: dockform apply --deployment ${{ github.event.inputs.environment }} --skip-confirmation
Safety and Destructive Operations
Danger
destroy removes all labeled resources for the active identifier (containers, networks, volumes). Use with care and ensure backups exist.
- Always run
dockform planbeforeapplyto review changes - Keep recent backups for stateful volumes before destructive commands
- Consider using docker-volume-backup for automated backups
Performance
- Keep fileset sizes reasonable; use
.dockform-excludeaggressively - Minimize changes per deployment for faster diffs
- Use stable project and resource names to reduce churn and restarts
Troubleshooting
| Issue | Solution |
|---|---|
| Compose fails | Run docker compose -f <file> config to validate YAML |
| Service doesn't update | Check labels and config-hash drift with dockform plan |
| Volume/network missing in Compose | Ensure declared in manifest and referenced as external |
| Stack not discovered | Verify directory structure matches <context>/<stack>/compose.yaml |
| Secrets not decrypted | Run dockform doctor to check SOPS configuration |
Quick Reference
| Command | Purpose |
|---|---|
dockform plan |
Preview changes before applying |
dockform apply |
Apply changes to infrastructure |
dockform destroy |
Remove all managed resources |
dockform validate |
Validate manifest syntax |
dockform doctor |
Check environment and dependencies |
dockform dashboard |
Interactive TUI for monitoring |