Skip to content

Commit 489a953

Browse files
committed
docs(plans): add future-additions.md
Captures the naturally-extensible surface that has a clear pattern but no current user demand: - More TLS DNS-01 providers (DigitalOcean, Hurricane Electric, Google Cloud DNS, Linode, OVH) — same shape as v0.13/v0.17. - More framework recipes (Rails, Next.js, Flask) — same shape as v0.7/v0.14/v0.16. - More db engines (valkey, elasticsearch, opensearch, kafka, minio, clickhouse) — same shape as v0.5/v0.15. - `--on-host` for `stack lemp`: explicitly **rejected** with rationale (LEMP is intrinsically multi-container; the v0.9.0 `db --on-host` covers the "I want a local db without Docker" need without inheriting the recipe's coupling complexity). Distinct from `known-issues.md` (deferred items with a target release) and `feature-gap-analysis.md` (Skip list — charter decisions). The future-additions file is "this slot is well- defined, the pattern is clear, nobody's asking yet." Documents the graduation bar: "someone is asking for it" — not "it would be nice to have." Naive expansion turns each `shimkit <tool>` boot into a Typer cold-start tax. Linked from docs/README.md Development section. Entry under CHANGELOG `[Unreleased]` — bundles with the next feature release rather than getting its own tag.
1 parent 02f1155 commit 489a953

3 files changed

Lines changed: 168 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- `docs/plans/future-additions.md` — captures the naturally-
12+
extensible surface (more TLS DNS-01 providers, more framework
13+
recipes, more db engines) with concrete patterns but no
14+
current user demand. Documents the bar to graduate an item
15+
("someone is asking for it" — not "it would be nice to
16+
have"). Also captures the **rejected** `--on-host` for
17+
`stack lemp` with the reasoning. Linked from docs/README.md
18+
Development section.
19+
920
## [0.18.0] — 2026-05-16
1021

1122
### Changed

docs/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ Top-level utilities (not tools):
9393
- **[Known issues + pending items](plans/known-issues.md)** — checks
9494
that exist in our scope but can't be automated (and why), coverage
9595
deferrals, and aspirational follow-ups without owners.
96+
- **[Future additions](plans/future-additions.md)** — naturally-
97+
extensible surface (more TLS DNS-01 providers, more framework
98+
recipes, more db engines) with concrete patterns but no current
99+
user demand. Move items out when someone asks.
96100

97101
## Release notes
98102

docs/plans/future-additions.md

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Future additions
2+
3+
Naturally-extensible surface that could be built on top of the
4+
current shape **if and when a concrete user need surfaces**. These
5+
are not deferrals (the way `shimkit cron` and `--on-host` were
6+
deferred from v0.5.0 → v0.6/v0.9) and they're not commitments. They
7+
exist here so the next contributor / future-me has a written
8+
record of "this slot is well-defined, the design pattern is clear,
9+
nobody's asking for it yet."
10+
11+
For things actually deferred to a specific future release, see
12+
[`known-issues.md`](known-issues.md). For things deliberately
13+
chosen against, see
14+
[`.design/plans/feature-gap-analysis.md`](../../.design/plans/feature-gap-analysis.md)'s
15+
**Skip** column.
16+
17+
---
18+
19+
## TLS / ACME — more DNS-01 providers
20+
21+
Two providers shipped (v0.13.0 Cloudflare, v0.17.0 Route53). The
22+
shape for adding a third is well-understood: a provider-specific
23+
container image with the right certbot plugin, a per-provider
24+
credentials-mount path, a `Literal["dns-<provider>"]` widening,
25+
and a `tools.tls.{certbot_dns_<provider>_image,
26+
<provider>_propagation_seconds}` config pair.
27+
28+
Plausible next providers, ranked by ACME ecosystem usage:
29+
30+
| Provider | certbot image | Credentials shape |
31+
|----------|---------------|-------------------|
32+
| **DigitalOcean** | `certbot/dns-digitalocean` | `dns_digitalocean_token = <pat>` (one line, like Cloudflare) |
33+
| **Hurricane Electric** | community plugin (no official `certbot/dns-he` image) | username + password |
34+
| **Google Cloud DNS** | `certbot/dns-google` | service-account JSON file |
35+
| **Linode** | `certbot/dns-linode` | `dns_linode_key = <token>` |
36+
| **OVH** | `certbot/dns-ovh` | application key + secret + consumer key |
37+
38+
Each is ~100 LOC + ~10 tests in the established pattern. Pick one
39+
when the first user asks.
40+
41+
---
42+
43+
## Framework recipes — more siblings
44+
45+
Three shipped (v0.7 Laravel, v0.14 Symfony, v0.16 Django). The
46+
pattern is well-understood:
47+
48+
1. `perms` — fix permissions on the framework's writable tree.
49+
2. `env` — scaffold the framework's env-file shape with a
50+
generated app secret + sensible `DATABASE_URL`.
51+
3. One framework-specific shortcut (`migrate` / `cache-clear` /
52+
`cron-install` / etc).
53+
4. Generic console passthrough — host by default, `--in-container`
54+
for stack lemp.
55+
56+
Plausible next recipes:
57+
58+
| Framework | Console | Secret | Writable tree | Likely shortcut |
59+
|-----------|---------|--------|---------------|-----------------|
60+
| **Ruby on Rails** | `rails` (or `bin/rails`) | `Rails.application.credentials.secret_key_base` | `tmp/` + `log/` + `public/uploads/` | `db:migrate` |
61+
| **Next.js** | `next` | `.env.local` `NEXTAUTH_SECRET` | `.next/` + `node_modules/` | `next build` |
62+
| **Express / Node** | varies || varies | varies — probably too project-shaped, skip |
63+
| **FastAPI** |||| dotfile / Dockerfile territory, skip |
64+
| **Flask** | `flask` | env-var | `instance/` | `db.create_all` (via `flask shell`) |
65+
66+
Each is ~200 LOC + ~25 tests in the Laravel/Symfony/Django mould.
67+
68+
---
69+
70+
## DB engines — more registry entries
71+
72+
Six shipped (mysql / mariadb / postgres / mongo / redis /
73+
phpmyadmin). The pattern is:
74+
75+
1. New file under `tools/db/engines/<name>.py` with an `Engine`
76+
subclass.
77+
2. Add to the `REGISTRY` dict in `engines/__init__.py`.
78+
3. Add a `DbEngineEntry` line in `defaults.json` +
79+
`schema.py::engines` default.
80+
4. Optionally override `up_command()` (Redis pattern) for argv-
81+
passed config.
82+
5. Decide `supports_dump` / `supports_on_host`.
83+
84+
Plausible next engines:
85+
86+
| Engine | Image | Port | Notes |
87+
|--------|-------|-----:|-------|
88+
| **valkey** | `valkey/valkey:7-alpine` | `:16380` | Redis fork; same shape as Redis (`up_command` overrides). One-line `s/redis/valkey/g` plus the image swap. |
89+
| **elasticsearch** | `elasticsearch:8` | `:19200` | Single-node config via `discovery.type=single-node` env var. Heap settings (`ES_JAVA_OPTS`). `supports_dump=False` (snapshots are repo-based). |
90+
| **opensearch** | `opensearchproject/opensearch:2` | `:19200` | Apache 2.0 ES fork. Same shape; `OPENSEARCH_INITIAL_ADMIN_PASSWORD` env var. |
91+
| **kafka** | `apache/kafka:3.7` or `confluentinc/cp-kafka` | `:19092` | Heavier — needs Zookeeper OR KRaft mode. Probably needs a multi-container stack recipe (`shimkit stack kafka`) rather than a single-engine entry. |
92+
| **minio** | `minio/minio:latest` | `:19000` + `:19001` (console) | S3-compatible. Two ports. Needs `command` override for `server /data --console-address :9001`. |
93+
| **clickhouse** | `clickhouse/clickhouse-server` | `:18123` (HTTP) + `:19000` (native) | Two ports. Default user `default` with no password — would need a config injection for AUTH. |
94+
95+
Each is ~150 LOC + ~15 tests in the engine-driver pattern.
96+
97+
---
98+
99+
## `--on-host` for `stack lemp` — out of charter
100+
101+
Initially scoped in the v0.5.0 plan as a deferred `v0.7+`
102+
candidate. **Won't be built.**
103+
104+
The LEMP recipe is intrinsically multi-container: db + php-fpm +
105+
nginx on a per-project user-defined bridge network. The Docker-
106+
first design IS the value here — replicating the same shape on
107+
the host means coordinating three host packages (mysql + php-fpm
108+
+ nginx), their config files, a shared user/group, and the
109+
inter-process communication paths that the bridge network gives
110+
for free in the container path.
111+
112+
Users who want host-installed components can:
113+
114+
1. **Mix and match.** `shimkit db postgres up --on-host` plus
115+
`shimkit stack lemp up` will work — the stack's php-fpm
116+
container reaches the host db via `host.docker.internal` (or
117+
`host-gateway` on Linux).
118+
2. **Skip the recipe entirely.** Brew/apt-install nginx +
119+
php-fpm + mysql themselves and run them via systemd /
120+
`brew services`. The original `ubuntu/` scripts did exactly
121+
this and had **five Critical security flags** (apparmor
122+
disable, mysql 0.0.0.0 bind, etc.) — shimkit's containerised
123+
LEMP is the safer path.
124+
125+
The v0.9.0 `--on-host` for `shimkit db` covers the "I want a
126+
local db without Docker" need without inheriting the LEMP
127+
recipe's coupling complexity. That's the supported escape hatch.
128+
129+
If a future user has a specific need for host-LEMP that isn't
130+
covered by either of the two paths above, the right move is to
131+
document the path explicitly here as a deferral rather than
132+
silently building an opt-in mode that re-introduces audit-flagged
133+
patterns.
134+
135+
---
136+
137+
## How to graduate an item
138+
139+
When a concrete user shows up wanting one of these:
140+
141+
1. Move the item to a `v0.X.0-<name>.md` plan doc with the
142+
detailed surface, LOC estimate, test plan, and any open
143+
design questions.
144+
2. Cross-link from `known-issues.md` (so it's tracked alongside
145+
the other in-flight deferrals).
146+
3. Build it on the next available release cycle.
147+
4. When shipped, delete the entry here and add the cross-link
148+
in the relevant release notes.
149+
150+
The bar is **"someone is asking for it"** — not **"it would be
151+
nice to have"**. shimkit's existing surface is broad enough that
152+
adding more sub-apps purely on aesthetic grounds will slowly
153+
turn each `shimkit <tool>` boot into a Typer cold-start tax.

0 commit comments

Comments
 (0)