Skip to content

Commit 0a23e18

Browse files
committed
release: v0.15.0 — shimkit db redis
Sixth engine in the db registry: Redis. Container-first, port :16379, AUTH via --requirepass, AOF persistence on by default. Why Redis: standard cache + queue backend for Laravel (CACHE_DRIVER=redis), Symfony (CacheItemPool), Django (Channels) etc. With this release a developer can: shimkit db postgres up shimkit db redis up shimkit framework symfony env --yes --db postgres ./my-app and have a full SQL + cache dev stack with one apt-install-free flow. New Engine ABC method: def up_command(self, *, password: str) -> list[str] | None: ... Default returns None (use image's default CMD). Redis overrides to return `["redis-server", "--requirepass", PW, "--appendonly", "yes"]`. Available to any future engine that needs argv-passed config the image doesn't expose as env vars. `DbManager._EngineBound.up` plumbs the new method through to `docker.containers.run` via a `command=` kwarg, conditionally when up_command returns non-None. Redis specifics — what we don't do: - **`dump` is unsupported.** Redis backups are RDB snapshots (binary, server-version-tied). The right backup story is volume-level (`/data/dump.rdb` inside the managed volume), not a stream piped to stdout. Users wanting a dump: `shimkit db redis shell` then `SAVE` or `BGSAVE`. - **`--on-host` is unsupported.** Same charter as mongo + phpmyadmin: shimkit doesn't install host packages. Users wanting host Redis run `brew install redis` / `apt install redis-server` themselves. stack lemp interaction: `stack lemp` is SQL-class only. The recipe now rejects non-SQL backing DBs with a clearer error pointing the user at `shimkit db <engine> up` for cache / non-relational backends. Two pre-existing tests that used `redis` as the "unknown engine" placeholder are updated to use `elasticsearch` (still genuinely unknown). Tests: 16 new in test_tools_db_redis.py (1070 → 1086 total). Registry membership + insertion order, pure engine driver (environment_for_up empty / up_command argv shape with --requirepass + --appendonly / shell_argv uses --no-auth-warning + -a / no-password fallback / supports_dump=False / supports_on_host=False / data_dir=/data / container_port=6379 / name=redis), manager plumbing (up passes command= through docker.containers.run / dump refused / on-host refused), config defaults present. Gates: pytest 1086 passed, ruff clean, mypy strict clean. No new optional dependency extras.
1 parent db058f7 commit 0a23e18

16 files changed

Lines changed: 605 additions & 17 deletions

File tree

CHANGELOG.md

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

77
## [Unreleased]
88

9+
## [0.15.0] — 2026-05-16
10+
11+
### Added
12+
13+
- **`shimkit db redis`** — sixth engine in the `db` registry.
14+
Image `redis:7-alpine`, host port `:16379`, container port 6379.
15+
AUTH via `--requirepass` (Redis's official image doesn't read
16+
a `REDIS_PASSWORD` env var), AOF persistence on by default.
17+
- **`Engine.up_command(password)`** — new method on the engine
18+
ABC. Default returns `None` (use image's default CMD). Redis
19+
overrides to return `["redis-server", "--requirepass", PW,
20+
"--appendonly", "yes"]`. Available to any future engine that
21+
needs argv-passed config the image doesn't expose as env vars.
22+
- `Redis` engine driver in `tools/db/engines/redis.py`. Marks
23+
`supports_dump=False` (Redis backups are volume-level RDB
24+
snapshots, not logical dumps) and `supports_on_host=False`
25+
(same charter as mongo / phpmyadmin — shimkit doesn't manage
26+
host-installed Redis).
27+
28+
### Changed
29+
30+
- `stack lemp` rejects non-SQL backing DBs with a clearer error
31+
(mongo / redis / phpmyadmin can run alongside via the per-
32+
engine `shimkit db <engine> up` but don't fit the L-E-M-P role).
33+
- `DbManager._EngineBound.up` plumbs `Engine.up_command` through
34+
to `docker run` via the new optional `command=` kwarg.
35+
36+
### Tests
37+
38+
- 16 new tests in `tests/test_tools_db_redis.py` (1070 → 1086
39+
total). Registry membership + insertion order, pure engine
40+
driver shape (environment_for_up empty / up_command argv /
41+
shell_argv with --no-auth-warning / no-password fallback /
42+
supports_dump=False / supports_on_host=False / data_dir /
43+
container_port), manager plumbing (up passes command= through
44+
docker.containers.run / dump refused / on-host refused),
45+
config defaults present.
46+
- Adjusted two pre-existing tests that used `redis` as an "unknown
47+
engine" placeholder (now a valid name).
48+
49+
### Notes
50+
51+
`shimkit db redis up` gives Laravel / Symfony / Django users a
52+
local Redis cache and queue backend without touching the host
53+
package manager. Pairs with the framework recipes — set
54+
`REDIS_URL=redis://default:shimkit-dev@127.0.0.1:16379/0` in
55+
your `.env` / `.env.local` / `settings.py`.
56+
57+
Gates: pytest 1086 passed, ruff clean, mypy strict clean. No new
58+
optional dependency extras.
59+
960
## [0.14.0] — 2026-05-16
1061

1162
### Added

docs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ Top-level utilities (not tools):
9494

9595
Per-version, user-facing summaries (newest first):
9696

97+
- **[`v0.15.0`](release-notes/v0.15.0.md)**`shimkit db redis`
98+
sixth engine. `Engine.up_command()` for argv-passed config.
9799
- **[`v0.14.0`](release-notes/v0.14.0.md)** — `shimkit framework
98100
symfony` sibling recipe under the `framework` parent.
99101
- **[`v0.13.0`](release-notes/v0.13.0.md)** — `shimkit tls --method

docs/release-notes/v0.15.0.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# shimkit 0.15.0
2+
3+
Sixth engine in the `shimkit db` registry: Redis. For the full
4+
machine-readable changelog, see [`CHANGELOG.md`](../../CHANGELOG.md).
5+
6+
---
7+
8+
## TL;DR
9+
10+
```
11+
shimkit db redis up # redis:7-alpine on 127.0.0.1:16379
12+
shimkit db redis shell # redis-cli with AUTH
13+
shimkit db redis down # stop + remove the container
14+
shimkit db redis status # state + port
15+
shimkit db redis reset # SEVERE — drop the container AND its volume
16+
```
17+
18+
`dump` and `--on-host` are intentionally **not** supported on
19+
Redis (see below).
20+
21+
---
22+
23+
## Why Redis
24+
25+
Local Redis is the standard cache + queue backend for Laravel
26+
(`CACHE_DRIVER=redis` / queue worker), Symfony (`CacheItemPool` via
27+
Redis), Django (Channels), and just about everything else. Adding
28+
it to the `db` registry means one command brings up an authed
29+
Redis container alongside your SQL DB:
30+
31+
```bash
32+
shimkit db postgres up
33+
shimkit db redis up
34+
shimkit framework symfony env --yes --db postgres ./my-app
35+
echo "REDIS_URL=redis://default:shimkit-dev@127.0.0.1:16379/0" >> ./my-app/.env.local
36+
```
37+
38+
No `apt install redis-server`, no systemd config, no AUTH file
39+
to maintain — same lifecycle as the other engines.
40+
41+
---
42+
43+
## What's new
44+
45+
### `Engine.up_command(password)` (new ABC method)
46+
47+
Default returns `None` (use image's default `CMD`). Redis overrides
48+
to return:
49+
50+
```python
51+
["redis-server", "--requirepass", PASSWORD, "--appendonly", "yes"]
52+
```
53+
54+
The official `redis:7-alpine` image doesn't read a `REDIS_PASSWORD`
55+
env var (that's a Bitnami convention). The clean way to configure
56+
AUTH is to pass `--requirepass` as the container command. The new
57+
ABC method is available to any future engine that needs argv-passed
58+
config.
59+
60+
### Redis specifics
61+
62+
- **Port**: `127.0.0.1:16379` (shimkit's `:1` prefix on the
63+
upstream port — keeps a system-installed Redis from colliding).
64+
- **Volume**: `~/.shimkit/data/db/redis-dev/` mounts at `/data`
65+
inside. AOF + RDB live here.
66+
- **Persistence**: AOF enabled by default (`--appendonly yes`).
67+
- **AUTH**: mandatory. Default password `shimkit-dev`; override
68+
via `--password` or `tools.db.default_password`.
69+
- **Image**: `redis:7-alpine` (~30 MB).
70+
71+
### Why no `dump`
72+
73+
Redis dumps are RDB snapshots — binary, version-tied to the
74+
server. The right backup story is volume-level (just `cp` the
75+
`/data/dump.rdb` file inside the managed volume), not a stream
76+
piped to stdout. shimkit returns `supports_dump=False` rather
77+
than emitting half-broken bytes.
78+
79+
To trigger an RDB write:
80+
81+
```bash
82+
shimkit db redis shell
83+
# 127.0.0.1:16379> SAVE (synchronous, blocks)
84+
# 127.0.0.1:16379> BGSAVE (background)
85+
```
86+
87+
The file lands at `~/.shimkit/data/db/redis-dev/dump.rdb` on the
88+
host.
89+
90+
### Why no `--on-host`
91+
92+
Same charter as mongo and phpmyadmin: shimkit doesn't install host
93+
packages. Users wanting host Redis run `brew install redis` /
94+
`apt install redis-server` themselves and manage it via systemd
95+
/ brew services directly. The `--on-host` mode for mysql /
96+
mariadb / postgres (v0.9.0) exists because those are the engines
97+
where users frequently switch between host + container; Redis
98+
isn't.
99+
100+
---
101+
102+
## `stack lemp` interaction
103+
104+
The LEMP recipe is SQL-only. Trying to use `--db redis` now
105+
returns a clear error:
106+
107+
```
108+
✗ `stack lemp` only supports SQL backing DBs (mariadb, mysql,
109+
postgres); got 'redis'. Run `shimkit db redis up` separately
110+
to add a cache / non-relational backend.
111+
```
112+
113+
Run them side-by-side:
114+
115+
```bash
116+
shimkit stack lemp up --db postgres --project myapp
117+
shimkit db redis up
118+
```
119+
120+
Both bind 127.0.0.1; the framework container reaches Redis via
121+
`host.docker.internal:16379` on Docker Desktop or
122+
`172.17.0.1:16379` on Linux (`host-gateway`).
123+
124+
---
125+
126+
## Stats
127+
128+
- Tests: 1070 → 1086 (+16)
129+
- Gates: pytest, ruff, mypy strict — all green
130+
- New optional extras: 0
131+
132+
---
133+
134+
## Upgrading
135+
136+
```bash
137+
uv tool upgrade shimkit
138+
pipx upgrade shimkit
139+
```
140+
141+
Existing db engines see no behavioural change. To start using
142+
Redis, `shimkit db redis up`.

docs/tools/db.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# shimkit db
22

3-
Container-first database orchestration. Five engines today
4-
(`mysql`, `mariadb`, `postgres`, `mongo`, `phpmyadmin`); every one
3+
Container-first database orchestration. Six engines today
4+
(`mysql`, `mariadb`, `postgres`, `mongo`, `redis`, `phpmyadmin`); every one
55
runs as a Docker container, bound to `127.0.0.1` by default,
66
backed by a host volume at `~/.shimkit/data/db/<engine>-<id>/`.
77

@@ -73,12 +73,31 @@ Limits:
7373
| mariadb | `mariadb:10.11` | `:13307` | `3306` | `root` |
7474
| postgres | `postgres:16` | `:15432` | `5432` | `postgres` |
7575
| mongo | `mongo:7` | `:17017` | `27017` | `admin` |
76+
| redis | `redis:7-alpine` | `:16379` | `6379` | n/a (`--requirepass`) |
7677
| phpmyadmin | `phpmyadmin:5` | `:18080` | `80` | n/a (web UI) |
7778

7879
Shimkit-prefixed host ports keep a system-installed engine
7980
(if any) from colliding. Override per-invocation with `--port` or
8081
project-wide via `tools.db.engines.<engine>.default_port`.
8182

83+
### Redis (v0.15.0)
84+
85+
Redis is the odd engine: no admin user, no SQL, no dump. The
86+
official `redis:7-alpine` image doesn't read a `REDIS_PASSWORD`
87+
env var, so shimkit configures AUTH by passing `--requirepass`
88+
as the container command. AOF persistence (`--appendonly yes`) is
89+
on by default — that's the recommended dev posture.
90+
91+
- **`dump` is unsupported** — Redis backups are volume-level
92+
(the `/data/dump.rdb` file inside the managed volume), not
93+
logical dumps. Trigger one from the shell:
94+
`shimkit db redis shell` then `SAVE` (synchronous) or `BGSAVE`
95+
(background).
96+
- **`--on-host` is unsupported** — same reason as mongo /
97+
phpmyadmin: shimkit doesn't install host packages. Users
98+
wanting host Redis run `brew install redis` /
99+
`apt install redis-server` themselves.
100+
82101
Default bind is **`127.0.0.1`** (loopback only). Override with
83102
`--bind 0.0.0.0` if you really want to expose the port on the LAN —
84103
and pair that with a sensible `--password`.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "shimkit"
7-
version = "0.14.0"
7+
version = "0.15.0"
88
description = "A toolkit of developer utilities — Java version manager, shell upgrader, and more. Python tools, shimmed by bash."
99
readme = "README.md"
1010
license = { file = "LICENSE" }

src/shimkit/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
Python tools, shimmed by bash.
44
"""
55

6-
__version__ = "0.14.0"
6+
__version__ = "0.15.0"
77
__all__ = ["__version__"]

src/shimkit/config/defaults.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
"mariadb": {"image": "mariadb:10.11", "default_port": 13307},
157157
"postgres": {"image": "postgres:16", "default_port": 15432},
158158
"mongo": {"image": "mongo:7", "default_port": 17017},
159+
"redis": {"image": "redis:7-alpine","default_port": 16379},
159160
"phpmyadmin": {"image": "phpmyadmin:5", "default_port": 18080}
160161
},
161162
"host_services": {

src/shimkit/config/schema.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ class DbConfig(_StrictModel):
304304
"mariadb": DbEngineEntry(image="mariadb:10.11", default_port=13307),
305305
"postgres": DbEngineEntry(image="postgres:16", default_port=15432),
306306
"mongo": DbEngineEntry(image="mongo:7", default_port=17017),
307+
"redis": DbEngineEntry(image="redis:7-alpine", default_port=16379),
307308
"phpmyadmin": DbEngineEntry(image="phpmyadmin:5", default_port=18080),
308309
}
309310
)

src/shimkit/tools/db/engines/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
from .mysql import MySQL
1717
from .phpmyadmin import PhpMyAdmin
1818
from .postgres import Postgres
19+
from .redis import Redis
1920

2021
# Insertion order is preserved so `db ls` / help output is stable.
2122
REGISTRY: dict[str, Engine] = {
2223
"mysql": MySQL(),
2324
"mariadb": MariaDB(),
2425
"postgres": Postgres(),
2526
"mongo": Mongo(),
27+
"redis": Redis(),
2628
"phpmyadmin": PhpMyAdmin(),
2729
}
2830

@@ -42,6 +44,7 @@ def get(name: str) -> Engine | None:
4244
"MySQL",
4345
"PhpMyAdmin",
4446
"Postgres",
47+
"Redis",
4548
"UnsupportedEngineOperationError",
4649
"get",
4750
]

src/shimkit/tools/db/engines/base.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ def requires_link(self) -> bool:
104104
"""
105105
return False
106106

107+
def up_command(self, *, password: str) -> list[str] | None:
108+
"""Override the image's default ``CMD``.
109+
110+
Default is ``None`` — use the image's built-in entrypoint /
111+
cmd. Engines that need argv-passed config (e.g. Redis's
112+
``--requirepass``, which isn't exposed as an env var by the
113+
official image) override and return the full argv.
114+
"""
115+
return None
116+
107117
# ---- --on-host mode -------------------------------------------------
108118

109119
def supports_on_host(self) -> bool:

0 commit comments

Comments
 (0)