Dockhand Stack Management
This guide covers how to properly manage Docker Compose stacks with Dockhand to ensure all containers are tracked and manageable through the Dockhand interface.
Table of Contents
- Overview
- Prerequisites
- Adopting Existing Stacks into Dockhand
- Creating New Stacks
- Updating Stacks
- Important Rules
- Troubleshooting
Overview
Key Principle: All stack compose files should be located in /home/jeff/docker/[stack-name]/ for Dockhand to properly manage them.
Dockhand has two types of stacks:
- Internal Stacks: Fully managed by Dockhand with known compose file locations
- Untracked Stacks: Running stacks that Dockhand detects but doesn't know where the compose files are located
Our goal is to have all stacks as Internal stacks for full management capabilities.
Note on Container Updates: This documentation reflects that Internal stacks should be safe to update via the Containers tab because Dockhand knows the compose file location and can reference the full configuration. This is based on experience with similar tools (Portainer, Dockge) and the difference between Internal vs. Untracked stacks. The guidance will be validated through real-world testing and updated if needed.
Prerequisites
Dockhand Configuration
Ensure Dockhand has access to your docker directory. Your Dockhand compose.yml should include:
services:
dockhand:
image: fnsys/dockhand:latest
container_name: dockhand
restart: unless-stopped
ports:
- 3003:3000
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./dockhand_data:/app/data
- /home/jeff/docker:/home/jeff/docker # Critical mount
Never adopt Dockhand's own stack into Dockhand. Manage Dockhand via Dockge or CLI only.
Adopting Existing Stacks into Dockhand
Scenario 1: Stack Already in /home/jeff/docker
If your stack is already located in /home/jeff/docker/[stack-name]/:
- Stop the running stack (important - prevents conflicts):
cd /home/jeff/docker/[stack-name]
docker compose down
- Adopt in Dockhand:
- Navigate to Stacks → Adopt
- Browse to
/home/jeff/docker/[stack-name] - Click on the
docker-compose.yaml(orcompose.yaml) file - Click Adopt
- Dockhand will automatically deploy the stack
- Verify Success:
- Stack should show as Internal in the Source column
- Location should show:
/home/jeff/docker/[stack-name]/docker-compose.yaml - Status should be running
Scenario 2: Stack Located Elsewhere (e.g., /opt/[stack-name])
If your stack is outside /home/jeff/docker:
- Stop the running stack:
cd /opt/[stack-name] # or wherever it's located
docker compose down
- Move the stack to the standard location:
sudo mv /opt/[stack-name] /home/jeff/docker/
sudo chown -R jeff:jeff /home/jeff/docker/[stack-name]
- Adopt in Dockhand (follow Scenario 1 steps above)
Scenario 3: Standalone Containers (Not Compose)
If containers were created with docker run commands (showing as Untracked):
- Document the current configuration:
docker inspect [container-name] > /tmp/[container-name]-config.json
- Create a compose file:
mkdir -p /home/jeff/docker/[stack-name]
cd /home/jeff/docker/[stack-name]
nano docker-compose.yaml
- Recreate as compose using the inspect output for reference
- Stop the old container:
docker stop [container-name]
docker rm [container-name]
- Adopt the new compose file (follow Scenario 1)
Creating New Stacks
Never create stacks directly in Dockhand's UI. This creates them in Dockhand's internal directory structure, making them harder to manage outside of Dockhand.
Recommended Workflow
- Create the directory structure:
mkdir -p /home/jeff/docker/[new-stack-name]
cd /home/jeff/docker/[new-stack-name]
- Create the docker-compose.yaml file:
nano docker-compose.yaml
Example structure:
services:
app:
image: someapp:latest
container_name: [stack-name]
ports:
- "8080:80"
volumes:
- ./data:/data
environment:
- VARIABLE=value
restart: unless-stopped
- Create .env file for sensitive data (optional but recommended):
nano .env
Example:
# Application Configuration
DATABASE_PASSWORD=your-secure-password
API_KEY=your-api-key
- Do NOT start the stack yet:
# DO NOT RUN: docker compose up -d
- Adopt into Dockhand:
- Navigate to Stacks → Adopt
- Browse to
/home/jeff/docker/[new-stack-name] - Click on
docker-compose.yaml - Click Adopt
- Dockhand will deploy the stack automatically
- Verify:
- Check that stack shows as Internal
- Verify containers are running
- Test the application
Alternative: Edit After Adopting
If you prefer to use Dockhand's editor:
- Create the directory and minimal compose file as above
- Adopt into Dockhand (it will fail to start due to incomplete config)
- Click on the stack → Edit
- Complete the configuration in Dockhand's editor
- Click Save & redeploy
Updating Stacks
Understanding Update Safety
The safety of updating from the Containers tab depends on whether your stack is Internal or Untracked:
| Stack Type | Containers Tab Update | Why |
|---|---|---|
| Internal | ✅ Likely Safe | Dockhand knows the compose file location and can reference the full configuration |
| Untracked | ❌ Not Safe | Dockhand doesn't know where the compose file is and can only use Docker's stored config |
Update Methods
Method 1: Containers Tab (For Internal Stacks)
Once your stacks are adopted as "Internal", updating from the Containers tab should preserve all configuration:
- Navigate to Containers tab
- Click Check for updates
- Update individual containers or Update all
What gets preserved:
- Environment variables (from compose file and .env)
- Volume mounts
- Network configurations
- Port mappings
- Dependencies
Important: This method is ONLY recommended for stacks showing as "Internal" in the Stacks tab. Never use this for "Untracked" stacks.
Method 2: CLI Update (Always Safe)
This method works for both Internal and Untracked stacks:
cd /home/jeff/docker/[stack-name]
docker compose pull
docker compose up -d
Benefits:
- Guaranteed to use compose file configuration
- Works regardless of Internal/Untracked status
- Full control over the update process
Method 3: Edit and Redeploy in Dockhand
For Internal stacks in Dockhand:
- Stacks → Click on stack → Edit
- Modify if needed (or just trigger a redeploy)
- Click Save & redeploy
Note: This method requires a change in the compose file to trigger an image pull. Simply clicking "Save & redeploy" without changes may not pull new images.
Method 4: Auto-Update (Recommended for Maintenance)
Configure automatic updates at the stack level:
- Stacks → Click on stack
- Look for Settings or Auto-update tab
- Enable Auto-update
- Configure schedule (daily/weekly/custom cron)
- Set vulnerability criteria if using scanning
- Save
Verification After Updates
After updating any stack (especially the first few times using Containers tab), verify configuration is intact:
# Check environment variables
docker inspect [container-name] | grep -A 30 "Env"
# Check volume mounts
docker inspect [container-name] | grep -A 10 "Mounts"
# Check networks
docker inspect [container-name] | grep -A 5 "Networks"
# Test the application
# Access the web UI or API to ensure it works correctly
Critical Rules for Updates
✅ SAFE Methods:
For Internal Stacks:
- Containers tab updates (Check for updates → Update)
- CLI:
docker compose pull && docker compose up -d - Stacks tab: Edit → Save & redeploy
- Enable auto-updates at stack level
For Untracked Stacks:
- CLI:
docker compose pull && docker compose up -d(ONLY safe method) - Adopt the stack first, then use any method above
❌ UNSAFE Methods:
Never do this for Untracked stacks:
- Containers → Check for updates → Update
- Containers → Update all
Why Untracked Updates Fail: When a stack is Untracked, Dockhand cannot reference the compose file. Updates use only Docker's stored container configuration, which may be incomplete and can lose:
- Environment variables from .env files
- Custom network configurations
- Dependency relationships
- Volume mount details
Example of what can go wrong: Updating an Untracked n8n stack lost the N8N_ENCRYPTION_KEY environment variable, breaking MFA and requiring database repairs.
Update Workflow Recommendation
First-time setup (for each stack):
- Ensure stack is adopted as "Internal"
- Perform first update using CLI method
- Verify all configuration is preserved
- Once confirmed working, you can use Containers tab for future updates
Ongoing updates:
- Use Containers tab for routine updates (after verifying it works for your setup)
- Use CLI for critical stacks or when you want absolute certainty
- Consider enabling auto-updates for non-critical stacks
Important Rules
✅ DO:
- Create all stack compose files in
/home/jeff/docker/[stack-name]/ - Adopt stacks into Dockhand before starting them
- Verify stacks show as "Internal" in the Stacks tab
- Update Internal stacks via Containers tab OR CLI (both should work)
- Update Untracked stacks ONLY via CLI
- Use
.envfiles for sensitive configuration - Keep compose files version-controlled (git)
❌ DON'T:
- Create stacks directly in Dockhand's UI (creates them in internal directories)
- Update Untracked stacks from the Containers tab
- Adopt Dockhand's own stack into Dockhand
- Edit running containers directly without updating the compose file
- Use
docker runfor new containers (use compose instead)
Update Safety by Stack Type
| Stack Status | Containers Tab | CLI | Stacks Tab | Auto-Update |
|---|---|---|---|---|
| Internal | ✅ Safe* | ✅ Safe | ✅ Safe | ✅ Safe |
| Untracked | ❌ Unsafe | ✅ Safe | ❌ N/A | ❌ N/A |
*After verifying it works correctly for your environment. Test carefully the first few times.
Stack Naming Conventions
- Use lowercase with hyphens:
my-app-name - Be descriptive:
jellyfinnotmedia - Match the directory name to stack name for clarity
Directory Structure Example
/home/jeff/docker/
├── dockhand/
│ ├── compose.yml
│ └── dockhand_data/
├── n8n/
│ ├── docker-compose.yaml
│ └── .env
├── jellyfin/
│ ├── docker-compose.yaml
│ └── config/
├── seafile/
│ ├── docker-compose.yaml
│ ├── .env
│ ├── seafile-data/
│ └── mysql/
└── [new-stack]/
├── docker-compose.yaml
└── .env
Troubleshooting
Stack Shows as "Untracked"
Problem: Stack is running but shows as "Untracked" in Dockhand
Solution:
- Stop the stack:
docker compose down - Adopt the compose file via Stacks → Adopt
- Dockhand will deploy and track it
"Stack directory not found" Error During Adoption
Problem: Adoption fails with directory error
Solutions:
- Verify the compose file exists at the path
- Check Dockhand has the volume mount:
/home/jeff/docker:/home/jeff/docker - Restart Dockhand:
docker restart dockhand - Check directory permissions:
ls -la /home/jeff/docker/[stack-name]
Can't See /home/jeff/docker in Adopt Browser
Problem: Adopt browser doesn't show your docker directory
Solution: Check Dockhand's compose file includes the volume mount:
volumes:
- /home/jeff/docker:/home/jeff/docker
Restart Dockhand if you just added it:
cd /home/jeff/docker/dockhand
docker compose down
docker compose up -d
Encryption Key Mismatch (n8n, etc.)
Problem: After updating, apps like n8n show encryption key errors or MFA failures
Cause: Updated an Untracked stack via Containers tab instead of adopting it first
Prevention:
- Adopt all stacks as "Internal" before updating
- For Internal stacks, Containers tab updates should preserve configuration
- For critical stacks with encryption keys, consider using CLI updates for extra safety
Recovery:
- Fix the compose file to include correct environment variables
- Redeploy from Stacks tab or CLI
- May need to disable/reset features like MFA (database recovery may be required)
Lost Configuration After Update
Problem: Container lost environment variables, volumes, or settings after update
Cause: Updated an Untracked stack via Containers tab
Solution:
- Adopt the stack as Internal first
- Check the compose file has all configuration
- Redeploy via Stacks → Edit → Save & redeploy or CLI
Prevention: Only update from Containers tab after stack is adopted as "Internal"
Quick Reference Commands
# Create new stack structure
mkdir -p /home/jeff/docker/[stack-name]
cd /home/jeff/docker/[stack-name]
nano docker-compose.yaml
# Then adopt via Dockhand UI
# Move existing stack to standard location
sudo mv /path/to/stack /home/jeff/docker/[stack-name]
sudo chown -R jeff:jeff /home/jeff/docker/[stack-name]
cd /home/jeff/docker/[stack-name]
docker compose down
# Then adopt via Dockhand UI
# Update stack via CLI (always safe)
cd /home/jeff/docker/[stack-name]
docker compose pull
docker compose up -d
# Update via Containers tab (for Internal stacks)
# Navigate to Containers → Check for updates → Update
# Verify afterwards with commands below
# Verify configuration after update
docker inspect [container-name] | grep -A 30 "Env"
docker inspect [container-name] | grep -A 10 "Mounts"
docker inspect [container-name] | grep -A 5 "Networks"
# Check stack status
docker compose ps
docker compose logs -f
# View all stacks
ls -la /home/jeff/docker/
# Restart Dockhand
cd /home/jeff/docker/dockhand
docker compose restart
Additional Resources
- Dockhand Documentation: https://dockhand.pro/manual/
- Docker Compose Reference: https://docs.docker.com/compose/
- Your Dockhand Instance: http://your-server:3003
Last Updated: February 14, 2026