Toolbox for generating mkcert certificates, inspecting containers & debugging networks.
10K+
A lightweight, multi-tool Docker image for:
mkcert + certify)mkhost) + templatesdelhost)senv)notifierd + notify + host docknotify)docker-cli + compose + lazydocker)netx, dig, mtr, traceroute, nmap, etc.)git, jq, yq, rg, fd, sqlite, shellcheck, nano, etc.)mkcert bundledcertify scans vhosts under /etc/share/vhosts/** and generates:
.p12 for Nginx client)example.com.conf β example.com + *.example.com)localhost, 127.0.0.1, ::1CAROOT=/etc/share/rootCAmkhost generates Nginx/Apache vhost configs using predefined templates/etc/share/runtime-versions.json (override via RUNTIME_VERSIONS_DB)ACTIVE_PHP_PROFILE, ACTIVE_NODE_PROFILE, APACHE_ACTIVE)age + sops installedsenv provides a clean workflow around .env β .env.enc./.sops.yaml (highest priority)/etc/share/sops (mountable)notifierd listens on TCP (default 9901) and emits a stable single-line event to stdout using a prefix (default __HOST_NOTIFY__)notify sends events into notifierd (inside container)docknotify can push events to the container from the hostdocker-cli + composelazydocker bundled (mount the docker socket)netx (Toolset wrapper)curl, wget, ping, ncdig/nslookup (bind-tools)iproute2, traceroute, mtrnmapgit + gitx (Toolset)jq, yqripgrep (rg), fdsqlite + sqlitex (Toolset)shellcheckzip, unzip, tree, ncdunano is default EDITOR and VISUAL/etc/nanorc is configured to load syntax rules when availablechromacat, figlet, show-banner shell hook| Command | Purpose |
|---|---|
mkcert | Local CA + trusted TLS certificates |
certify | Scan vhosts and generate server/client certs |
mkhost | Generate vhost configs (Nginx/Apache) + optional Node compose |
delhost | Remove vhost configs for a domain (Nginx/Apache/Node yaml) |
senv | SOPS/Age workflow for .env + .env.enc |
lazydocker | Docker TUI (requires docker socket) |
notify | Send notification to notifierd |
notifierd | TCP β stdout bridge (for host watchers) |
gitx | Git helper CLI |
chromacat | Colorized output |
sqlitex | SQLite helper CLI |
netx | Networking helper wrapper |
This repo is designed so you can keep all generated + persistent artifacts in a single configuration/ folder, and mount them into the container.
Rule of thumb:
- Mount RW if the container should generate/update files there (
certify,mkhost,senv init/keygen).- Mount RO if you want βconsume onlyβ behavior (good for shared secrets repo).
.
ββ configuration/
β ββ apache/ # Generated/managed Apache vhosts (*.conf)
β ββ nginx/ # Generated/managed Nginx vhosts (*.conf)
β ββ ssl/ # Generated certificates (.pem, .p12, keys)
β ββ rootCA/ # mkcert CA store (persist across rebuilds)
β ββ sops/ # Global SOPS Model B (persisted)
β ββ age.keys # Global Age key (fallback)
β ββ .sops.yaml # Global fallback config (created by senv init if writable)
β ββ keys/ # Per-project keys
β β ββ projectA.age.keys
β β ββ projectB.age.keys
β ββ config/ # Optional per-project configs
β ββ projectA.sops.yaml
β ββ projectB.sops.yaml
β
ββ secrets-repo/ # Optional shared encrypted env store (usually RO mount)
β ββ projectA/
β β ββ .env.enc
β ββ projectB/
β ββ prod/.env.enc
β
ββ docker-compose.yml
| Host path | Container path | Used by |
|---|---|---|
./configuration/apache | /etc/share/vhosts/apache | mkhost, certify |
./configuration/nginx | /etc/share/vhosts/nginx | mkhost, certify |
./configuration/ssl | /etc/mkcert | certify, mkcert |
./configuration/rootCA | /etc/share/rootCA | mkcert (CA store) |
./configuration/sops | /etc/share/sops | senv init, senv keygen, senv enc/dec/edit |
./secrets-repo | /etc/share/vhosts/sops | senv dec --in=... (alias input source) |
/var/run/docker.sock | /var/run/docker.sock | docker, lazydocker |
services:
tools:
image: infocyph/tools:latest
container_name: docker-tools
volumes:
- ./configuration/apache:/etc/share/vhosts/apache
- ./configuration/nginx:/etc/share/vhosts/nginx
- ./configuration/ssl:/etc/mkcert
- ./configuration/rootCA:/etc/share/rootCA
- ./configuration/sops:/etc/share/sops
- ./secrets-repo:/etc/share/vhosts/sops:ro
- /var/run/docker.sock:/var/run/docker.sock
environment:
- TZ=Asia/Dhaka
# - NOTIFY_TCP_PORT=9901
# - NOTIFY_PREFIX=__HOST_NOTIFY__
# - NOTIFY_TOKEN=
Use as:
docker run --rm ... infocyph/tools certifynotifierddocker run --rm -it \
-v "$(pwd)/configuration/apache:/etc/share/vhosts/apache" \
-v "$(pwd)/configuration/nginx:/etc/share/vhosts/nginx" \
-v "$(pwd)/configuration/ssl:/etc/mkcert" \
-v "$(pwd)/configuration/rootCA:/etc/share/rootCA" \
-v "$(pwd)/configuration/sops:/etc/share/sops" \
-v /var/run/docker.sock:/var/run/docker.sock \
infocyph/tools:latest
On container startup, the entrypoint runs certify (best-effort). It:
*.conf under /etc/share/vhosts/**.conf)*.domain)localhost, 127.0.0.1, ::1mkcert| File name | Domains generated |
|---|---|
test.local.conf | test.local, *.test.local |
example.com.conf | example.com, *.example.com |
internal.dev.site.conf | internal.dev.site, *.internal.dev.site |
All certs are written to /etc/mkcert.
| Certificate Type | Files Generated |
|---|---|
| Apache (Server) | apache-server.pem, apache-server-key.pem |
| Apache (Client) | apache-client.pem, apache-client-key.pem |
| Nginx (Server) | nginx-server.pem, nginx-server-key.pem |
| Nginx (Proxy) | nginx-proxy.pem, nginx-proxy-key.pem |
| Nginx (Client) | nginx-client.pem, nginx-client-key.pem, nginx-client.p12 |
mkhost is your βdomain setup wizardβ. It generates:
/etc/share/vhosts/nginx/<domain>.conf/etc/share/vhosts/apache/<domain>.conf/etc/share/vhosts/node/<token>.yamlRun it:
docker exec -it docker-tools mkhost
It runs a guided 9-step flow (slightly different for PHP vs Node):
Domain name (validated)
App type: PHP or Node
Server type (PHP only): Nginx or Apache
HTTP / HTTPS mode (keep HTTP, redirect, or HTTPS)
Document root (/app/<path>)
Client body size
Runtime version selection:
If HTTPS: optional client certificate verification (mutual TLS)
If you enable HTTPS, mkhost triggers certify automatically so the required certs exist.
mkhost stores the βactive selectionsβ into env (used by your server wrapper to enable compose profiles).
You can query/reset these values:
mkhost --RESET
mkhost --ACTIVE_PHP_PROFILE
mkhost --ACTIVE_NODE_PROFILE
mkhost --APACHE_ACTIVE
--RESET clears all active selections.--ACTIVE_PHP_PROFILE prints the chosen PHP profile (if PHP was selected).--ACTIVE_NODE_PROFILE prints the chosen Node profile (if Node was selected).--APACHE_ACTIVE prints apache when Apache mode was selected.delhost deletes the generated files for a domain:
/etc/share/vhosts/nginx/<domain>.conf/etc/share/vhosts/apache/<domain>.conf/etc/share/vhosts/node/<token>.yaml (token is a safe slug of the domain)Run it:
docker exec -it docker-tools delhost example.com
Interactive mode (no args):
docker exec -it docker-tools delhost
Behavior:
y/N)2 (useful for scripts)Initialize (creates missing defaults only when writable/mounted):
senv init
Initialize repo-local config in current directory:
senv init --local
Local-only init (does not touch /etc/share/sops):
senv init --local-only
Status / info:
senv info
Encrypt / decrypt (defaults):
senv enc # .env -> .env.enc
senv dec # .env.enc -> .env
senv edit # edit .env.enc using sops editor mode
Explicit input/output:
senv enc --in=./.env --out=./.env.enc
senv dec --in=./.env.enc --out=./.env
Use βshared encrypted env repoβ as input source:
# reads from /etc/share/vhosts/sops/demo.env.enc
# writes to ./demo.env (unless --out is set)
senv dec --in=demo.env.enc
# nested path inside the shared repo
senv dec --in=projectA/prod/.env.enc --out=./.env
Push/Pull sugar (shared encrypted repo):
# pull /etc/share/vhosts/sops/<project>/.env.enc -> ./.env
senv pull --project projectA
# push ./.env -> /etc/share/vhosts/sops/<project>/.env.enc
senv push --project projectA
notifierdnotifierd listens on TCP (default 9901) and emits a single-line event to stdout with a fixed prefix (default __HOST_NOTIFY__).
notify (inside the tools container)notify "Build done" "All services are healthy β
"
docknotifyA host-side companion that sends notifications to the tools notifierd service using a stable one-line TCP protocol.
Protocol (tab-separated): token timeout urgency source title body
sudo curl -fsSL \
"https://raw.githubusercontent.com/infocyph/Scriptomatic/refs/heads/main/bash/docknotify.sh" \
-o /usr/local/bin/docknotify \
&& sudo chmod +x /usr/local/bin/docknotify
docknotify "Build done" "All services are healthy β
"
docker logs -f docker-tools 2>/dev/null | awk -v p="__HOST_NOTIFY__" '
index($0, p) == 1 {
line = $0
sub("^" p "[ \t]*", "", line)
n = split(line, a, "\t")
if (n >= 6) {
urgency = a[3]
source = a[4]
title = a[5]
body = a[6]
for (i = 7; i <= n; i++) body = body "\t" a[i]
printf("[%-8s][%s] %s β %s\n", urgency, source, title, body)
} else {
print line
}
fflush()
}
'
| Variable | Default | Description |
|---|---|---|
TZ | (empty) | Timezone |
CAROOT | /etc/share/rootCA | mkcert CA root directory |
RUNTIME_VERSIONS_DB | /etc/share/runtime-versions.json | runtime versions DB used by mkhost |
EDITOR / VISUAL | nano | default editor |
NOTIFY_TCP_PORT | 9901 | notifier TCP port |
NOTIFY_FIFO | /run/notify.fifo | internal FIFO path |
NOTIFY_PREFIX | __HOST_NOTIFY__ | stdout prefix |
NOTIFY_TOKEN | (empty) | optional token auth |
SOPS_BASE_DIR | /etc/share/sops | global SOPS base directory |
SOPS_KEYS_DIR | /etc/share/sops/keys | per-project keys directory |
SOPS_CFG_DIR | /etc/share/sops/config | per-project config directory |
SOPS_REPO_DIR | /etc/share/vhosts/sops | shared encrypted env repo mount |
docker exec -it docker-tools lazydocker
Make sure /var/run/docker.sock is mounted.
Licensed under the MIT Licenseβ Β© infocyph
Content type
Image
Digest
sha256:eea1617f8β¦
Size
219.1 MB
Last updated
about 20 hours ago
docker pull infocyph/tools