# v2 git bundle
3c4ae47b6348f2ff75876368e07dd09bdf5a9e95 refs/heads/bundle
3c4ae47b6348f2ff75876368e07dd09bdf5a9e95 HEAD

PACK      
™(x‰výtree 7191c08eb67d41c73c74a04e953db8b77bba0ec3
author Zach Kelling <z@zeekay.io> 1783193549 -0700
committer Zach Kelling <z@zeekay.io> 1783193549 -0700

feat: canonical Node 24 base image with sqlite3 bundled

Node 24.18.0 (LTS Krypton) on alpine. sqlite3 bundled two ways, both
proven at build time: require('node:sqlite') builtin works, and native
better-sqlite3/sqlite3 compile against build-base+python3+sqlite-dev via
node-gyp. One base, one way: services do FROM ghcr.io/hanzoai/nodejs:v24.18.0.

Self-contained CI on hanzo-build-linux-amd64, amd64-only, semver-only
(vX.Y.Z + :v24), never sha/latest.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
žùÖ«®xœ340031QÐKÉOÎN-ÊLÏË/Je8bþNõæV¾²7·ó´'…5Úßª11 ½ôÌ’ŒÒ$†ùö«˜}ÃÌâ›‚?{iáÝ×<k¡F•@Í	ÕW’ðWÔ�=–{êÛš9§µf\…ªrÛ—–™“ÊPôUM¤ùrÒ´Í‹—îªÜîl{æÏ¨*_½Ü†ûiŠ…¦ë}¥Ë=~­8äñæÍ3¨Š WG_W�¢ôïDšO¿³}“,Oz¢3÷ƒ‚3Î ˆeZ²x íÿ.git
.github
*.md
6k¤x$ Ûÿ40000 workflows Œ#
Æ+u/Ël0i	|­ºtz”Ói²¥x% Úÿ100644 build.yml a…›ôxõ«dL,gáo¦ÜwMîn¶’xœ�VáRÛ8þŸ§Ø	™IØ�4ÃÝ™SJShKH'…þéõ¨b+±@¶\I6ä€™{ˆ{Â>IW’“s(™ë5kw?}»Úýä”$4€—"¼¦²¶G$)	‡3Q˜E�%dF¡eº=Øõ…3MŸµa*$Îá„¤	¡¨,XH•�`ï)Ÿz¡H5a)�`’3�HAÇ´QÆ#J£ùp|™Z±±yÖÝã,Ío=’D{½¶ÃL
*…Ï ð¹Øü3¦A“dù„3S³8”>‹DX'EjW*ø½0C Kgˆ˜�+LÃÄE·çÃÙàÃ`'š*TL •á¦Î†�g _ÎÂ¹%f)ºÕ¯ÿ/GoßCL¤ˆLözI‘qª´NO‡~mCw§»çíô¼î/ˆ Ò p#äõ”‹›Ëˆ©Œè06‹Y®ìKÀÇf±ÙüTCJ	SŠ‰T«)4M5Ú%%‘	#á5ž.ÜH<¯Ú•˜XÇÈ¶Ü°e/vüÝH‘cÊ0™ƒÂ ž¢Î‡ƒmÌA'Ê•Í-Åž±5´Ç1ICÍç¾”yª°
¬9Dë„ç�)G Àƒ\’$Ô&•NÓð©</zµ¥KjÛôH$r´e(M ,
V�B ÷ËWÜñh. c�Æ+¶ñàU¿Þ¸;~}~rñâß.MÊõŠKh† Þ@[XZ1 w¼ß>m¶[¦_ºìïÃÓ¿�²Iñ0ÁtÚî¯þÎ
Ú§h´f’fà‰4Mëv›­?üÕg³œÛ)ãî!Æcoÿ…9&Œeñ¦Ý¶!TÙ…*®á·†ô²!¢’¦R$ðj<b=«å¾™*´h,æRG2ÿ¦ògQònWËë¼q¤ú.Âü0¾<“ÑÅù»‹óï#ìÜöv×úE¼sú€c¬SC"(ak�zÔ�N*Ï\oc[Û¾}^<{Ü­§bÆPìŸ�—dV€¸q© ,œn˜Žƒ
IgLi9_ò®ØPºwwFã|â#$ŠÚÃCÅ/#J¡¼DÎOÑP¢ùeÉÎGogÆÿQ/¬f“4²}-;É'ÇO§ä&Þx/óÚ[›—Õ¬[€_%ŠÒ‹7K‚˜•íªv„´ÌieÑIãýÊ@­;d“¿‘ ßù¨5¨*Ê7÷ÊJÅþ/€»IV B‚ræ™‰AÂóŒög1ÙV¡À%¦ç0¿‹Ñâ?"¶|ôrûøÌ>à˜Nç‹[˜»p—cäîóŸSË×Ãã~ýgªZF×(H¿ê„|Âˆ¬ÀódR:€Ù¼âGQ¯%ý’ãÍÔrêŠÑlïcÇ)Á©�“·b.H¤Ì×Is+“¿`,us»¢Z}8¨c´x ëÿnode_modules/
*.log
O±Ü¹’x)	Öö# hanzoai/nodejs â€” the ONE canonical Node base image for every Hanzo Node service.
#
# Node 24 (LTS "Krypton") + sqlite3 bundled two ways, BOTH proven at build time:
#   1. node:sqlite â€” the built-in DatabaseSync (stable since Node 22.5; present in
#      24). `require('node:sqlite')` works out of the box, zero dependencies.
#   2. native npm sqlite â€” better-sqlite3 / sqlite3 compile against the baked-in
#      toolchain (build-base + python3 + sqlite-dev) through node-gyp.
#
# One base, one way. Services do:  FROM ghcr.io/hanzoai/nodejs:v24.18.0
# Bump the pinned node:<ver>-alpine below to move the whole fleet's runtime;
# the git tag (vX.Y.Z) must match the Node version so consumers can reason about it.
FROM node:24.18.0-alpine

