Deploying Dockhand: A Detailed Technical Guide 2026

Deploying Dockhand: A Detailed Technical Guide

Dockhand is a modern, intuitive Docker management tool for handling containers, stacks, updates, logs, and multi-host environments. It’s source-available under BSL 1.1 (Business Source License), with full code on GitHub (GitHub - Finsys/dockhand: Dockhand - Docker management you will like.). This guide focuses on deployment, drawing from official documentation and best practices. It’s designed for technical users, emphasizing security, configuration, and scalability. Assume a Linux host unless noted.

Prerequisites

  • Docker Engine: Version 20.10 or later (API 1.41+).
  • Hardware: Minimum 512 MB RAM (1 GB recommended for production).
  • Browser: Latest Chrome, Firefox, Safari, or Edge.
  • Database: SQLite (default, embedded) or PostgreSQL 14+ for larger setups.
  • Permissions: Dockhand requires Docker socket access for management. Run as non-root where possible.
  • Network: For remote hosts, ensure firewall allows necessary ports (e.g., 2375/2376 for TCP, or use agents).
  • Security Note: Dockhand has privileged access to Docker. Always enable authentication immediately after launch to mitigate risks. Use reverse proxies for external exposure.

Verify Docker installation:

docker --version

Quick Start: Basic Deployment

For a single-host setup, use Docker or Docker Compose. This mounts the Docker socket for control and persists data.

Using Docker (Simple Run)

Pull and run the latest image:

docker run -d \
  --name dockhand \
  --restart unless-stopped \
  -p 3000:3000 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v dockhand_data:/app/data \
  fnsys/dockhand:latest
  • Access at http://localhost:3000.
  • The -v dockhand_data:/app/data uses a named volume for persistence (SQLite DB, configs).

Using Docker with Custom Data Directory (Bind Mount)

For relative paths in Compose files (e.g., ./config.yml), match host and container paths:

mkdir -p /opt/dockhand
docker run -d \
  --name dockhand \
  --restart unless-stopped \
  -p 3000:3000 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /opt/dockhand:/opt/dockhand \
  -e DATA_DIR=/opt/dockhand \
  fnsys/dockhand:latest
  • DATA_DIR env var sets the internal data path.

Using Docker Compose

Create docker-compose.yml:

services:
  dockhand:
    image: fnsys/dockhand:latest
    container_name: dockhand
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - dockhand_data:/app/data
volumes:
  dockhand_data:

Run:

docker compose up -d

First-Time Setup and Security

  1. Access the UI: Open http://<host-ip>:3000. Authentication is disabled initially.
  2. Enable Authentication:
    • Navigate to Settings > Authentication.
    • Create an admin user (strong password required).
    • Toggle authentication ON.
    • Refresh the page; you’ll be prompted to log in.
  3. Add Environment:
    • Go to Settings > Environments > Add Environment.
    • Name it (e.g., “production”).
    • Set connection type to “Unix socket” for local host.
    • Save and test connection.
  4. Security Best Practices:
    • Immediate Auth: Never leave auth disabled; Dockhand controls all containers.
    • Reverse Proxy: Expose via HTTPS only (see examples below).
    • Socket Permissions: Avoid chmod 666 /var/run/docker.sock (high risk).
    • Vulnerability Scanning: Enable Grype/Trivy in Settings > Environment > Security for image scans on pulls/updates.
    • No Telemetry: Verified source-available; no phoning home.
    • Hardened Image: Built minimally (no unnecessary deps); audit via GitHub.

Handling Docker Socket Permissions

Dockhand runs as non-root by default but needs socket access. Choose an option based on security needs.

Option Description Pros Cons When to Use
Match Docker GID Add container to host’s Docker group. Simple, non-root. Requires knowing GID. Standard Linux setups.
Run as Root Use --user 0:0. Easy access. Elevated privileges. Quick tests.
PUID/PGID Set env vars for custom UID/GID. Matches host user. Setup overhead. Production with specific users.
User Directive -u <uid>:<gid>. Precise control. Bind mounts only (no named volumes). Advanced, chown data dir first.
Socket Proxy Use tecnativa/docker-socket-proxy. Isolated access. Extra container. High-security environments.

Example: Match Docker GID

Find GID:

stat -c '%g' /var/run/docker.sock  # e.g., 999

Docker Compose:

