The base Docker image
The base Docker image
The open app ships as ghcr.io/cboxdk/cbox-billing, built by CI on GitHub-hosted
runners from this public repo. It is the image the private
cloud composition overlays.
No build secrets
Every Composer dependency is public on Packagist (including the engine, the Stripe
adapter, console-kit, cboxdk/license, health, and telemetry), and the base runtime
image is a public GHCR package. The committed composer.lock resolves everything to
its published releases, so a clean checkout builds with a plain composer install —
no build secret required.
The build
A multi-stage build on the cbox php-fpm-nginx base image:
- Build stage (on the build host's native arch):
composer install --no-dev --no-scripts --optimize-autoloader, then the front-end build (npm install+npm run buildvia Vite/Tailwind), thenrm -rf node_modules.vendor/andpublic/buildare arch-neutral, so the runtime image just copies them. - Runtime image: copies the built tree owned by
www-data.
--no-scripts at build time because there is no app env then; the base-image
entrypoint runs package:discover and caches config/routes/events at container
start.
Schema is not baked in
The image does not run migrations. Schema is applied by the deployment (the
same split cbox-id / cbox-id-cloud use) — an in-image migrate would race across
replicas. Apply it at deploy time with composer deploy (or
php artisan migrate --force). See Operations.
Runtime env
Runtime configuration is supplied by the deployment (see the
environment reference and the cloud repo's
.env.production.example). The image sets APP_ENV=production and enables OPcache.
The deploy step
composer deploy runs migrate + config/route/view cache + cbox-id:publish-manifest
(see Deployment overview). Run it as your release/init step, once, not
per replica.