# Native addon build toolchain (node-gyp needs python3 + make + g++, all via
# build-base), the system sqlite CLI + headers, and the glibc shim so prebuilt
# (glibc) native addons load on musl. corepack ships pnpm/yarn shims.
RUN apk add --no-cache \
      build-base \
      python3 \
      sqlite \
      sqlite-dev \
      libc6-compat \
 && corepack enable

# Build-time proof gate â€” the image FAILS TO BUILD if either sqlite path breaks.
#   (1) node:sqlite builtin round-trips an in-memory DB.
#   (2) better-sqlite3 compiles from source against the toolchain and round-trips.
# The verify scratch dir is removed so it adds no weight to the published layer.
RUN node -e "const {DatabaseSync}=require('node:sqlite');const d=new DatabaseSync(':memory:');d.exec('create table t(x int)');d.prepare('insert into t values (?)').run(7);if(d.prepare('select x from t').get().x!==7)throw new Error('node:sqlite roundtrip failed');console.log('node:sqlite OK on '+process.version);" \
 && mkdir -p /tmp/verify && cd /tmp/verify && npm init -y >/dev/null 2>&1 \
 && npm install --no-audit --no-fund better-sqlite3 >/dev/null 2>&1 \
 && node -e "const D=require('better-sqlite3');const db=new D(':memory:');db.exec('create table t(x int)');db.prepare('insert into t values (?)').run(42);if(db.prepare('select x from t').get().x!==42)throw new Error('better-sqlite3 roundtrip failed');console.log('better-sqlite3 '+require('better-sqlite3/package.json').version+' OK');" \
 && cd / && rm -rf /tmp/verify /root/.npm

# Match the upstream node image default so this is a transparent drop-in.
CMD ["node"]
Þ=°_xðú# LLM.md â€” hanzoai/nodejs

Canonical Node base image for the whole Hanzo Node fleet. One base, one way.

## What this is

`FROM node:24.18.0-alpine` + the sqlite3 toolchain, published as
`ghcr.io/hanzoai/nodejs:v24.18.0` (+ `:v24`). Every Hanzo Node service does
`FROM ghcr.io/hanzoai/nodejs:v24.18.0` so Node 24 and sqlite3 are uniform.

## sqlite3, two ways (both build-gated)

- `require('node:sqlite')` (builtin `DatabaseSync`, stable Node â‰¥22.5) â€” no deps.
- `better-sqlite3` / `sqlite3` compile via node-gyp against `build-base` +
  `python3` + `sqlite-dev`. The Dockerfile compiles better-sqlite3 at build time
  and round-trips it; the image fails to build if that breaks.

## Why alpine

Majority of Hanzo Node services already use `node:*-alpine`. better-sqlite3
compiles cleanly on musl with `build-base`; `node:sqlite` is builtin regardless.
`libc6-compat` lets prebuilt glibc addons load. Debian-slim consumers
(paas, platform, base-studio, market, embeddings, store-api, insights, gallery)
need an `apt-get`â†’`apk` port before switching to this base â€” tracked as the sweep tail.

## Release / bump

1. Edit the `FROM node:<X.Y.Z>-alpine` pin in `Dockerfile` to move the runtime.
2. Tag `vX.Y.Z` (must equal the Node version). CI publishes `:vX.Y.Z` + `:vX`.
3. Consumers bump their `FROM ghcr.io/hanzoai/nodejs:vX.Y.Z` pin on their own release.

CI: `.github/workflows/build.yml`, self-contained, routes to `hanzo-build-linux-amd64`.
amd64-only (DOKS has no arm64). Semver only, never sha/latest.
¶‘SºBx*Õû# hanzoai/nodejs

The **one** canonical Node base image for every Hanzo Node service.

- **Node 24** (LTS "Krypton", pinned `node:24.18.0-alpine`)
- **sqlite3 bundled, two ways** â€” both proven at build time:
  1. `require('node:sqlite')` â€” the built-in `DatabaseSync` (Node â‰¥ 22.5). Zero deps.
  2. Native npm sqlite (`better-sqlite3`, `sqlite3`) compiles against the baked-in
     toolchain (`build-base` + `python3` + `sqlite-dev`) via node-gyp.

## Use

One way. In any Hanzo Node service's Dockerfile:

```dockerfile
FROM ghcr.io/hanzoai/nodejs:v24.18.0
```

Pin the exact semver (`v24.18.0`). The moving major tag `v24` also exists but
consumers must pin the patch for reproducible builds.

## Verify

```sh
docker run --rm ghcr.io/hanzoai/nodejs:v24.18.0 node -e "require('node:sqlite');console.log('ok')"
```

## Release

Tag `vX.Y.Z` where `X.Y.Z` matches the pinned Node version in the `Dockerfile`.
CI (`hanzo-build-linux-amd64`, self-hosted) builds `linux/amd64` and publishes
`ghcr.io/hanzoai/nodejs:vX.Y.Z` + `:vX`. Never `:latest`, never `:sha`.
(§d¶ }¢ÞÞ>Kít²2×äÍQ5