diff --git a/README.md b/README.md index 3457ec4..b638e0d 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ If you would like to add a new config, you can use the [service-template](templa ### 📊 Dashboards and Visualization | 📊 Service | 📝 Description | 🔗 Link | -| -------------- | ------------------------------------------------------------------------------------ | ---------------------------- | +| -------------- | ------------------------------------------------------------------------------------ | ---------------------------- | | 🧭 **Glance** | A concise, customizable dashboard for self-hosted services and personal metrics. | [Details](services/glance) | | 🏠 **Homepage** | A modern, highly customizable homepage for organizing links and monitoring services. | [Details](services/homepage) | @@ -126,18 +126,19 @@ If you would like to add a new config, you can use the [service-template](templa | 🛠️ Service | 📝 Description | 🔗 Link | | ------------------------ | ------------------------------------------------------------------------------------------------------ | ----------------------------------- | +| 🧰 **Arcane** | A self-hosted Docker management UI for Compose stacks; this repo includes a Tailscale sidecar example. | [Details](services/arcane) | | 🖥️ **Changedetection.io** | A tool for monitoring website changes. | [Details](services/changedetection) | | 🛠️ **Coder** | Self-hosted cloud dev environments with browser IDEs, Terraform-managed workspaces. | [Details](services/coder) | | 🔧 **Cyberchef** | A web app for encryption, encoding, compression, and data analysis. | [Details](services/cyberchef) | +| 🐳 **Dockhand** | A modern, lightweight Docker management UI for containers and Compose stacks. | [Details](services/dockhand) | | 🖥️ **Dozzle** | A real-time log viewer for Docker containers. | [Details](services/dozzle) | -| 🖥️ **GitSave** | A self-hosted service to back up your GitHub repositories via a simple REST API and scheduled runs. | [Details](services/gitsave) | | 🔁 **FossFLOW** | A self-hosted tool to make beautiful isometric infrastructure diagrams. | [Details](services/fossflow) | +| 🖥️ **GitSave** | A self-hosted service to back up your GitHub repositories via a simple REST API and scheduled runs. | [Details](services/gitsave) | | 🖥️ **Gokapi** | A lightweight self-hosted file sharing platform. | [Details](services/gokapi) | | 🖥️ **Homarr** | A sleek dashboard for all your Homelab services. | [Details](services/homarr) | | 🖥️ **IT-Tools** | A collection of handy online tools for developers and sysadmins. | [Details](services/it-tools) | | 🖥️ **Node-RED** | A flow-based development tool for visual programming. | [Details](services/nodered) | | 🖥️ **Portainer** | A lightweight management UI which allows you to easily manage your Docker environments. | [Details](services/portainer) | -| 🧰 **Arcane** | A self-hosted Docker management UI for Compose stacks; this repo includes a Tailscale sidecar example. | [Details](services/arcane) | | 🔍 **searXNG** | A free internet metasearch engine which aggregates results from various search services. | [Details](services/searxng) | ### 📈 Monitoring and Analytics diff --git a/services/dockhand/.env b/services/dockhand/.env new file mode 100644 index 0000000..ac0c5d2 --- /dev/null +++ b/services/dockhand/.env @@ -0,0 +1,17 @@ +#version=1.1 +#URL=https://github.com/tailscale-dev/ScaleTail +#COMPOSE_PROJECT_NAME= # Optional: only use when running multiple deployments on the same infrastructure. + +# Service Configuration +SERVICE=dockhand # Service name (e.g., adguard). Used as hostname in Tailscale and for container naming (app-${SERVICE}). +IMAGE_URL=fnsys/dockhand:latest # Docker image URL from container registry (e.g., adguard/adguard-home). + +# Network Configuration +SERVICEPORT=3000 # Port to expose to local network. Uncomment the "ports:" section in compose.yaml to enable. +DNS_SERVER=9.9.9.9 # Preferred DNS server for Tailscale. Uncomment the "dns:" section in compose.yaml to enable. + +# Tailscale Configuration +TS_AUTHKEY= # Auth key from https://tailscale.com/admin/authkeys. See: https://tailscale.com/kb/1085/auth-keys#generate-an-auth-key for instructions. + +# Optional Service variables +# PUID=1000 \ No newline at end of file diff --git a/services/dockhand/README.md b/services/dockhand/README.md new file mode 100644 index 0000000..5f764ec --- /dev/null +++ b/services/dockhand/README.md @@ -0,0 +1,38 @@ +# Dockhand with Tailscale Sidecar Configuration + +This Docker Compose configuration sets up **Dockhand** with a Tailscale sidecar container, enabling secure access to your self-hosted Docker management interface over your private Tailscale network. With this setup, your Dockhand instance remains private and accessible only from authorized devices on your Tailnet, ensuring that container management and infrastructure controls are never exposed to the public internet. + +## Dockhand + +[**Dockhand**](https://github.com/Finsys/dockhand) is a modern, lightweight Docker management UI focused on real-time container operations and multi-environment orchestration. It provides an intuitive interface for managing containers, images, volumes, networks, and Docker Compose stacks across local or remote Docker hosts. + +Dockhand is designed for operators and homelab environments that want a clean, responsive alternative to heavier container management platforms, while still retaining full control over their infrastructure. + +## Key Features + +- Container Management – Start, stop, restart, and inspect containers in real time. +- Compose Stack Support – Deploy and manage Docker Compose applications. +- Multi-Environment Support – Connect to and manage multiple Docker hosts. +- Live Logs & Terminal – Stream logs and access container terminals directly from the UI. +- File & Volume Access – Inspect volumes and container file systems. +- Git-Based Deployments – Deploy stacks from Git repositories with optional sync. +- Docker-Native – Built specifically for Docker environments. +- Open Source – Community-driven and self-hostable. + +## Why Self-Host? + +A Docker management interface has full control over your infrastructure. Exposing such a tool publicly significantly increases risk, as it can allow attackers to manipulate containers, access secrets, or pivot deeper into your network. + +Self-hosting Dockhand ensures that you maintain full ownership and operational control. When combined with Tailscale, Dockhand becomes a secure, private control plane for your Docker environments, accessible only from authenticated devices within your Tailnet. This dramatically reduces the attack surface while preserving remote management convenience. + +## Configuration Overview + +In this deployment, a Tailscale sidecar container (for example `tailscale-dockhand`) runs the Tailscale client and joins your private Tailscale network. The main `dockhand` service uses: + +```plain +network_mode: service:tailscale-dockhand +``` + +This configuration routes all inbound and outbound traffic through the Tailscale interface, ensuring that the Dockhand web interface and Docker API interactions are accessible only via your Tailscale network. + +By avoiding public port mappings and relying exclusively on Tailnet access, you create a secure-by-default Docker management setup suitable for homelabs, remote infrastructure, and internal DevOps environments. diff --git a/services/dockhand/compose.yaml b/services/dockhand/compose.yaml new file mode 100644 index 0000000..e57b35d --- /dev/null +++ b/services/dockhand/compose.yaml @@ -0,0 +1,69 @@ +configs: + ts-serve: + content: | + {"TCP":{"443":{"HTTPS":true}}, + "Web":{"$${TS_CERT_DOMAIN}:443": + {"Handlers":{"/": + {"Proxy":"http://127.0.0.1:3000"}}}}, + "AllowFunnel":{"$${TS_CERT_DOMAIN}:443":false}} + +services: + # Make sure you have updated/checked the .env file with the correct variables. + # All the ${ xx } need to be defined there. + # Tailscale Sidecar Configuration + tailscale: + image: tailscale/tailscale:latest # Image to be used + container_name: tailscale-${SERVICE} # Name for local container management + hostname: ${SERVICE} # Name used within your Tailscale environment + environment: + - TS_AUTHKEY=${TS_AUTHKEY} + - TS_STATE_DIR=/var/lib/tailscale + - TS_SERVE_CONFIG=/config/serve.json # Tailscale Serve configuration to expose the web interface on your local Tailnet - remove this line if not required + - TS_USERSPACE=false + - TS_ENABLE_HEALTH_CHECK=true # Enable healthcheck endpoint: "/healthz" + - TS_LOCAL_ADDR_PORT=127.0.0.1:41234 # The : for the healthz endpoint + #- TS_ACCEPT_DNS=true # Uncomment when using MagicDNS + - TS_AUTH_ONCE=true + configs: + - source: ts-serve + target: /config/serve.json + volumes: + - ./config:/config # Config folder used to store Tailscale files - you may need to change the path + - ./ts/state:/var/lib/tailscale # Tailscale requirement - you may need to change the path + devices: + - /dev/net/tun:/dev/net/tun # Network configuration for Tailscale to work + cap_add: + - net_admin # Tailscale requirement + #ports: + # - 0.0.0.0:${SERVICEPORT}:${SERVICEPORT} # Binding port ${SERVICEPORT} to the local network - may be removed if only exposure to your Tailnet is required + # If any DNS issues arise, use your preferred DNS provider by uncommenting the config below + # dns: + # - ${DNS_SERVER} + healthcheck: + test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:41234/healthz"] # Check Tailscale has a Tailnet IP and is operational + interval: 1m # How often to perform the check + timeout: 10s # Time to wait for the check to succeed + retries: 3 # Number of retries before marking as unhealthy + start_period: 10s # Time to wait before starting health checks + restart: always + + # ${SERVICE} + application: + image: ${IMAGE_URL} # Image to be used + network_mode: service:tailscale # Sidecar configuration to route ${SERVICE} through Tailscale + container_name: app-${SERVICE} # Name for local container management + environment: + - HOST_DATA_DIR=/app/data + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./dockhand-data:/app/data # Data directory for Dockhand - you may need to change the path + depends_on: + tailscale: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-fsS", "http://127.0.0.1:41234/healthz"] # Check if ${SERVICE} is responding + interval: 1m # How often to perform the check + timeout: 10s # Time to wait for the check to succeed + retries: 3 # Number of retries before marking as unhealthy + start_period: 30s # Time to wait before starting health checks + restart: always \ No newline at end of file