feat: add InvenTree Cloudron package (Business-Apps) [#658]

Official-image wrapper of inventree/inventree 1.5.2 (digest-pinned).
allauth OIDC provider JSON built from the platform env; invoke update
on boot; RQ worker behind the web-port gate; admin seeded with a
generated password. grind-stack: lowercase image names. 19th package.
Verified: health 200, SSO route 302s to issuer, migrations clean.

Detail: https://projects.knownelement.com/issues/658#note-5086
This commit is contained in:
2026-09-06 19:12:02 -05:00
parent b9bc032d2b
commit 69d0d3e896
11 changed files with 285 additions and 9 deletions
+51
View File
@@ -1419,6 +1419,57 @@ no logo file ships).
---
### 19. InvenTree (Business-Apps) ✅
**Date**: 2026-09-06
**Application**: InvenTree — open-source inventory management (parts,
stock, BOMs, suppliers, purchase/build orders, plugins, REST API).
Upstream: https://github.com/inventree/InvenTree (MIT), v1.5.2.
**Ticket**: [#658](https://projects.knownelement.com/issues/658)
**Pattern**: official-image wrapper of `inventree/inventree:1.5.2`
(amd64 digest pinned). Upstream compose splits server (gunicorn :8000)
and worker (`invoke worker`); Cloudron is one container — worker
backgrounded behind the web-port gate (NetBox pattern, third use).
**Auth gate verdict**: ✅ OIDC preferred. django-allauth in core;
`INVENTREE_SOCIAL_PROVIDERS` (settings.py:1002, JSON) carries the
openid_connect provider; `SOCIALACCOUNT_OPENID_CONNECT_URL_PREFIX=''`
routes SSO at `/accounts/oidc/<provider_id>/`. start.sh builds the
provider JSON from `CLOUDRON_OIDC_*` with `server_url` (discovery) +
PKCE. LDAP also in core as an alternative. Local admin seeded with a
generated password persisted at `/app/data/.admin_password`.
**Key decisions**:
- Everything env-driven (INVENTREE_DB_*, INVENTREE_CACHE_* = redis
addon with cache DB 1, INVENTREE_SITE_URL, INVENTREE_ADMIN_*).
- `invoke update` driven explicitly on every boot (migrations +
collectstatic); the image's init.sh ENTRYPOINT is bypassed so
ordering is ours.
- Data dir pinned to /app/data — media/static/config.yaml/secret all
persist; the image's own SECRET_KEY_FILE convention then lives in
localstorage too.
- Health endpoint: `/api/system/health/` (upstream's unauthenticated
probe path).
- grind-stack fix: image names must be lowercase — dir basenames are
lowercased for tags/volumes (`grind-InvenTree:test` was invalid).
**Verification** (grind-stack, ephemeral pg+redis): first boot ~7.5 min
(migrations + static collection) → health 200; home 302→login;
`/accounts/oidc/cloudron/login/` 302s to the issuer (provider JSON
valid); worker gate fired; version-check JSONDecodeError in logs =
release-API fetch noise (sandboxed network), benign.
**Files Created**: Dockerfile, CloudronManifest.json (port 8000,
localstorage + postgresql + redis, 2048MB, healthCheckPath
/api/system/health/), start.sh, README.md, CHANGELOG.md,
.dockerignore, logo.png (from repo docs/docs/assets).
**Commit**: `feat: add InvenTree Cloudron package (Business-Apps) [#658]`
---
## Packaging Pattern: Download Pre-Compiled Binaries
### When to Use