TYPO3 Docker Images
Production-ready Docker images for TYPO3 CMS — Debian Trixie + PHP (Sury packages).
Multi-architecture support: linux/amd64 + linux/arm64 (Apple Silicon).
Images Overview
| Image | Purpose |
|---|---|
typo3incubator/typo3-base | Slim runtime image with PHP-FPM — build your project on top |
typo3/demo | Pre-installed TYPO3 for demos and evaluation |
typo3/contrib | Ready-to-run TYPO3 Core contribution environment |
Where to Start
- New to these images? Start with the Quick Start to have a running TYPO3 in minutes.
- Building a project? See Base Image for the production base and Production Deployment for a full stack with SSL.
- Contributing to TYPO3 Core? See Core Contribution.
Getting Started
This project provides three Docker images for different use cases:
- Base Image — A slim runtime image for building your own TYPO3 project images. Available as an all-in-one Nginx variant or a standalone FPM variant for Kubernetes.
- Demo Image — A pre-installed TYPO3 ready to start for demos, evaluation, and onboarding.
- Contrib Image — A development environment for contributing to the TYPO3 Core.
Start with the Quick Start to get a running TYPO3 in minutes, then explore the image that fits your use case.
Quick Start
Get a fully working TYPO3 demo running in minutes.
Prerequisites
- Docker with Docker Compose
Start the Demo
docker compose -f docker-compose.demo.yml up
This starts TYPO3 with MariaDB, Redis, and Mailpit.
| Service | URL |
|---|---|
| Frontend | http://localhost:8080 |
| Backend | http://localhost:8080/typo3 |
| Mailpit | http://localhost:8025 |
Admin Credentials
Admin credentials are randomly generated on first run. Check the setup container logs:
docker compose -f docker-compose.demo.yml logs setup
Or set your own via environment variables:
TYPO3_SETUP_ADMIN_USERNAME=admin \
TYPO3_SETUP_ADMIN_PASSWORD=MySecurePass1! \
docker compose -f docker-compose.demo.yml up
Stop the Demo
docker compose -f docker-compose.demo.yml down
Add -v to also remove the database volume and start fresh next time.
Next Steps
- Base Image — Build your own project image for production
- Demo Image — Learn about demo variants and tags
- Environment Variables — Configure TYPO3 via environment
Base Image
typo3incubator/typo3-base is a slim runtime image with PHP-FPM and all required PHP extensions for TYPO3. It does not contain TYPO3 itself — you build your project-specific image on top of it.
Variants
Two variants are available:
| Variant | Ports | Processes | Use Case |
|---|---|---|---|
-nginx | 80 | Nginx + PHP-FPM (Supervisor) | Docker Compose, simple deploys |
-fpm | 9000 | PHP-FPM only | Kubernetes, CI, external web server |
Available Tags
| Tag | PHP | Variant | Description |
|---|---|---|---|
8.2-nginx | 8.2 | Nginx | Minimum for TYPO3 v13 |
8.2-fpm | 8.2 | FPM | |
8.3-nginx | 8.3 | Nginx | Recommended |
8.3-fpm | 8.3 | FPM | |
8.4-nginx | 8.4 | Nginx | Latest PHP |
8.4-fpm | 8.4 | FPM | |
latest | 8.3 | Nginx | Alias for 8.3-nginx |
Usage — Nginx Variant (all-in-one)
# syntax=docker/dockerfile:1
FROM ghcr.io/typo3incubator/typo3-base:8.3-nginx AS base
FROM composer:2 AS build
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --prefer-dist --optimize-autoloader --no-scripts
COPY . .
RUN composer dump-autoload --optimize --no-dev
FROM base
COPY --from=build --chown=typo3:typo3 /app /var/www/html
Usage — FPM Variant (Kubernetes / external web server)
FROM ghcr.io/typo3incubator/typo3-base:8.3-fpm
COPY --from=build --chown=typo3:typo3 /app /var/www/html
Pair with an Nginx, Caddy, or Traefik container as a sidecar or reverse proxy.
Relationship to DDEV
These images complement DDEV — they do not compete with it.
| Use Case | Recommended Tool |
|---|---|
| Local development | DDEV |
| Team development | DDEV |
| CI/CD pipelines | typo3incubator/typo3-base (fpm variant) |
| Staging & production | typo3incubator/typo3-base (with your project) |
| Kubernetes / Cloud | typo3incubator/typo3-base (fpm variant) + Helm Charts |
| Demo & evaluation | typo3/demo |
| TYPO3 Core contribution | typo3/contrib |
Demo Image
typo3/demo is a pre-installed TYPO3 for demos, evaluation, and onboarding. Includes a complete TYPO3 setup ready to start.
Available Tags
| Tag | TYPO3 | PHP | Description |
|---|---|---|---|
13 | 13 LTS | 8.3 | Stable LTS |
13-php8.2 | 13 LTS | 8.2 | |
13-php8.4 | 13 LTS | 8.4 | |
14 | 14.x | 8.3 | Sprint releases |
14-php8.4 | 14.x | 8.4 | |
latest | 13 LTS | 8.3 | Alias for 13 |
Introduction Package Variant
Tags with -intro include the TYPO3 Introduction Package — a full demo site with sample content, pages, and templates.
| Tag | TYPO3 | PHP |
|---|---|---|
13-intro | 13 LTS | 8.3 |
13-intro-php8.2 | 13 LTS | 8.2 |
13-intro-php8.4 | 13 LTS | 8.4 |
14-intro | 14.x | 8.3 |
14-intro-php8.4 | 14.x | 8.4 |
Quick Start
docker compose -f docker-compose.demo.yml up
| Service | URL |
|---|---|
| Frontend | http://localhost:8080 |
| Backend | http://localhost:8080/typo3 |
| Mailpit | http://localhost:8025 |
Credentials
Admin credentials are randomly generated on first run. Check the setup container logs:
docker compose -f docker-compose.demo.yml logs setup
Or set your own:
TYPO3_SETUP_ADMIN_USERNAME=admin \
TYPO3_SETUP_ADMIN_PASSWORD=MySecurePass1! \
docker compose -f docker-compose.demo.yml up
Building Locally
# Standard demo
make build-demo
# With Introduction Package
make build-demo-intro
# Specific versions
make build-demo PHP_VERSION=8.4 TYPO3_VERSION=14
make build-demo-intro PHP_VERSION=8.4 TYPO3_VERSION=13
Guides
Step-by-step guides for common workflows:
- Production Deployment — Deploy TYPO3 with Traefik and automatic SSL
- Kubernetes — Run TYPO3 on Kubernetes with the FPM variant
- Environment Variables — Configure TYPO3 entirely via environment
- Core Contribution — Set up a TYPO3 Core development environment
Production Deployment
Deploy your TYPO3 project with Traefik reverse proxy and automatic Let's Encrypt SSL certificates.
Overview
The production stack includes:
- Traefik — Reverse proxy with automatic HTTPS via Let's Encrypt
- TYPO3 Web — Your project image based on the base image
- MariaDB — Database with health checks
- Redis — Cache backend for TYPO3
Prerequisites
- A server with Docker and Docker Compose
- A domain name pointing to your server
- Ports 80 and 443 open
Step 1: Build Your Project Image
Create a Dockerfile in your TYPO3 project:
# syntax=docker/dockerfile:1
FROM ghcr.io/typo3incubator/typo3-base:8.3-nginx AS base
FROM composer:2 AS build
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --prefer-dist --optimize-autoloader --no-scripts
COPY . .
RUN composer dump-autoload --optimize --no-dev
FROM base
COPY --from=build --chown=typo3:typo3 /app /var/www/html
Step 2: Copy Configuration Files
Copy docker-compose.prod.yml and .env.prod.example from this repository into your project:
curl -O https://raw.githubusercontent.com/TYPO3incubator/typo3-base/main/docker-compose.prod.yml
curl -O https://raw.githubusercontent.com/TYPO3incubator/typo3-base/main/.env.prod.example
Step 3: Configure Environment
cp .env.prod.example .env
Edit .env and set at minimum:
# Your domain (required)
DOMAIN=typo3.example.com
# Let's Encrypt email (required)
ACME_EMAIL=admin@example.com
# Database passwords (change these!)
TYPO3_DB_PASSWORD=your_secure_password
MARIADB_ROOT_PASSWORD=your_root_password
# TYPO3 encryption key (generate via Install Tool or openssl)
TYPO3_ENCRYPTION_KEY=your_encryption_key
Generate an encryption key:
openssl rand -hex 48
Step 4: Uncomment the Build Section
In docker-compose.prod.yml, uncomment the build section for the web service to build from your local Dockerfile:
web:
# image: ghcr.io/typo3incubator/typo3-base:${PHP_VERSION:-8.3}-nginx
build:
context: .
dockerfile: Dockerfile
args:
PHP_VERSION: "${PHP_VERSION:-8.3}"
Step 5: Start the Stack
docker compose -f docker-compose.prod.yml up -d
Your site will be available at https://your-domain.com with auto-renewed SSL.
Stack Architecture
Internet
│
├─ :80 ──→ Traefik ──→ HTTP→HTTPS redirect
├─ :443 ──→ Traefik ──→ TYPO3 web (:80 internal)
│ │
│ └─ Let's Encrypt TLS challenge
│
└─ Internal Docker network:
├─ web → TYPO3 (Nginx + PHP-FPM)
├─ db → MariaDB 11
└─ redis → Redis 7
Volumes
The production stack uses named volumes for persistent data:
| Volume | Mount Point | Purpose |
|---|---|---|
fileadmin | /var/www/html/public/fileadmin | Editor uploads |
typo3var | /var/www/html/var | Cache, logs, sessions |
typo3config | /var/www/html/config | Site configuration |
db-data | /var/lib/mysql | Database files |
redis-data | /data | Redis persistence |
traefik-certs | /letsencrypt | SSL certificates |
Environment Variables
See the full Environment Variables reference for all available configuration options including mail, PHP tuning, and Redis.
Kubernetes
Coming Soon — A Helm chart is planned. See the project roadmap for progress.
Recommended Setup
For Kubernetes deployments, use the FPM variant of the base image:
FROM ghcr.io/typo3incubator/typo3-base:8.3-fpm
COPY --from=build --chown=typo3:typo3 /app /var/www/html
The FPM variant exposes port 9000 and runs PHP-FPM only — pair it with an Nginx or Caddy sidecar container for serving static files and proxying PHP requests.
Key Considerations
- Use the
-fpmvariant (no bundled web server) - Run Nginx as a sidecar container in the same pod
- Mount
fileadminandvaras persistent volumes (PVC) - Use Kubernetes Secrets for database credentials and encryption keys
- Set all environment variables via ConfigMaps or Secrets
- The image runs as non-root user
typo3(UID 1000) — configuresecurityContextaccordingly
Health Checks
The FPM variant checks for a running php-fpm process. For Kubernetes liveness/readiness probes, configure a TCP check on port 9000 or use the Nginx sidecar's health endpoint.
Environment Variables
The base image includes a declarative environment-to-config mapping. Set any of the variables below and they are automatically applied to TYPO3 at runtime — no file editing needed.
Database
| Variable | Default | Description |
|---|---|---|
TYPO3_DB_DRIVER | mysqli | Database driver (mysqli, pdo_mysql, pdo_pgsql) |
TYPO3_DB_HOST | — | Database hostname |
TYPO3_DB_PORT | 3306 | Database port |
TYPO3_DB_NAME | — | Database name |
TYPO3_DB_USERNAME | — | Database user |
TYPO3_DB_PASSWORD | — | Database password |
TYPO3_DB_CHARSET | utf8mb4 | Database charset |
TYPO3_DB_COLLATION | utf8mb4_unicode_ci | Database collation |
TYPO3
| Variable | Default | Description |
|---|---|---|
TYPO3_CONTEXT | Production | Application context |
TYPO3_PROJECT_NAME | — | Site name (SYS.sitename) |
TYPO3_ENCRYPTION_KEY | — | Encryption key (SYS.encryptionKey) |
TYPO3_TRUSTED_HOSTS_PATTERN | .* | Trusted hosts pattern |
TYPO3_DISPLAY_ERRORS | — | Display errors (SYS.displayErrors) |
TYPO3_EXCEPTIONAL_ERRORS | — | Exceptional errors bitmask |
TYPO3_INSTALLTOOL_PASSWORD | — | Install tool password hash |
TYPO3_BE_DEBUG | — | Backend debug mode |
TYPO3_FE_DEBUG | — | Frontend debug mode |
TYPO3_SETUP_ADMIN_USERNAME | admin | Initial admin username (demo setup) |
TYPO3_SETUP_ADMIN_PASSWORD | — | Initial admin password (demo setup) |
TYPO3_SETUP_ADMIN_EMAIL | — | Initial admin email (demo setup) |
| Variable | Default | Description |
|---|---|---|
TYPO3_MAIL_TRANSPORT | — | Mail transport (smtp, sendmail, etc.) |
TYPO3_MAIL_SMTP_SERVER | — | SMTP server (host:port) |
TYPO3_MAIL_SMTP_USERNAME | — | SMTP username |
TYPO3_MAIL_SMTP_PASSWORD | — | SMTP password |
TYPO3_MAIL_FROM_ADDRESS | — | Default sender address |
TYPO3_MAIL_FROM_NAME | — | Default sender name |
TYPO3_MAIL_REPLY_ADDRESS | — | Default reply-to address |
TYPO3_MAIL_REPLY_NAME | — | Default reply-to name |
Legacy variables SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD are still supported for backwards compatibility.
Graphics
| Variable | Default | Description |
|---|---|---|
TYPO3_GFX_PROCESSOR | — | Image processor (e.g. GraphicsMagick) |
TYPO3_GFX_PROCESSOR_PATH | — | Path to processor binary |
TYPO3_GFX_PROCESSOR_PATH_LZW | — | Path to LZW processor binary |
PHP
| Variable | Default | Description |
|---|---|---|
PHP_MEMORY_LIMIT | 512M | Memory limit |
PHP_MAX_EXECUTION_TIME | 240 | Max execution time |
PHP_UPLOAD_MAX_FILESIZE | 32M | Upload max size |
PHP_POST_MAX_SIZE | 32M | Post max size |
PHP_MAX_INPUT_VARS | 1500 | Max input variables |
Redis Cache Backend
| Variable | Default | Description |
|---|---|---|
REDIS_HOST | — | Redis host (enables Redis cache backend) |
REDIS_PORT | 6379 | Redis port |
When REDIS_HOST is set, TYPO3 cache backends (hash, pages, rootline) are automatically configured to use Redis databases 0-2.
Extending the Config Mapping
The environment mapping is defined in base/config/typo3/additional.php using a declarative $configMappings array. To add a new env var, extend the array:
$configMappings = [
'EXTENSIONS' => [
'my_extension' => [
'apiKey' => 'MY_EXTENSION_API_KEY',
],
],
// ... existing mappings
];
Or mount your own config/system/additional.php to override entirely.
See Config Mapping for a detailed explanation of the mapping mechanism.
Core Contribution
typo3/contrib is a ready-to-run environment for contributing to the TYPO3 Core. It uses the FPM base image with a host-side Git checkout of the TYPO3 mono repository, set up as a Composer-based project.
Available Tags
| Tag | PHP | Description |
|---|---|---|
8.2 | 8.2 | Minimum PHP for TYPO3 Core |
8.3 | 8.3 | |
8.4 | 8.4 | Latest PHP |
latest | 8.2 | Alias for 8.2 |
Setup
1. Create a Working Directory and Clone TYPO3 Core
mkdir ~/TYPO3-Contrib && cd ~/TYPO3-Contrib
git clone --branch=main ssh://YOUR_USERNAME@review.typo3.org:29418/Packages/TYPO3.CMS.git typo3core
Replace YOUR_USERNAME with your my.typo3.org username.
2. Download the Compose File
curl -O https://raw.githubusercontent.com/TYPO3incubator/typo3-base/main/docker-compose.contrib.yml
3. Start the Environment
docker compose -f docker-compose.contrib.yml up --build
| Service | URL |
|---|---|
| Frontend | http://localhost:28080 |
| Backend | http://localhost:28080/typo3 |
| Mailpit | http://localhost:28025 |
Credentials: contrib / Th4nx4H3lp1ng
4. Install Additional Packages
Enter the web container to require additional packages:
docker compose -f docker-compose.contrib.yml exec web composer require "georgringer/news:*"
How It Works
The contrib image mounts your local TYPO3 Core checkout into the container. Changes you make on the host are immediately reflected inside the container. The environment includes:
- PHP-FPM + Nginx
- MariaDB
- Redis cache backend
- Mailpit for mail testing
- Composer (pre-installed in the base image)
Architecture
Build Stages
The build uses a multi-stage Dockerfile with selectable targets:
debian:trixie-slim + Sury PHP
|
[php-base] <- shared stage (PHP + extensions + Composer + GraphicsMagick)
/ \
[fpm] [nginx]
:8.3-fpm :8.3-nginx <- build targets (--target fpm / --target nginx)
| |
| Dockerfile.demo -> typo3/demo:{TYPO3_VERSION}
|
Dockerfile.contrib -> typo3/contrib:{PHP_VERSION}
Variants
| Variant | Ports | Processes | Use Case |
|---|---|---|---|
-nginx | 80 | Nginx + PHP-FPM (Supervisor) | Docker Compose, simple deploys |
-fpm | 9000 | PHP-FPM only | Kubernetes, CI, external web server |
Key Directories
| Path | Purpose |
|---|---|
base/config/php/ | PHP ini files (typo3.ini, opcache.ini) and FPM pool config |
base/config/nginx/ | Nginx config (nginx.conf main, typo3.conf TYPO3 vhost) — nginx variant only |
base/config/supervisor/ | Supervisord config (Nginx + PHP-FPM) — nginx variant only |
base/config/typo3/ | TYPO3 additional.php with environment mapping |
base/docker-entrypoint.sh | Entrypoint script — variant-aware, handles env var substitution |
demo/setup-demo.sh | Demo setup script (TYPO3 install/setup) |
demo/config/sites/main/ | TYPO3 site configuration for demo |
Base Image Internals
- OS: Debian Trixie (slim) with Sury PHP repository
- PHP installation: Pre-built packages via
apt install(no compilation) - Runs as non-root user
typo3(UID/GID 1000) - Nginx variant: Supervisor manages Nginx + PHP-FPM, exposes port 80, healthcheck at
/healthz - FPM variant: PHP-FPM only, exposes port 9000, healthcheck via process check
- PHP config paths:
/etc/php/${PHP_VERSION}/fpm/conf.d/and/etc/php/${PHP_VERSION}/cli/conf.d/ - FPM socket:
/run/php/php-fpm.sock - FPM binary symlink:
/usr/local/bin/php-fpm->/usr/sbin/php-fpm${PHP_VERSION}
Demo Image Build
The demo image uses a two-stage build:
- Build stage: Uses the nginx base image to run
composer create-project typo3/cms-base-distribution - Final stage: Copies the built project into a clean base image layer
The optional TYPO3_DEMO_CONTENT=introduction build arg adds the Introduction Package during the build stage.
Build Variables
| Variable | Default | Used in |
|---|---|---|
PHP_VERSION | 8.3 | Both Dockerfiles, Makefile |
TYPO3_VERSION | 13 | Dockerfile.demo, Makefile |
TYPO3_DEMO_CONTENT | "" | Dockerfile.demo (set to introduction for intro variant) |
REGISTRY | ghcr.io | Makefile |
BASE_IMAGE | $(REGISTRY)/typo3incubator/typo3-base | Makefile |
DEMO_IMAGE | $(REGISTRY)/typo3incubator/typo3-demo | Makefile |
CONTRIB_IMAGE | $(REGISTRY)/typo3incubator/typo3-contrib | Makefile |
HTTP_PORT | 8080 | Makefile (demo) |
PHP Extensions
All extensions required by TYPO3 are pre-installed in the base image.
Core Extensions
| Extension | Purpose |
|---|---|
gd | Image processing |
intl | Internationalization |
mbstring | Multi-byte string handling |
mysqli | MySQL/MariaDB driver |
opcache | Bytecode caching |
pdo_mysql | PDO MySQL driver |
pdo_pgsql | PDO PostgreSQL driver |
pgsql | PostgreSQL driver |
xml | XML parsing |
zip | ZIP archive handling |
Caching Extensions
| Extension | Purpose |
|---|---|
apcu | In-memory key-value cache |
redis | Redis client for cache backends |
Bundled Tools
| Tool | Version | Purpose |
|---|---|---|
| Composer | 2.x | PHP dependency management |
| GraphicsMagick | — | Image processing (GIF, JPEG, PNG, WebP) |
Volumes
For production deployments, mount these paths to persist data across container restarts:
Mount Points
| Path | Purpose |
|---|---|
/var/www/html/public/fileadmin | Editor uploads (images, documents, media) |
/var/www/html/var | Cache, logs, sessions |
/var/www/html/config | Site configuration |
Security Notes
- Mount
fileadminandvaras named Docker volumes or bind mounts with appropriate permissions - Avoid exposing volume mounts directly to the host filesystem in production
- The
vardirectory contains logs and session data — restrict access accordingly - Back up
fileadminand database regularly — these contain user-generated content - The
configdirectory holds site configuration that may include sensitive settings
Config Mapping
The base image includes a declarative mechanism to configure TYPO3 entirely via environment variables. This is implemented in base/config/typo3/additional.php.
How It Works
The additional.php file defines a $configMappings array that maps environment variable names to TYPO3 configuration paths. At runtime, each environment variable is checked — if set, its value is written into the corresponding TYPO3 configuration key.
This means you can configure database connections, mail transport, cache backends, and more without editing any PHP files.
The Mapping Array
The mapping uses a nested structure that mirrors TYPO3's configuration hierarchy:
$configMappings = [
'DB' => [
'Connections' => [
'Default' => [
'host' => 'TYPO3_DB_HOST',
'port' => 'TYPO3_DB_PORT',
'dbname' => 'TYPO3_DB_NAME',
'user' => 'TYPO3_DB_USERNAME',
'password' => 'TYPO3_DB_PASSWORD',
'driver' => 'TYPO3_DB_DRIVER',
'charset' => 'TYPO3_DB_CHARSET',
],
],
],
'SYS' => [
'sitename' => 'TYPO3_PROJECT_NAME',
'encryptionKey' => 'TYPO3_ENCRYPTION_KEY',
'trustedHostsPattern'=> 'TYPO3_TRUSTED_HOSTS_PATTERN',
'displayErrors' => 'TYPO3_DISPLAY_ERRORS',
],
// ... more mappings for MAIL, GFX, EXTENSIONS
];
Adding Custom Mappings
To map a new environment variable, extend the $configMappings array. For example, to configure an extension setting:
$configMappings = [
'EXTENSIONS' => [
'my_extension' => [
'apiKey' => 'MY_EXTENSION_API_KEY',
'debugMode' => 'MY_EXTENSION_DEBUG',
],
],
// ... existing mappings
];
Then set the environment variable in your docker-compose.yml or .env file:
environment:
MY_EXTENSION_API_KEY: "your-api-key"
Overriding Entirely
If you need full control, mount your own configuration file:
volumes:
- ./my-additional.php:/var/www/html/config/system/additional.php
This replaces the built-in mapping entirely.
Redis Cache Backend
The Redis cache backend is configured automatically when REDIS_HOST is set. It maps TYPO3 cache backends to Redis databases:
| Cache | Redis DB |
|---|---|
hash | 0 |
pages | 1 |
rootline | 2 |
See Environment Variables for the full list of supported variables.
Building
All build commands are available via make. Run make help to see all available targets.
Prerequisites
- Docker (with Buildx)
- GNU Make
- Git
Build Targets
# Build base image — nginx variant (default PHP 8.3)
make build-base
# Build base image — fpm-only variant
make build-base-fpm
# Build demo image (requires base nginx variant)
make build-demo
# Build demo image with Introduction Package
make build-demo-intro
# Build contrib image (requires base fpm variant)
make build-contrib
# Build all (nginx + fpm + demo + contrib)
make build-all
Specific Versions
# Build with specific PHP version
make build-base PHP_VERSION=8.4
make build-base-fpm PHP_VERSION=8.4
# Build with specific TYPO3 version
make build-demo PHP_VERSION=8.4 TYPO3_VERSION=14
make build-demo-intro PHP_VERSION=8.4 TYPO3_VERSION=13
Full Matrix Build
Build all PHP x TYPO3 x variant combinations:
make matrix
This builds base images (nginx + fpm) for PHP 8.2/8.3/8.4, demo images for TYPO3 13/14, introduction package variants, and contrib images.
Build Variables
| Variable | Default | Description |
|---|---|---|
PHP_VERSION | 8.3 | PHP version for base image |
TYPO3_VERSION | 13 | TYPO3 version for demo image |
REGISTRY | ghcr.io | Container registry |
BASE_IMAGE | $(REGISTRY)/typo3incubator/typo3-base | Base image name |
DEMO_IMAGE | $(REGISTRY)/typo3incubator/typo3-demo | Demo image name |
CONTRIB_IMAGE | $(REGISTRY)/typo3incubator/typo3-contrib | Contrib image name |
HTTP_PORT | 8080 | Host port for demo |
Running the Demo
# Build and start demo
make demo
# Start demo without rebuild
make up
# Stop demo
make down
Demo runs at http://localhost:8080, backend at /typo3.
Running the Contrib Environment
make contrib
Opens at http://localhost:28080.
Cleanup
make clean
Removes all built images and volumes.
Testing
Smoke Tests
Run smoke tests to verify the base image is correctly built:
# Test nginx variant
make test
# Test fpm variant
make test-fpm
# Test specific PHP version
make test PHP_VERSION=8.4
make test-fpm PHP_VERSION=8.4
Smoke tests verify:
- All required PHP extensions are loaded
- Composer is installed and working
- Nginx configuration is valid (nginx variant)
- GraphicsMagick is available
Integration Tests
Integration tests start the full demo stack and verify end-to-end functionality:
make demo
# Then manually verify:
# - Frontend responds at http://localhost:8080
# - Backend login works at http://localhost:8080/typo3
# - Health endpoint at http://localhost:8080/healthz
CI/CD Pipeline
Every push and PR triggers the GitHub Actions pipeline:
- lint — Hadolint checks on all Dockerfiles
- build-base — Builds base images for PHP 8.2, 8.3, 8.4 (linux/amd64 + linux/arm64)
- test — Smoke tests for nginx and fpm variants
- integration-test — Full stack test (MariaDB + Redis + TYPO3 setup + HTTP checks)
- build-demo — Builds demo images for TYPO3 13 + 14 with multiple PHP versions
- build-demo-intro — Builds demo images with Introduction Package
- build-contrib — Builds contrib images for PHP 8.2, 8.3, 8.4
- security-scan — Trivy vulnerability scan (on push to main only)
The pipeline builds multi-architecture images (amd64 + arm64) and pushes to GHCR on main branch. Pull requests build and test but do not push.
Weekly Rebuilds
Images are automatically rebuilt every Monday at 04:00 UTC to include the latest security patches from Debian and PHP.
Contributing
Contributions are welcome! This guide explains how to set up the development environment and submit changes.
Prerequisites
- Docker (with Buildx)
- GNU Make
- Git
Getting Started
git clone https://github.com/TYPO3incubator/typo3-base.git
cd typo3-base
Project Structure
.
├── Dockerfile.base # Base image (Debian Trixie + PHP-FPM)
├── Dockerfile.demo # Demo image (TYPO3 pre-installed)
├── Dockerfile.contrib # Contrib image (Core development)
├── Makefile # Build and test commands
├── docker-compose.demo.yml # Demo stack (MariaDB + Redis + TYPO3)
├── docker-compose.prod.yml # Production template (Traefik + SSL)
├── docker-compose.contrib.yml # Core contribution stack
├── base/
│ ├── config/nginx/ # Nginx configuration
│ ├── config/php/ # PHP ini and FPM pool config
│ ├── config/supervisor/ # Supervisord config
│ ├── config/typo3/ # TYPO3 additional.php (env mapping)
│ └── docker-entrypoint.sh # Entrypoint with env var substitution
├── demo/
│ ├── config/sites/main/ # TYPO3 site configuration
│ └── setup-demo.sh # Demo setup script
├── docs/ # MDBook documentation (this site)
└── .github/workflows/build.yml # CI/CD pipeline
Development Workflow
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-change) - Make your changes
- Run tests (
make test) - Commit with a descriptive message
- Push and open a Pull Request
PR Guidelines
- Keep changes focused — one feature or fix per PR
- Update documentation if behavior changes
- Ensure
make testpasses - Test with at least one PHP version locally
Quick Verification
# Build and test everything
make build-all
make test
make test-fpm
Security
Supported Versions
| Image | Tag | Supported |
|---|---|---|
| typo3incubator/typo3-base | 8.3-nginx | Yes |
| typo3incubator/typo3-base | 8.4-nginx | Yes |
| typo3incubator/typo3-base | 8.2-nginx | Yes |
| typo3/demo | 13 | Yes |
| typo3/demo | 14 | Yes |
Reporting a Vulnerability
If you discover a security vulnerability in these Docker images, please report it responsibly:
- Do not open a public GitHub issue
- Email the maintainers with details of the vulnerability
- Include steps to reproduce and potential impact
Security Practices
Credentials
- The demo image generates random admin passwords on first run
- Credentials are stored in
/var/www/html/var/credentials.txt(mode 600, owned bytypo3user) - Never use the demo image in production without changing credentials
- Set
TYPO3_SETUP_ADMIN_PASSWORDvia environment variable for deterministic passwords
Container Security
- Images run as non-root user
typo3(UID/GID 1000) - Supervisor manages Nginx and PHP-FPM as child processes
- No SSH or remote shell access included
- Debian Trixie slim base reduces attack surface
Network
- Only port 80 is exposed by the nginx base image (port 9000 for fpm)
- Use a reverse proxy (Traefik, Nginx) with TLS termination in production
- Database and Redis connections should stay on internal Docker networks
docker-compose.demo.ymluses an isolated network by default
Volumes
- Mount
/var/www/html/varto persist logs and sessions - Mount
/var/www/html/public/fileadminfor editor uploads - Avoid exposing volume mounts directly to the host in production
Updates
- Images are rebuilt weekly (Monday 04:00 UTC) to include security patches
- Trivy vulnerability scans run on every push to main
- Pin specific image tags in production (
8.3-nginx, notlatest)
Database
- Use strong passwords for
TYPO3_DB_PASSWORDandMARIADB_ROOT_PASSWORD - Do not expose database ports to the host in production
- Use dedicated database users with minimal privileges