composer.json: the PHP packages
TYPO3 system extensions, the Keycloak integration, local packages and how updates work.
Overview
{
"name": "local/typo3-appliance",
"description": "TYPO3 Docker Appliance",
"type": "project",
"license": "GPL-2.0-or-later",
…
}Composer is the package manager for PHP. composer.json defines which packages are installed within which version ranges. This is the recommended way to install TYPO3: the core, system extensions and third-party extensions are ordinary Composer packages.
The type project marks an application that is not itself included as a library. The license GPL-2.0-or-later matches TYPO3’s.
Local packages (repositories)
"repositories": [
{
"type": "path",
"url": "packages/*"
}
],Besides the public directory Packagist, Composer also looks for packages in packages/. Every subfolder with its own composer.json becomes a package, here local/oidc-backend and local/site-package.
Composer installs path packages as symbolic links: vendor/local/site-package points to packages/site_package. To add a new extension of your own, create its folder and require it:
docker compose run --rm --no-deps --entrypoint "" -v "$PWD:/app" -w /app php \
composer require local/my-extension:@dev --no-install
docker compose up -d --build
Dependencies (require)
"require": {
"php": "^8.4",
"causal/oidc": "^6.0",
"local/oidc-backend": "@dev",
"local/site-package": "@dev",
"typo3/cms-backend": "^14.3",
"typo3/cms-core": "^14.3",
…
},The version constraints follow semantic versioning:
^14.3allows all versions from 14.3.0 below 15.0.0, that is bug fix and feature updates of TYPO3 14, but no jump to a new major version."php": "^8.4"is not a package but a condition: Composer refuses to install on an older PHP version.@devallows any development state of the local package. Path packages have no published versions.
The packages in detail:
| Package | Purpose |
|---|---|
typo3/cms-core | the TYPO3 core |
typo3/cms-backend | backend user interface |
typo3/cms-frontend | website output |
typo3/cms-extbase, typo3/cms-fluid | MVC framework and template engine |
typo3/cms-fluid-styled-content | standard content elements such as text, image, table |
typo3/cms-rte-ckeditor | CKEditor rich text editor |
typo3/cms-install | Install Tool and typo3 setup |
typo3/cms-extensionmanager | extension management in the backend |
typo3/cms-filelist | file management (fileadmin) |
typo3/cms-beuser, typo3/cms-setup | user management and personal user settings |
typo3/cms-belog | log of backend actions |
typo3/cms-dashboard | dashboard after login |
typo3/cms-info, typo3/cms-lowlevel | page information and system configuration for admins |
typo3/cms-tstemplate | TypoScript module |
typo3/cms-scheduler | scheduled tasks, triggered by the scheduler service |
typo3/cms-seo, typo3/cms-redirects | meta tags, hreflang, XML sitemap and redirects |
typo3/cms-form, typo3/cms-felogin | forms and frontend login |
causal/oidc | sign-in via OpenID Connect (Keycloak) |
local/oidc-backend | custom additions to the Keycloak integration |
local/site-package | templates, language switch, search and content of the website |
System extensions you do not need can be removed here. A rebuild then removes them.
Settings (config, extra, stability)
"config": {
"allow-plugins": {
"typo3/class-alias-loader": true,
"typo3/cms-composer-installers": true
},
"sort-packages": true
},
"extra": {
"typo3/cms": {
"web-dir": "public"
}
},
"minimum-stability": "stable",
"prefer-stable": trueallow-plugins: Composer only runs plugins that are explicitly allowed.typo3/cms-composer-installerscreates the web rootpublic/withindex.phpand links the extensions’ public files intopublic/_assets.typo3/class-alias-loaderprovides old class names as aliases so that older extensions keep working.sort-packages:composer requirekeeps the list underrequiresorted alphabetically.web-dir: the public folder that nginx serves as its document root. Everything outside it, such asvendor/,config/andvar/, is not reachable from the web.minimum-stabilityandprefer-stable: stable versions only, no betas or development states. Exceptions such as@devfor the local packages only apply where they are stated explicitly.
composer.lock and updates
# verfügbare Updates anzeigen
docker compose run --rm --no-deps --entrypoint "" -v "$PWD:/app" -w /app php \
composer outdated "typo3/*"
# TYPO3 innerhalb von ^14.3 aktualisieren, nur composer.lock neu schreiben
docker compose run --rm --no-deps --entrypoint "" -v "$PWD:/app" -w /app php \
composer update "typo3/*" --with-all-dependencies --no-install
# Images mit den neuen Versionen bauen und starten
docker compose up -d --buildcomposer.json names the allowed version ranges, and composer.lock the exact installed versions including checksums. The build always installs exactly the state of the lock file. That is why it belongs in the repository, and why every machine and every restore sees identical versions.
An update first changes only the lock file. --no-install prevents Composer from creating a local vendor/ in the project folder, which plays no role in the image anyway. Only the rebuild brings the new versions into the images. On start, the entrypoint adjusts the database schema.