Container images for Phase2's devcloud preview environments and CI. Together they replace phase2/docker-cli.
| Image | Use it for | Tags |
|---|---|---|
ghcr.io/phase2/php-devcloud |
the PHP-FPM sidecar in devcloud pods; FROM for project images |
8.3, 8.4, 8.5, plus immutable 8.x-YYYYMMDD-<sha> |
ghcr.io/phase2/php-ci |
GitHub Actions job container for PHP projects | 8.3, 8.4, 8.5, plus immutable 8.x-YYYYMMDD-<sha> |
ghcr.io/phase2/ci-tools |
GitHub Actions job container without PHP | 1, plus immutable 1-YYYYMMDD-<sha> |
All images are linux/amd64 and linux/arm64, Debian trixie-slim based, with the docker user at 1000:1000 and code at /var/www. There is no latest tag.
images/
base/ internal foundation: docker user, utilities, nvm + Node 24 (not published)
ci-tools/ base + kubectl, helm (helm3), kustomize, aws, htpasswd, tmate
php-ci/ ci-tools + PHP CLI + Composer
php-devcloud/ base + PHP CLI/FPM, Composer, MySQL client, build tools; rootfs/ and tests/
_shared/ install-php.sh + install-composer.sh (used by both PHP images) + shared structure tests
docker-bake.hcl every image and the PHP matrix; named contexts wire the images together
Makefile lint / build / test / scan, used locally and in CI
Each image has a README with its tools, settings and details: base, ci-tools, php-ci, php-devcloud.
mise install # once: shellcheck, container-structure-test, lefthook
lefthook install # once: pre-commit hook (lint + gitleaks on staged changes)
make builder # once: docker-container builder (bake needs it)
make lint # hadolint, shellcheck, BuildKit checks
make repo-lint # actionlint, gitleaks
make build test scan IMAGE=php-devcloud PHP=8.4
make build test scan IMAGE=php-ci PHP=8.5
make build test scan IMAGE=ci-toolsPrerequisites: Docker with buildx and mise. mise.toml pins the host tools, mise.lock their checksums, and CI installs from the same files. hadolint, Trivy, actionlint and gitleaks run from digest-pinned images.
Images are only buildable through bake. FROM base and FROM ci-tools are bake named contexts, not registry images.
- Startup. With no command it runs
php-fpmon port 9000. The FPM master runs as root and the workers asdocker, withclear_env = no. - User and sudo. The image starts as root and
dockerhas passwordless sudo, because devcloud tooling runsrunuser -u dockeras root andsudoas uid 1000. It is not meant as a production runtime. - Project overrides. Set
PHP_OVERRIDES_DIRto a directory, typically in the project checkout, and the entrypoint applies it at start. When it is unset there are no project overrides, and the entrypoint logs a notice saying so. The directory holds:*.iniapplies to both the CLI and FPM.php-fpm.confholds[www]pool directives, e.g.php_admin_value[memory_limit] = 2048M.
- Memory. FPM defaults to
memory_limit = 1024Mand the CLI to-1. - Xdebug. Set
XDEBUG_ENABLED=1to turn it on.XDEBUG_MODE,XDEBUG_CLIENT_HOSTandXDEBUG_CLIENT_PORTconfigure it. - Node.
- nvm lives at
NVM_DIR=/home/docker/.nvm, with Node 24 as the default. nvm installfetches whatever a project's.nvmrcasks for and adds yarn 1 to it automatically.
- nvm lives at
- Debian packages come in through the weekly scheduled rebuild (no cache) and are gated on Trivy.
- Tool versions are
ARGs (or variables in theimages/_shared/*.shscripts) with# renovate:comments.- Renovate opens the bump PRs. Patch and minor bumps auto-merge on green CI.
- Builds verify each download against the checksum file its project publishes.
- Breaking changes to
ci-tools(a removed tool, for example) bumpCI_TOOLS_MAJORindocker-bake.hcl; CI reads the variants and their tags from there. They are recorded inCHANGELOG.md.
.github/workflows/images.yml runs lint, then builds and tests every variant on native amd64 and arm64 runners. On main, the weekly schedule and manual runs it then publishes through docker/github-builder. That adds an SBOM, SLSA provenance and signed attestations.
- Required check. The
cijob passes only when lint and every test variant pass. Make it the one required status check onmain; the test jobs' names come fromdocker-bake.hcl, so they can't be listed individually. - Code scanning. Each test job uploads Trivy's fixable HIGH/CRITICAL findings, including vendored npm, Go and PHP dependencies, to the repository's code scanning alerts, one category per variant and architecture. Pull requests from forks skip the upload.
GHCR packages must be public for devcloud to pull them, because the pod pulls anonymously. Set this once per package after its first publish.