This repository contains the official Docker image build system for Joomla Component Builder (JCB).
It is the canonical source for generating, tagging, and publishing all Joomla Component Builder Docker images across supported:
- Joomla versions
- PHP versions
- Runtime variants (Apache / FPM / FPM-ALPINE)
- Linux CPU architectures supplied by each selected official Joomla base image
- Stable and prerelease channels
All images are generated, versioned, and published automatically from authoritative upstream release data.
- The official Docker image source for Joomla Component Builder
- A fully automated build engine driven by upstream JCB releases
- A deterministic and auditable system that:
- Tracks release hashes describing what was built
- Generates Dockerfiles automatically
- Emits a complete build manifest
- Builds, tags, and publishes images consistently
- A manually curated set of Dockerfiles
- A place to hand-edit image definitions
- A CI script that hides build logic in YAML
All build logic lives in
src/bin/joomengine.sh. CI only authenticates, runs it, and commits the results.
All images are published to Docker Hub under:
https://hub.docker.com/r/octoleo/joomengine
You can pull images directly, for example:
docker pull octoleo/joomengine:latest
docker pull octoleo/joomengine:6.1.3
docker pull octoleo/joomengine:6.1.3-php8.3-apacheEvery tag is a multi-platform Linux image. Docker automatically selects the matching image for the host, so the same tags work across all architectures supplied by the selected official Joomla base image; architecture-specific JoomEngine tags are not required.
Image generation is driven entirely by the script:
./src/bin/joomengine.sh
At a high level, the build engine performs the following steps:
-
Discovers upstream JCB releases
- Fetches official update XML files per major version
- Extracts version numbers, download URLs, and SHA512 hashes
- Refuses to build if hashes are missing
-
Expands build matrices
- Joomla major versions
- Supported PHP versions (per Joomla)
- Runtime variants (
apache,fpm,fpm-alpine)
-
Generates build contexts
- Creates versioned directory trees under
images/ - Generates Dockerfiles from templates
- Injects release metadata as build arguments
- Copies and configures the Docker entrypoint
- Creates versioned directory trees under
-
Tracks build state
- Records JCB hashes, source fingerprints, and verified Joomla base digests
- Rebuilds only combinations whose effective inputs changed
- Commits hash state only after every affected image succeeds
-
Calculates tag leadership
- Determines highest stable versions per major
- Determines global highest stable version
- Handles prerelease channels (
alpha,beta,rc) correctly - Ensures no tag collisions
-
Emits a build manifest
- Outputs a machine-readable NDJSON manifest (
conf/manifest.ndjson) - Each line describes exactly one buildable image and its tags
- Outputs a machine-readable NDJSON manifest (
-
Builds and publishes images
- Pulls and pins the verified official Joomla base-image digest
- Automatically builds every Linux platform supplied by that base image
- Publishes each tag as one multi-platform image index
- Builds only changed base images
- Promotes complete multi-platform rolling and
latestaliases only after all base builds succeed - Pushes images to the registry (unless disabled)
This repository follows a strict, predictable tagging policy.
<version>-php<php>-<variant>
Example:
6.1.3-php8.3-apache
If the variant is apache, a shorthand tag is added:
<version>-php<php>
If the PHP version is the highest supported PHP for that Joomla major:
<version>-<variant>
<version>
(when apache)
If a version is the highest stable release of its major:
<minor>-php<php>-<variant>
<major>-php<php>-<variant>
<minor>-<variant>
<major>-<variant>
<minor>
<major>
(variant-dependent)
Only one image ever receives:
latest
Criteria:
- Stable release
- Highest version globally
- Apache variant
- Highest supported PHP
Prereleases are tagged without polluting stable tags.
Examples:
6.1.4-rc
6.1.4-rc1
6.1.4-rc1-php8.3-apache
Rules:
- Numbered prereleases roll forward correctly
- Unnumbered prereleases are treated as "highest in channel"
- Stable tags are never reused for prereleases
.
βββ conf/ # Declarative data & state
β βββ versions.json # Supported Joomla / PHP / variant matrix
β βββ maintainers.json # Image maintainer metadata
β βββ upstream-images.json # Verified Joomla image-index/platform state
β βββ hashes.txt # Tracks built release combinations
β βββ manifest.ndjson # (generated) build manifest (NDJSON)
β
βββ images/ # Generated Docker build contexts
β βββ jcbX.Y.Z/ # (generated) per-jcb-version
β βββ jX.Y.Z/ # (generated) per-joomla-version
β βββ phpX.Y/ # (generated) per-php-version
β βββ variant/ # (generated) per-variant
β βββ Dockerfile # (generated) dockerfile
β βββ entrypoint # (generated) entrypoint
β
βββ log/ # Logs folder (gitignored)
β βββ joomengine-tag.log # (generated) image tagging log (gitignored)
β
βββ src/ # Executable & reusable source
β βββ bin/
β β βββ check-joomla-releases.sh # Stable-release and Docker-tag detector
β β βββ joomengine.sh # The build engine (authoritative logic)
β β
β βββ docker/
β βββ Dockerfile.template # Template used to generate Dockerfiles
β βββ docker-entrypoint.sh # Runtime entrypoint copied into images
β βββ jq-template.awk # jq/awk helpers for manifest rendering (gitignored)
β βββ .gitignore
β
βββ docker/ # Developer-facing Docker usage
β βββ docker-compose.yml # Basic example
β βββ README.md # How to use these images
β
βββ .github/
β βββ workflows/ # Automation (thin by design)
β βββ joomla-release-poll.yml # Upstream release/digest polling
β βββ joomengine.yml # Changed-image publisher
β βββ quality.yml # Unit, lint, and image-smoke gates
β
βββ tests/ # Deterministic, network-free test suites
β
βββ .editorconfig
βββ .gitignore
βββ LICENSE
βββ README.md # Project overview (what / why)
Do not edit generated image files manually. They are overwritten by
./src/bin/joomengine.sh.
This repository uses GitHub Actions to run the build engine automatically.
Every six hours, the release poller:
- Reads Joomla's official stable-release feed
- Checks every configured PHP Γ variant tag on the official Joomla Docker Hub repository
- Waits successfully, without a repository change or failed workflow, while any candidate tag is unavailable
- Atomically updates
conf/versions.jsonandconf/upstream-images.jsononly when a complete matrix is ready - Dispatches the normal image publisher only when a version or tracked digest changed
Digest-only changes are deliberate rebuild triggers, so refreshed upstream base images receive the same verification and publication path as new Joomla releases.
- A JCB release dispatch
- A build-input change merged to
master - A ready Joomla version or official base-image digest change
- Manual dispatch
- Checks out the repository
- Installs required tooling
- Runs deterministic unit tests
- Registers cross-architecture emulation and creates a Buildx builder
- Authenticates with Docker
- Runs
./src/bin/joomengine.sh - Commits only the generated image contexts and build-state files
Pull requests also run ShellCheck, actionlint, JSON validation, unit tests, and native AMD64 smoke builds for Apache, FPM, and FPM-Alpine, plus an emulated ARM64 Apache smoke build.
- It does not contain build logic
- It does not define tagging rules
- It does not hide behavior in YAML
All logic remains reviewable and reproducible locally.
You can run the build engine locally:
./src/bin/joomengine.shUseful flags:
-q, --quiet Suppress all stdout output (exit code only)
-n, --dry-run Generate/review contexts without building or changing hashes
-f, --force Force update docker folder/files
--build-only Build and load one platform locally, do not push
--platforms Use auto or an explicit comma-separated platform list
-h, --help Show this help and exitNormal publication defaults to --platforms auto, which uses the complete
platform set verified for each official Joomla base image. --build-only
loads one platform into the local Docker image store, defaulting to the host
platform. Use an explicit single-platform override when needed, for example:
./src/bin/joomengine.sh --build-only --platforms linux/arm64/v8For publication or focused diagnostics, --platforms can also override the
automatic selection with an explicit comma-separated list.
Copyright (C) 2021-2026
Llewellyn van der Merwe
Licensed under the **GNU General Public License v2 (GPLv2)**
See `LICENSE` for details.