services:
  dockhand:
    # ... other config
    group_add:
      - "999"

Example: Socket Proxy (Most Secure)

docker-compose.yml:

services:
  socket-proxy:
    image: tecnativa/docker-socket-proxy
    restart: unless-stopped
    environment:
      CONTAINERS: 1
      IMAGES: 1
      NETWORKS: 1
      VOLUMES: 1
      EVENTS: 1
      POST: 1
      DELETE: 1
      INFO: 1
      SYSTEM: 1
      ALLOW_START: 1
      ALLOW_STOP: 1
      ALLOW_RESTARTS: 1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - socket-proxy

  dockhand:
    image: fnsys/dockhand:latest
    restart: unless-stopped
    depends_on:
      - socket-proxy
    ports:
      - "3000:3000"
    volumes:
      - dockhand_data:/app/data
    networks:
      - socket-proxy

networks:
  socket-proxy:
    internal: true

volumes:
  dockhand_data:

In Dockhand UI: Set environment host to socket-proxy:2375.

Advanced Configuration

Using PostgreSQL (for Scalability)

Env var for connection:

-e DATABASE_URL=postgres://user:pass@host:5432/dockhand

Full Docker example:

docker run -d \
  --name dockhand \
  -p 3000:3000 \
  -e DATABASE_URL=postgres://user:pass@postgres-host:5432/dockhand \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v dockhand_data:/app/data \
  fnsys/dockhand:latest

Note: No auto-migration from SQLite; backup and import manually if switching.

Moving Data Directory

Stop, copy, restart:

docker stop dockhand
mkdir -p /opt/dockhand
docker run --rm -v dockhand_data:/source:ro -v /opt/dockhand:/target busybox cp -a /source/. /target/
docker rm dockhand
# Restart with new bind mount and DATA_DIR
docker volume rm dockhand_data  # Optional

Multi-Host Deployment

For remote hosts, use Hawser Agent (included tool for secure connections).

Install Hawser Agent on Remote Host

Linux script:

curl -fsSL https://raw.githubusercontent.com/Finsys/hawser/main/scripts/install.sh | bash

Docker:

docker run -d \
  --name hawser \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e HAWSER_TOKEN=your_secure_token \
  fnsys/hawser:latest

In Dockhand UI:

  • Settings > Environments > Add.
  • Type: Hawser Standard (LAN) or Edge (NAT/VPS).
  • Enter remote IP/token.
  • Test connection (WiFi-like icon).
Type Connectivity Security
Hawser Standard Inbound to agent. TLS optional.
Hawser Edge Outbound only (agent calls home). Ideal for firewalled hosts.
Direct TCP Exposed Docker API. Use TLS (2376).

Reverse Proxy Examples

Always proxy for HTTPS/WebSockets (required for terminals/logs).

Nginx

/etc/nginx/sites-enabled/dockhand.conf:

server {
  listen 443 ssl;
  server_name dockhand.example.com;
  ssl_certificate /path/to/cert.crt;
  ssl_certificate_key /path/to/key.key;

  location / {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

Reload: nginx -s reload.

Traefik (Docker Compose Labels)

Add to Dockhand service:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.dockhand.rule=Host(`dockhand.example.com`)"
  - "traefik.http.routers.dockhand.entrypoints=websecure"
  - "traefik.http.routers.dockhand.tls.certresolver=letsencrypt"
  - "traefik.http.services.dockhand.loadbalancer.server.port=3000"

Troubleshooting

  • Socket Errors: Check GID/group_add; use proxy if persistent.
  • Updates: Enable scheduled checks in Settings > Environment > Updates.
  • Logs: UI logs searchable; download via UI.
  • Vulnerabilities: Scans run automatically; review in container details.
  • Enterprise Features: RBAC, LDAP, audits require paid license ($499+/host/year).

For updates: docker pull fnsys/dockhand:latest && docker compose up -d. Monitor GitHub for releases (BSL → Apache in 2029 per roadmap).

This setup provides a secure, scalable Dockhand deployment. Test in a VM first for production. Refer to Dockhand User Manual for UI usage.

3 Likes

This is such a solid tool. I was thinking about keeping arcane or portainer (though I manage everything in tha CLI, but I want a nice overview) but this one looks soooo nice. Thank you! Will apply the socket-proxy option (though using - lscr.io/linuxserver/socket-proxy:latest)

1 Like