
infocyph/toolsA 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 |
yamlservices: 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 certifynotifierdbashdocker 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:
bashdocker 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:
bashmkhost --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:
bashdocker exec -it docker-tools delhost example.com
Interactive mode (no args):
bashdocker exec -it docker-tools delhost
Behavior:
y/N)2 (useful for scripts)Initialize (creates missing defaults only when writable/mounted):
bashsenv init
Initialize repo-local config in current directory:
bashsenv init --local
Local-only init (does not touch /etc/share/sops):
bashsenv init --local-only
Status / info:
bashsenv info
Encrypt / decrypt (defaults):
bashsenv enc # .env -> .env.enc senv dec # .env.enc -> .env senv edit # edit .env.enc using sops editor mode
Explicit input/output:
bashsenv enc --in=./.env --out=./.env.enc senv dec --in=./.env.enc --out=./.env
Use “shared encrypted env repo” as input source:
bash# 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):
bash# 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)bashnotify "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
bashsudo curl -fsSL \ "[***]" \ -o /usr/local/bin/docknotify \ && sudo chmod +x /usr/local/bin/docknotify
bashdocknotify "Build done" "All services are healthy ✅"
bashdocker 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 |
bashdocker exec -it docker-tools lazydocker
Make sure /var/run/docker.sock is mounted.
Licensed under the MIT License © infocyph


manifest unknown 错误
TLS 证书验证失败
DNS 解析超时
410 错误:版本过低
402 错误:流量耗尽
身份认证失败错误
429 限流错误
凭证保存错误
来自真实用户的反馈,见证轩辕镜像的优质服务