DockHand integration with Home Assistant

DockHand HA Cards

For many years, I used Portainer to manage my Docker containers, but it isn’t very convenient for updating Docker images. Originally, I integrated it into my Home Assistant UI using the Ingress integration from HACS, but recent versions required adjusting my Nginx reverse proxy configuration after every single update. On top of that, I used Updates2MQTT to get update notifications in Home Assistant and to update images directly from there. However, I still had to prune old images from my instance manually.

That’s when I found DockHand, which covers everything I need:

  • Smooth Home Assistant integration
  • Scheduled checks for available image updates
  • Updating images directly from Home Assistant
  • Scheduled pruning of unused images
Table of Contents
    Add a header to begin generating the table of contents

    Copmare Portiner and DockHand

    FeaturePortainer CEDockhand
    LicenseOpen source (zlib)BSL 1.1 (free for personal and internal business use)
    Container management (start, stop, logs, console)✅✅
    Compose stacks✅✅ Visual editor with env variables side-by-side
    Git deployment with auto-sync✅✅ Webhooks and auto-sync
    Multiple Docker hosts✅ Portainer Agent✅ Hawser agent
    Kubernetes support✅❌ Docker only
    Scheduled checks for image updates❌✅
    Scheduled automatic container updates❌ Only for Git-based stacks✅ Per container (daily, weekly, monthly)
    Scheduled pruning of unused images❌✅
    Vulnerability scanning❌✅
    SSO (OIDC/OAuth)✅✅
    Role-based access controlBasic (full RBAC in Business Edition)Enterprise edition only
    Home Assistant integrationCore integration (monitoring and basic control)HACS integrations with update entities and “Update image” buttons

    DockHand Deployment

    Dockhand should be deployed as a separate stack outside of its own management, because it can’t manage the stack it runs in. Updating or restarting that stack from Dockhand would stop Dockhand itself mid-operation.

    Let’s create necessary folder for it and docker compose file:

    💻
    sudo mkdir -p /opt/dockhand
    sudo mcedit /opt/dockhand/docker-compose.yml 

    Add the following config:

    📋
    services:
      dockhand:
        image: fnsys/dockhand:latest
        container_name: dockhand
        restart: unless-stopped
        volumes:
          - /etc/localtime:/etc/localtime:ro
          - /var/run/docker.sock:/var/run/docker.sock
          - /opt/dockhand/dockhand_data:/app/data
          - /opt/HA:/opt/HA
          - /opt/technitium:/opt/technitium
        network_mode: host
    
    • image: fnsys/dockhand:latest: the official Dockhand image from Docker Hub. Since Dockhand itself runs in a separate stack, I update it manually from time to time.
    • container_name: dockhand: a fixed container name, which makes it easier to find in logs and CLI commands.
    • restart: unless-stopped: Docker starts Dockhand automatically after a reboot or crash, unless I’ve stopped it on purpose.
    • /etc/localtime:/etc/localtime:ro: syncs the container’s time zone with the host, so scheduled update checks and image pruning run at the expected local time. It’s mounted read-only, since Dockhand only needs to read it.
    • /var/run/docker.sock:/var/run/docker.sock: gives Dockhand access to the Docker Engine API on the host. This is what allows it to manage containers, pull images and prune unused ones. Keep in mind that access to the Docker socket effectively means root access to the host, so don’t expose Dockhand to the internet without proper authentication.
    • /opt/dockhand/dockhand_data:/app/data: persistent storage for Dockhand’s database and settings, so nothing gets lost when the container is recreated.
    • /opt/HA:/opt/HA and /opt/technitium:/opt/technitium: the directories with the Compose files of the stacks I manage with Dockhand (Home Assistant and Technitium DNS). They’re mounted under the same paths as on the host, so relative paths in those Compose files resolve correctly when Dockhand deploys or updates the stacks.
      ⚠️ Adjust paths according to your setup.
    • network_mode: host: the container uses the host’s network stack directly, so the Dockhand UI is available on the host’s IP address without any port mapping (port 3000 by default).
    I use the following simple script placed in the same directory as docker compose file to pull last image version and start the stack:
    💻
    #!/bin/sh
    
    docker compose pull
    docker compose up -d --remove-orphans
    docker image prune -fa

    Now start DockHand and open it with URL http://YOUR_HOST_IP:3000

    Deploy Hawser Agent

    If you run Docker stacks on several hosts, you can easily manage all of them from a single Dockhand instance using Hawser agents.

    First, create the necessary folder and a Docker Compose file for Hawser on your remote host:

    💻
    sudo mkdir -p /opt/hawser
    sudo mcedit /opt/hawser/docker-compose.yml 

    Add the following config:

    📋
    services:
      hawser:
        image: ghcr.io/finsys/hawser:latest
        container_name: hawser
        restart: unless-stopped
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - /opt/stacks:/opt/stacks   # your compose files, same path inside and out
        environment:
          - TOKEN=TOP_SECRET   # choose any strong token
          - AGENT_NAME=HOME    # friendly name shown in Dockhand
        network_mode: host
    
    
    • image: ghcr.io/finsys/hawser:latest: the official Hawser agent image from GitHub Container Registry.
    • container_name: hawser and restart: unless-stopped: a fixed container name, and automatic restart after a reboot or crash unless the agent was stopped on purpose.
    • /var/run/docker.sock:/var/run/docker.sock: gives Hawser access to the Docker Engine on the remote host, so Dockhand can manage its containers, images and stacks through the agent.
    • /opt/stacks:/opt/stacks: the directory with the Compose files of the stacks on this host. It’s mounted under the same path inside and outside the container, so relative bind mounts in those Compose files resolve correctly.
    • TOKEN: the shared secret Dockhand uses to authenticate to the agent. Use a long random string, for example generated with openssl rand -base64 32 or with Dockhand’s built-in generator.
    • AGENT_NAME: a friendly name shown in Dockhand instead of the hostname.
    • network_mode: host: the agent listens directly on the host’s network on port 2376, without any port mapping.

     

    DockHand Configuration

    Unfortunately, unlike Portainer, Dockhand doesn’t add environments automatically, so you have to add them manually:

    1. Navigate to Settings.
    2. Open the Environments tab.
    3. Click Add Environment.
    4. Choose Unix socket for the local host, or Hawser agent (standard) for a remote one.
    Add Environment

    Check your parameters with clicking on Test connection button and switch to Updates tab:

    Update Settings

    I recommend enabling update checks and automatic image pruning. Automatic updates are available too, but only if you enjoy surprises, like a broken Home Assistant while you’re on vacation.

    Now, navigate to Stacks and chose one them:

    Stack View

    Most likely, you’ll see Browse for compose file button instead of your docker compose file, so you need to click on it and navigate DockeHand to your file.

    As can you see, basic setup is pretty simple.

    DockHand integration with Home Assistant

    This integration is sipmle and streight forward as well. Just install Dockhand integration and Dockhand cars from HACS and configure them.

    DockHand HACS integration

    Once the Dockhand integration is configured, just start adding a card to your dashboard, and you’ll find the Dockhand cards there, already preconfigured. At most, a couple of small adjustments may be needed.

    Scroll to Top