Skip to content

almightyvats/herd

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

herd

Manage remote services from a single CLI — Docker Compose stacks and bare-metal scripts alike. Syncs files via rsync, then controls services over SSH.

Prerequisites

Local (the machine running herd):

  • bash 4+
  • ssh with key-based auth configured for every target server (no password prompts)
  • rsync

Remote (each target server):

  • Docker and Docker Compose

    curl -fsSL https://get.docker.com | sh

    This installs Docker Engine and the Compose plugin (docker compose) in one shot.

  • aria2c — only required if you use herd dl

    # Debian / Ubuntu
    sudo apt install aria2

SSH Config

herd uses short host aliases everywhere (my-server, my-pve, …). Define them in ~/.ssh/config so SSH knows how to reach each host:

Host my-server
    HostName 192.168.1.50
    User docker
    IdentityFile ~/.ssh/id_ed25519

Host my-pve
    HostName 192.168.1.10
    User root
    IdentityFile ~/.ssh/id_ed25519

Host my-vm
    HostName 192.168.1.20
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519

Test each connection before using herd:

ssh my-server "docker ps"

Installation

Copy herd somewhere on your PATH and make it executable:

cp herd ~/.local/bin/herd
chmod +x ~/.local/bin/herd

Or symlink it so changes in this repo take effect immediately:

ln -s "$PWD/herd" ~/.local/bin/herd

Workspace Setup

herd discovers its workspace by walking up from $PWD until it finds a servers.conf file (same behaviour as git finding .git). The directory containing servers.conf is the workspace root.

servers.conf

Maps SSH host aliases to the remote directory where services live. A template is provided at servers.conf.example — copy and edit it:

# host-alias = /remote/path/to/appdata
my-unraid = /mnt/flash/appdata
my-server = /home/docker
my-pve    = /root
my-vm     = ~/docker

Directory Layout

Each server gets a subdirectory. Inside it, each service gets its own folder. herd syncs the local service folder to the matching path on the remote host.

my-services/                ← workspace root (contains servers.conf)
├── servers.conf
├── herd
├── my-server/
│   ├── nginx/
│   │   ├── compose.yaml
│   │   └── .env            ← gitignored
│   └── postgres/
│       └── compose.yaml
├── my-pve/
│   └── my-agent/
│       └── install.sh      ← bare-metal, no Docker
└── my-vm/
    └── grafana-stack/
        └── compose.yaml

.env files and secrets are gitignored. See .gitignore.

Shell Completion

herd ships with completion for bash and zsh. Servers and services are completed dynamically at tab-press time — no hardcoded lists.

bash — add to ~/.bashrc:

eval "$(herd completion bash)"

zsh — add to ~/.zshrc:

eval "$(herd completion zsh)"

Commands

Docker Compose

Command Arguments What it does
deploy <server> <service> Sync files then docker compose up -d
sync <server> <service> Sync files only, no restart
down <server> <service> docker compose down — stop and remove containers
restart <server> <service> docker compose restart — restart in-place
pull <server> <service> Pull latest images
logs <server> <service> [args] View logs — pass -f to follow
ps <server> List all containers on a server
exec <server> <container> [cmd] Open a shell inside a running container

System

Command Arguments What it does
run <server> <service> <script> Sync files then run a shell script on the host
dl <server> <url> [dir] Download a file on the remote host (aria2c must be installed there)
cpy <server> <remote> <local> Copy a file or directory from remote to local

Examples

# Deploy (sync + bring up) nginx on my-server
herd deploy my-server nginx

# Follow logs, last 50 lines
herd logs my-server nginx -f --tail 50

# List all containers on my-pve
herd ps my-pve

# Open a shell in the nginx container
herd exec my-server nginx

# Run a one-off command without opening a full shell
herd exec my-server nginx "nginx -t"

# Run a bare-metal install script on my-pve
herd run my-pve my-agent install.sh

# Download a file to a specific remote directory
herd dl my-unraid https://example.com/file.tar.gz /mnt/flash/downloads

# Pull a file back to your local machine
herd cpy my-server /home/docker/nginx/nginx.conf ./backups/

Environment Variable Override

Set HERD_WORKSPACE to point herd at a specific workspace regardless of where you run it from:

export HERD_WORKSPACE=/home/user/work/internal-services

About

Agentless remote service manager. Deploy Docker Compose stacks and run bare-metal scripts across multiple servers with zero remote configuration.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages