← all projects

itool

local internal docker tools runner
repo docker homeserver localhost runner tools

itool — local internal tools runner

itool.sh is a small CLI for running many independent internal tools on a single machine in a predictable, conflict-free way using Docker.

The design is intentionally conservative: machine-local facts live in a registry, application facts stay inside projects, and itool only glues the two together.


What’s in this repository

.
├── itool.sh      # the CLI (symlink this into your PATH)
└── README.md     # this document

After cloning, install it like this:

ln -s $(pwd)/itool.sh ~/.local/bin/itool

Goals


Core invariants

  1. The registry owns machine-local facts only

    • Project path
    • Host port (unique per machine)
  2. Projects own application facts

    • Container port (PORT in .env)
    • How the server is started
    • Docker image and runtime config
  3. itool never guesses

    • If the project doesn’t declare its container port, startup fails
    • No “smart defaults” for app internals
  4. Ports are assigned once and stay stable

    • Auto-assigned at registration
    • Persisted in the registry
    • Reboots do not change them

File layout (outside this repo)

itool keeps all machine-local state under ~/.config/itools:

~/.config/itools/
  registry.ini

Each internal tool is a normal project directory:

project/
  docker-compose.yml
  docker-compose.override.yml   # generated, machine-local (DO NOT COMMIT)
  .env
  Dockerfile

Registry format (one file for all tools)

The registry lives at:

~/.config/itools/registry.ini

Each tool is a section containing only its path and host port.

Example

[taskpe]
path = /home/username/dev/python/task-progress-estimator
port = 8611

[search]
path = /home/username/dev/internal/search-service
port = 8612

That is the entire registry contract.


Port management


Project requirements

Every project must define its container port itself.

.env

PORT=8501

This is the port the application listens on inside the container.

docker-compose.yml

The base compose file must not hardcode host ports:

services:
  app:
    build: .
    env_file: .env
    restart: unless-stopped

Machine-local wiring (generated)

itool generates a compose override per project:

docker-compose.override.yml

# Generated by itool (machine-local). DO NOT COMMIT.
services:
  app:
    ports:
      - "8611:${PORT}"

This file is:


Commands

itool register <name> <path> [--port N]

itool edit-registry

itool list

itool info <name>

itool <name> up

Other lifecycle helpers

itool <name> down
itool <name> restart
itool <name> logs
itool <name> ps
itool <name> build
itool <name> path

URLs and networking

Each tool is reachable at:

http://<name>.local:<host_port>

Name resolution is intentionally outside the registry:


Example: taskpe (a webapp)

Project defines:

PORT=8501

Registry assigns:

port = 8611

Resulting URL:

http://taskpe.local:8611

The webapp still runs on 8501 internally; only the host port is machine-specific.


Behavior on reboot


What itool intentionally does not do


Mental model

If something is wrong, it fails loudly and early.


Running itool on a home-server setup

This section explains how to run itool on an always-on home server (NUC, mini-PC, NAS, or spare machine) so tools are reachable from your LAN and survive reboots without manual intervention.


Assumptions


Networking model (recommended)

Resulting URLs from other devices on your network:

http://homeserver:8611
http://homeserver:8612

This is the simplest, most robust setup for a home server.


Project configuration for LAN access

In each project’s .env:

PORT=8501
HOST=0.0.0.0

Ensure the app actually listens on 0.0.0.0:

If the app only binds to 127.0.0.1, it will not be reachable from other machines.


Docker restart behavior

All tools should include in docker-compose.yml:

restart: unless-stopped

This ensures:

Verify Docker itself is enabled:

sudo systemctl enable docker

Firewall considerations

If a firewall is enabled (e.g. ufw), allow the itool port range:

sudo ufw allow 8600:8999/tcp

Or selectively allow only ports in use:

sudo ufw allow 8611/tcp
sudo ufw allow 8612/tcp

Name resolution on the LAN

Option 1: Use the hostname (simplest)

Most home networks already support this:

http://homeserver:8611

No additional configuration required.

Option 2: Local DNS (optional)

If you run a local DNS (router, Pi-hole, dnsmasq):

This is purely cosmetic and not required for itool.


Managing tools remotely

From the server itself:

itool list
itool taskpe restart
itool search logs

From another machine:


Backups and persistence

Machine-local state to back up:

Project data:

Containers can always be recreated; the registry is what preserves stable ports.


Security notes

If you later need remote access, put a proxy (Caddy, Nginx) in front of selected tools explicitly—itool stays unchanged.


Summary for home-server usage

This keeps the home-server setup simple, resilient, and easy to reason about.