InvenTree Common — Shared Application Configuration
InvenTree_Common is the shared application layer for InvenTree. It is not
deployed on its own; instead it supplies the InvenTree-specific configuration
that InvenTree_CloudRun builds on — the container
image, the baseline InvenTree environment, and the database bootstrap jobs. End
users never configure this layer directly — it has no deployment UI of its own —
but understanding what it provides explains the defaults you see in the
platform guide.
For the infrastructure that actually provisions and runs InvenTree, see the platform guide (InvenTree_CloudRun) and the foundation guides (App_CloudRun, App_Common).
1. What this layer provides
| Area | Provided by InvenTree_Common | Where it surfaces |
|---|---|---|
| Container image | Thin custom build of the official inventree/inventree image with a wrapper entrypoint; built via Cloud Build | container_image output of the platform deployment |
| Database engine | Cloud SQL for MySQL 8.0 (MYSQL_8_0), INVENTREE_DB_ENGINE = "mysql", port 3306 | §Database in the platform guide |
| Database bootstrap | A two-job chain: db-init (database, user, grants) → migrate (Django migrations) | initialization_jobs output |
| Core settings | The baseline INVENTREE_* environment: proxy/HTTPS handling, data directory, migrations off in-process | Application behaviour in the platform guide |
| Storage | One extra Cloud Storage bucket (storage) | storage_buckets output |
| Secrets | None — the only credential is the database password, generated by the foundation | database_password_secret output |
| Health checks | Passes through the variant's startup_probe / liveness_probe | §Observability in the platform guide |
The module also enables the Secret Manager API on the project.
2. Secrets
InvenTree_Common generates no application secrets: its secret_ids and
secret_values outputs are both empty. The database password is generated and
stored in Secret Manager by the foundation and injected as DB_PASSWORD.
InvenTree's own signing key is not supplied by this layer. InvenTree
generates secret_key.txt inside its data directory (/home/inventree/data) on
first start, which is why that directory must be persistent — see §6.
See App_Common for the shared secret model.
3. Database engine and bootstrap
InvenTree runs on Cloud SQL for MySQL 8.0 (MYSQL_8_0). InvenTree ships no
bundled SQL — the schema is created by Django migrations. Two initialization
jobs run in sequence (both execute_on_apply = true):
db-init(mysql:8.0-debian,max_retries = 3,timeout_seconds = 600) — finds the Cloud SQL connection (a Unix socket under/cloudsqlif mounted, otherwise TCP toDB_IP), waits for MySQL, creates or aligns the application user and database, grants privileges, verifies the user can connect (which also warms thecaching_sha2_passwordcache), then signals the Cloud SQL Auth Proxy sidecar to exit.migrate(depends_on_jobs = ["db-init"], the application image,cpu_limit = "2000m",memory_limit = "2Gi",timeout_seconds = 1800,max_retries = 1,mount_nfs = true) — mapsDB_*ontoINVENTREE_DB_*, runspython3 manage.py migrate --noinput, then counts the tables actually present and fails if there are fewer than 10. Amigratethat silently picked up the wrong settings would otherwise exit 0 with an empty schema.
A caller-supplied initialization_jobs list replaces both jobs.
Recovery note. A database left half-migrated (for example by an in-process
migration attempt) cannot be repaired by re-running migrate — it fails with
Duplicate column name. Drop and recreate the database, then run db-init and
migrate again.
4. Container image and entrypoint
scripts/Dockerfile:
ARG INVENTREE_VERSION=1.5.4
FROM inventree/inventree:${INVENTREE_VERSION}
COPY entrypoint.sh /cloud-entrypoint.sh
RUN chmod +x /cloud-entrypoint.sh
ENTRYPOINT ["/cloud-entrypoint.sh"]
CMD ["sh", "-c", "exec gunicorn -c ./gunicorn.conf.py InvenTree.wsgi -b ${INVENTREE_WEB_ADDR}:${INVENTREE_WEB_PORT} --chdir ${INVENTREE_BACKEND_DIR}/InvenTree"]
The CMD is restated deliberately: the vendor image keeps the gunicorn command
in CMD, so replacing the ENTRYPOINT without it left init.sh with no
arguments and the container exited 0 on every start.
The base tag comes from the app-specific INVENTREE_VERSION build ARG, set from
application_version. The pin that takes effect is the variant's
application_version default (1.5.4 in InvenTree_CloudRun), because the
variant passes its value down to this layer.
scripts/entrypoint.sh runs on every container start:
- Site URL. If
INVENTREE_SITE_URLis unset, it falls back toCLOUDRUN_SERVICE_URL; if both are missing it refuses to start. InvenTree'ssettings.pyexits on start without a site URL (URL validation, emptyALLOWED_HOSTS, emptyCSRF_TRUSTED_ORIGINS). - Database mapping. Requires
DB_IP,DB_NAME,DB_USER,DB_PASSWORDand exportsINVENTREE_DB_HOST(fromDB_IP— the socket-directory form ofDB_HOSTis not a TCP host),INVENTREE_DB_NAME,INVENTREE_DB_USER,INVENTREE_DB_PASSWORDandINVENTREE_DB_PORT(default 3306). - Static files. Unless
INVENTREE_COLLECTSTATICisfalse, runsinvoke int.collect-static --no-i18n(falling back tomanage.py collectstatic --noinput). A failure is a warning, not a fatal error. - Hand-off.
exec /bin/bash ./init.sh "$@"— the vendor init script then runs gunicorn (web container) orinvoke worker(theqclustersidecar).
scripts/migrate.sh performs the same DB_* mapping for the migrate job.
5. Core application settings
InvenTree_Common sets this baseline environment. Values in the caller's
environment_variables are merged on top and win on a clash.
| Variable | Value | Why |
|---|---|---|
INVENTREE_DB_ENGINE | mysql | Cloud SQL for MySQL. |
INVENTREE_DB_PORT | 3306 | MySQL port. |
INVENTREE_AUTO_UPDATE | false | The migrate job owns the schema. In-process migration runs before the port binds, its empty-database branch upstream is unreachable, and two containers would race. |
INVENTREE_USE_X_FORWARDED_PROTO | true | Otherwise every absolute link (password reset, invitations) is built as http:// behind Cloud Run. |
INVENTREE_SESSION_COOKIE_SECURE | true | Otherwise CSRF, session and language cookies are non-secure on an HTTPS-only endpoint. |
INVENTREE_DATA_DIR | /home/inventree/data | All mutable state. |
INVENTREE_BACKGROUND_WORKERS | 2 | From this layer's background_workers input (not exposed by the variant). |
Container defaults set here: container_port = 8000 (gunicorn binds
INVENTREE_WEB_ADDR:INVENTREE_WEB_PORT, not Cloud Run's $PORT),
database_type = MYSQL_8_0, enable_cloudsql_volume = false,
cloudsql_volume_mount_path = /cloudsql, image_source = "custom", plus the
resource limits and instance counts forwarded from the variant.
Inputs declared here but not used. admin_username, admin_email,
php_memory_limit and enable_gcs_storage_volume are declared (and the last
three are forwarded by the variant) but nothing in this layer reads them. No
administrator account is created and no bucket is mounted by them.
6. Storage and the data directory
InvenTree keeps all of its mutable state under INVENTREE_DATA_DIR
(/home/inventree/data): config.yaml, the generated secret_key.txt,
uploaded media, collected static files and the plugin directory. The image
declares no volume for it.
This layer adds no GCS Fuse volume for it — a real POSIX filesystem (the NFS
share) is the intended backing store. In the variant, the qcluster sidecar
mounts NFS at /home/inventree/data and the web container and jobs mount it at
nfs_mount_path, all only when enable_nfs = true. Any caller-supplied
gcs_volumes are passed through unchanged.
The storage_buckets output adds one bucket with the suffix storage
(STANDARD, force_destroy = true, public access prevention enforced). It is
not mounted into the container.
7. Health probe behaviour
This layer forwards whatever startup_probe / liveness_probe the variant
passes. In InvenTree_CloudRun both are HTTP GET /, matching the vendor
image's own health check; the startup probe allows a long window
(failure_threshold = 60, period_seconds = 15).
For the InvenTree-specific, user-facing configuration (variables by group, outputs, and how to explore each service from the Console and CLI), see the platform guide: InvenTree_CloudRun.
Related guides
- InvenTree on Google Cloud Run — this configuration deployed on Cloud Run.
Need RAD to do something it does not do yet? Request it on the roadmap, or vote on what is already there.