Skip to content

Containerized TYPO3 – from quick start to extension development

License

Notifications You must be signed in to change notification settings

undecaf/typo3-dev

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Containerized TYPO3 – from quick start to extension development

Build Status Latest release Image Size

This project provides a containerized TYPO3 installation equivalent to composer require typo3/cms with ImageMagick installed and configured for Composer Mode. The image is based on Alpine Linux 3.10, Apache 2.4 and PHP 7.3, uses less than 300 MB disk space and can run in Docker and Podman.

The TYPO3 container can be combined with a database container such as MySQL or PostgreSQL but also can be run independently due to the built-in SQLite database. Setting up and managing such scenarios is simplified by a shell script for Linux and macOS.

You can use your favorite IDE on the host to develop for TYPO3 in the container, including remote debugging with XDebug. Your extension development directories can be excluded from changes made by Composer. PHP and Composer do not need to be installed on the host.

File access rights, ownerships, UIDs and GIDs are transparently and consistently mapped between host and container.

What you get

Parts of this project in a block diagram: containers for TYPO3 and database, browser and IDE

Contents

Running TYPO3

Quick start

To start a TYPO3 instance in a standalone container, enter this command:

$ docker run \
    --volume typo3-root:/var/www/localhost \
    --publish 127.0.0.1:8080:80 \
    undecaf/typo3-dev

If you prefer working rootless with Podman then substitute podman for docker.

Next, browse to https://localhost:8080. This starts the TYPO3 installation wizard. When asked to select a database, choose Manually configured SQLite connection and continue through the remaining dialogs to the TYPO3 login dialog.

Volume typo3-root persists the state of the TYPO3 instance independently of container lifetime.

Online documentation

In order to view the version of this README file that matches the version of the running TYPO3 instance, browse to https://localhost:8080/readme.html.

t3 shell script

More complex setups (such as using an external database) require complex Docker or Podman command lines.

In order to simplify usage, the t3 shell script has been provided for Linux and macOS. This script is avaliable for download here. It lets you:

  • configure and run a TYPO3 container plus an optional database container;
  • stop these containers and optionally remove them;
  • map the TYPO3 root in the container to a working directory;
  • modify the TYPO3 environment even while the container is running;
  • run Composer within the TYPO3 container.

See the t3 reference for a complete description.

Quick start with t3

To run a TYPO3 standalone container as shown above with t3, simply type:

$ t3 run --

t3 chooses between Docker and Podman engines automatically, depending on which one is installed. If both are, Podman will be preferred.

To stop and remove the container, enter

$ t3 stop --rm

State is preserved in volume typo3-root so that a subsequent t3 run -- command will resume from where you left off.

MariaDB and PostgreSQL

MariaDB or PostgreSQL is optional for TYPO3 v9.5+ but is required for TYPO3 v8.7.

The following example starts a TYPO3 and a MariaDB container (bitnami/mariadb) and connects them, preserves state in volumes typo3-root and typo3-data and exposes TYPO3 and MariaDB on ports 127.0.0.1:8080 and 127.0.0.1:3306, respectively:

$ t3 run -d maria

For a PostgreSQL container (bitnami/postgresql) exposed on 127.0.0.1:5432, replace -d maria with -d postgres.

Enter

$ t3 stop --

to stop both containers. If you wish to have the stopped containers removed, too, append --rm to t3 run or t3 stop.

Database credentials

Database credentials can be defined by host environment variables T3_DB_NAME, T3_DB_USER and T3_DB_PW. If not set then the database name, user and password all default to t3.

Developing for TYPO3

The following sections describes how this project can aid in customizing or developing TYPO3 extensions or otherwise altering the source code of your TYPO3 installation.

Using an IDE

In order to work on your TYPO3 installation in an IDE, the TYPO3 root directory needs to be exposed to a working directory where the current user has sufficient (read and write) permissions. At the container volume mount point, this is usually not the case.

t3 uses the bindfs utility (available for Debian-like and macOS hosts) to solve this problem. See below for what is happening behind the scenes.

First, bindfs needs to be installed from the repositories of your system. For macOS, osxfuse is required beforehand.

When starting TYPO3, specify the path of the desired working directory (e.g. ~/ide-workspace/typo3-root) as the -v option to t3 run, i.e. in the simplest case

$ t3 run -v ~/ide-workspace/typo3-root

This will

  • start the container(s),
  • create a TYPO3 volume having the working directory basename (typo3-root) as its name,
  • make the TYPO3 volume content appear in the working directory (~/ide-workspace/typo3-root) as if it were owned by the current user.

Thus, the TYPO3 instance can now be edited in the IDE. File changes, creates and deletes will be passed in both directions between working directory and container with the current user's UID/GID mapped to container UIDs/GIDs.

Stopping the TYPO3 container will unmount the working directory automatically.

Podman users please note: working directories require at least Podman v1.4.3.

Editing a stopped TYPO3 instance

Whenever there is a persistent TYPO3 volume, you can edit that TYPO3 instance even if the container is not running or does not even exist. Just mount your working directory on top of the volume:

$ t3 mount -m ~/ide-workspace/typo3-root

As with t3 run -v, the name of the volume is the working directory basename.

When you are finished, unmount your working directory again:

$ t3 unmount -u ~/ide-workspace/typo3-root

Behind the scenes

The TYPO3 root directory is accessible outside of the container at the volume mount point of e.g. typo3-root which can be obtained by inspecting the container. The files, however, are owned by a system account and cannot be edited by the current user, e.g.:

$ sudo ls -nA $(sudo docker volume inspect --format '{{.Mountpoint}}' typo3-root)

-rw-r--r--  1 100 101   1117 Mai  3 23:00 composer.json
-rw-r--r--  1 100 101 155056 Mai  3 23:01 composer.lock
drwxr-xr-x  6 100 101   4096 Mai  3 22:58 public
drwxrwsr-x  7 100 101   4096 Mai  3 23:02 var
drwxr-xr-x 15 100 101   4096 Mai  3 23:01 vendor

With Podman, files are owned by one of the current user's sub-UIDs which leads to the same problem.

bindfs is a FUSE filesystem that resolves this situation. It can provide a bind-mounted view of the files and directories in a volume with their UIDs and GIDs mapped to your own UID and GID. This does not affect UIDs and GIDs seen by the container.

Setting the container environment

Container environment variables control the time zone inside the container, TYPO3 mode, PHP settings and Composer operation.

These variables can be set by t3 run option --env, e.g.

$ t3 run --env MODE=dev --env php_post_max_size=500K

Command t3 env can modify most settings also while the container is running, e.g. in order to change the TYPO3 mode or to experiment with different php.ini settings:

$ t3 env MODE=xdebug php_post_max_size=1M

Container environment settings are lost when the container is stopped.

Composer

Command t3 composer lets you manage your TYPO3 installation. It accepts Composer command line options and is equivalent to running Composer inside the container, e.g.

$ t3 composer require bk2k/bootstrap-package

t3 composer and the composer script found in the container always act on the TYPO3 root directory. Neither Composer nor PHP have to be installed on the host.

XDebug should be deactivated before running Composer because it might slow down Composer significantly.

Preventing Composer from overwriting your changes

If you are continuing development of an extension which is already available from a repository, then running t3 composer update may overwrite your changes with the (older) version of that extension from the repository.

In order to prevent this, set the container environment variable COMPOSER_EXCLUDE to a colon-separated list of subdirectories of /var/www/localhost which are to be excluded from changes made by Composer.

Debugging with XDebug

Set up your IDE for XDebug

Install browser debugging plugins

Although not strictly required, debugging plugins make starting a XDebug session more convenient. Browser Debugging Extensions lists recommended plugins for various browsers.

Activate XDebug in the container

Unless the container was started already with --env MODE=xdebug or host environment variable T3_MODE=xdebug, this mode needs to be activated now:

$ t3 env MODE=xdebug

Now everything is ready to start a XDebug session.

Accessing the TYPO3 database

SQLite

A working directory needs to be mounted as described above. Point your database client at the file var/sqlite/cms-*.sqlite in that working directory. This is the TYPO3 SQLite database. The actual filename contains a random part.

MariaDB and PostgreSQL

Unless configured differently by t3 run option -P or host environment variable T3_DB_PORT, MariaDB is accessible at 127.0.0.1:3306 and PostgreSQL at 127.0.0.1:5432.

The database credentials are defined by host environment variables.

Managing multiple TYPO3 instances

To have multiple TYPO3 instances coexist, each instance must have

  • a unique container name (t3 run option -n), and
  • unique volume names or work directories (t3 run options -v and -V).

If you wish to run multiple TYPO3 instances simultaneously then each instance must be mapped also to unique host ports (t3 run options -p and -P). Debugging is possible in one instance at a time only.

Each t3 stop, t3 composer and t3 env command must be given an -n option to specify which TYPO3 instance should be targeted.

Suggested implementation

For each TYPO3 instance, create a configuration script which exports all required options as host environment variables, e.g. my-t3-conf:

export T3_NAME=my-t3
export T3_ROOT=t3-root
export T3_PORT=127.0.0.1:8181
  ⁝

source the appropriate configuration script before issuing each t3 command and omit all options from the command, e.g.

$ source my-t3-conf && t3 run --
  ⁝
$ source my-t3-conf && t3 stop

t3 shell script reference

t3is a shell script for Linux and macOS for managing containerized TYPO3 instances. t3 command lines contain a command verb (what to do) and options (how to do it):

$ t3 COMMAND [option]...

The t3 script is avaliable for download here. In order to view the version of this document that matches a running TYPO3 instance, point your browser to e.g. https://localhost:8080/readme.html.

Commands are described below.

Getting help

This displays a list of available commands:

$ t3 -h

Getting help for a particular command:

$ t3 COMMAND -h

t3 run

Configures and runs a TYPO3 container plus an optional MariaDB/PostgreSQL container:

$ t3 run [option]... [--] [Docker/Podman option]...

Although all options are optional, at least one option must be set (-- is sufficient) as a precaution against inadvertent command invocation.

Container engine: if you have both Docker and Podman installed then option -e lets you choose between docker and podman. Setting host environment variable T3_ENGINE relieves you from repeating that option for each t3 command.

Container name(s): the name of the TYPO3 container defaults to typo3. Option -n and host environment variable T3_NAME let you specify a different name. The database container name is derived from the TYPO3 container name by appending -db.

TYPO3: by default, the latest image built for the most recent TYPO3 version is pulled from docker.io/undecaf/typo3-dev. Option -t (or T3_TAG) selects a particular TYPO3 version and build by one of the available tags.

TYPO3 is served at 127.0.0.1:8080 by default. Option -p (or T3_PORT) lets you choose a different host interface and/or port.

TYPO3 volume and work directory: The TYPO3 instance is saved in a persistent volume named typo3-root. A different name can be assigned by option -v (or T3_ROOT). That name must not contain a /.

The TYPO3 volume can be made available for editing in a working directory at the host: just specify the working directory path (it must contain a /) for option -v (or T3_ROOT). This will have the following effects:

  1. The working directory basename becomes the TYPO3 volume name.
  2. The TYPO3 volume content appears in the working directory as if it were owned by the current user.
  3. File changes, creates and deletes will be passed in both directions between working directory and container, with the current user's UID/GID mapped to container UIDs/GIDs.

Please note: using working directories requires the bindfs (available for Debian-like and macOS hosts) utility to be installed from the repositories of your system. For macOS, osxfuse is needed beforehand.

Database: by default, the SQLite instance of the TYPO3 image is used (works only with TYPO3 V9.5+). Option -d (or T3_DB_TYPE) lets you use mariadb or postgresql, pulling the latest image from docker.io/bitnami/mariadb or docker.io/bitnami/postgresql, respectively.

Database state is saved in persistent volumes: SQLite is part of the TYPO3 volume, and MariaDB and PostgreSQL each use an additional volume named typo3-data. Option -V (or T3_DB_DATA) sets a different volume name.

A new database is created whenever a database volume is used for the first time. MariaDB and PostgreSQL database name and credentials are determined by host environment variables T3_DB_NAME, T3_DB_USER and T3_DB_PW. If not set then they all default to t3.

To access an SQLite database from the host, a TYPO3 working directory must be specified (see above). The database is located at var/sqlite/cms-*.sqlite in that working directory. The actual filename contains a random part.

MariaDB and PostgreSQL databases are published to the host at 127.0.0.1:3306 and 127.0.0.1:5432 by default. Use the -P option (or T3_DB_PORT) to set a different host interface and/or port.

Container environment variables: control the time zone inside the container, TYPO3 mode, PHP settings and Composer operation; see this table for details.

Use option --env NAME=VALUE or the corresponding host environment variable to assign an initial value to a container environment variable; --env takes precedence.

This option may appear multiple times. --env options must be the last options on the command line.

The container environment can be changed at runtime by command t3 env.

Remove stopped container(s): add option --rm if the TYPO3 and the database container (if one exists) should be removed by t3 stop. This option can also be used with t3 stop.

Please note: t3 never removes volumes. You have to use docker/podman volume rm to do that.

Options to be passed to Docker/Podman: must be placed at the end of the command line and should be separated from t3 options by --. Such options are applied to both the TYPO3 and the database container (if one exists).

t3 stop

Stops a running TYPO3 (and the associated database) container:

$ t3 stop [option]...

t3 stop will unmount a working directory mounted by t3 run or by t3 mount.

Although all options are optional, at least one option must be set (-- is sufficient) as a precaution against inadvertent command invocation.

Container engine: the same engine as for the corresponding t3 run command. Use option -e (or T3_ENGINE) if necessary.

Container name: the same container name as for the corresponding t3 run command. Use option -n (or T3_NAME) if necessary.

Remove stopped container(s): add option --rm if the TYPO3 and the database container (if one exists) should be removed after being stopped. This option can also be used with t3 run.

t3 env

Modifies the environment of a running TYPO3 container by setting container environment variables:

$ t3 env [option]... [NAME=VALUE]...

Container engine: the same engine as for the corresponding t3 run command. Use option -e (or T3_ENGINE) if necessary.

Container name: the same container name as for the corresponding t3 run command. Use option -n (or T3_NAME) if necessary.

Container environment variables: control the time zone inside the container, TYPO3 mode, PHP settings and Composer operation; see this table for details.

Use option NAME=VALUE to assign a value to a container environment variable. This option may appear multiple times.

Initial values can be assigned by command t3 run.

t3 composer

Executes a Composer command inside of a running TYPO3 container:

$ t3 composer [option]... COMPOSER_CMD [Composer option]...

Container engine: the same engine as for the corresponding t3 run command. Use option -e (or T3_ENGINE) if necessary.

Container name: the same container name as for the corresponding t3 run command. Use option -n (or T3_NAME) if necessary.

Composer command: the rest of the Composer command line. Composer is run in the context of the TYPO3 installation root in the container (/var/www/localhost), i.e. the root of the TYPO3 volume.

In order to keep Composer from overwriting changes you made in your working directory, set the container environment variable COMPOSER_EXCLUDE to a colon-separated list of subdirectories of /var/www/localhost which are to be excluded from changes made by Composer.

t3 mount

Mounts a working directory to a container volume so that the volume appears to be owned and can be managed by the current user:

$ t3 mount [--mount|-m] WORK_DIR [option]...

This is equivalent to t3 run with a working directory path for -v except that the container does not need to be running (it does not even have to exist).

This command will ask for sudo authorization unless there are cached credentials.

Container engine: the same engine as for the corresponding t3 run command. Use option -e (or T3_ENGINE) if necessary.

TYPO3 working directory: specify the working directory path (it must contain a /) for option -m. The directory basename is taken as the volume name, and the working directory is bind-mounted at that volume. This is equivalent to the -v option of t3 run except that no container is needed for this operation.

t3 unmount

Unmounts a working directory from the container volume:

$ t3 unmount [--unmount|-u] WORK_DIR [option]...

This command will ask for sudo authorization unless there are cached credentials.

Container engine: the same engine as for the corresponding t3 run command. Use option -e (or T3_ENGINE) if necessary.

TYPO3 working directory: specify the working directory path to unmount for option -u. This is what is done automatically by t3 stop.

Options

The following table shows which options are applicable to each command. It also indicates which host environment variable contains the default value for each option and which default value is used if that environment variable is not set.

Option Commands Description
--engine=ENGINE
-e ENGINE
all Container engine to use: docker, podman (can be) abbreviated, or an absolute path to the engine executable.
Default: $T3_ENGINE, or podman if installed, else docker.
-h
--help
none
all
Displays a list of commands, or help for the specified command.
--name=NAME
-n NAME
run
stop
composer
env
Container name. The database container name, if any, has -db appended to this name.
Default: $T3_NAME, or typo3.
--hostname=HOSTNAME
-h HOSTNAME
run Hostname assigned to the TYPO3 container and to Apache ServerName and ServerAdmin.
Default: $T3_HOSTNAME, or typo3.$(hostname).
--tag=TAG
-t TAG
run Tag of image to run, consisting of TYPO3 version and build version, e.g. 8.7-1.3 or 9.5-latest.
Default: $T3_TAG, or latest, i.e. the latest build for the most recent TYPO3 version.
--typo3-root=VOLUME
-v VOLUME
run Either a volume name to be mapped to the TYPO3 root directory inside the container, or a working directory path (containing a /).
In the latter case, the directory basename is used as the volume name, and the directory is bind-mounted at that volume. Thus, volume content appears to be owned by the current user.
Podman users please note: working directories require at least Podman v1.4.3.
Default: $T3_ROOT, or typo3-root.
--typo3-port=PORT
-p PORT
run Host interface (optional) and port where to publish the TYPO3 HTTP port.
Default: $T3_PORT, or 127.0.0.1:8080.
--db-type=TYPE
-d TYPE
run Type of database container: mariadb for MariaDB or postgresql for PostgreSQL (can be abbreviated). If empty then the SQLite instance of the TYPO3 container will be used.
Default: $T3_DB_TYPE, or empty.
--db-vol=VOLUME
-V VOLUME
run Database volume name; requires option --db-type.
Defaults: $T3_DB_DATA, or typo3-data.
--db-port=PORT
-P PORT
run Host interface (optional) and port where to publish the database port; requires option --db-type.
Defaults: $T3_DB_PORT, or 127.0.0.1:3306 for MariaDB and 127.0.0.1:5432 for PostgreSQL.
--rm run
stop
Causes the TYPO3 container and the respective database container (if one exists) to be removed after they were stopped.
--env NAME=VALUE run Sets the (initial) value of a container environment variable, eventually overriding the corresponding host environment variable. The values of most variables can be changed afterwards by t3 env.
This option may appear multiple times. --env options must be the last options on the command line.
--mount=WORKDIR
-m WORKDIR
mount Path of a working directory to bind-mount to a persistent volume. The basename of this path is taken as the name of the persistent volume.
--unmount=WORKDIR
-u WORKDIR
unmount Absolute path of the directory to unmount from a persistent volume.

Host environment variables

These variables can be set in the host shell and are intended for setting custom default values for options and container environment variables, thus establishing a consistent environment for all t3 commands.

Name Description Built-in default
T3_ENGINE Container engine to use: docker, podman (can be) abbreviated, or an absolute path to the engine executable. podman if installed, else docker
T3_NAME Container name. The database container name, if any, has -mariadb or -postgresql appended to this name. typo3
T3_HOSTNAME Hostname assigned to the TYPO3 container and to Apache ServerName and ServerAdmin. typo3.$(hostname)
T3_TAG Tag of image to run, consisting of TYPO3 version and build version, e.g. 8.7-1.3 or 9.5-latest. latest
T3_ROOT Volume name to be mapped to the TYPO3 root directory inside the container.
If an absolute directory path specified then its basename is used as the volume name; in addition, that directory is bind-mounted at the volume so that files and directories in that volume appear to be owned by the current user.
typo3-root
T3_PORT Interface (optional) and port where to publish the TYPO3 HTTP port. 127.0.0.1:8080
T3_DB_TYPE Type of database container: mariadb for MariaDB or postgresql for PostgreSQL (can be abbreviated). If empty then the SQLite instance of the TYPO3 container will be used. empty
T3_DB_DATA Database volume name; effective only if T3_DB_TYPE or --db-type is set. typo3-data
T3_DB_PORT Host interface (optional) and port where to publish the database port; effective only if T3_DB_TYPE or --db-type is set. 127.0.0.1:3306, or
127.0.0.1:5432
T3_DB_NAME Name of the TYPO3 database that is created automatically by t3 run. t3
T3_DB_USER Name of the TYPO3 database owner. t3
T3_DB_PW Password of the TYPO3 database. t3
T3_DB_ROOT_PW Password of the MariaDB root user. toor
T3_TIMEZONE
T3_MODE
T3_COMPOSER_EXCLUDE
T3_PHP_...
T3_php_...
Initial values for container environment variables TIMEZONE, MODE, COMPOSER_EXCLUDE, PHP_... and php_.... empty

Container environment variables

These variables can get their initial values from host environment variables or from the t3 run --env option; the --env option takes precedence.

Except for TIMEZONE, these variables can be set or changed at runtime by the t3 env command.

Name Description Built-in default
TIMEZONE Sets the TYPO3 container timezone (e.g. Europe/Vienna). Timezone of your current location, or else UTC.
MODE
prod
selects production mode: TYPO3 operating in „Production Mode“, no Apache/PHP signature headers, PHP settings as per php.ini-production
dev
selects development mode: TYPO3 in „Development Mode“, verbose Apache/PHP signature headers, PHP settings as recommended by php.ini-development
xdebug
selects development mode as above and also enables XDebug
prod
COMPOSER_EXCLUDE Colon-separated list of subdirectories of /var/www/localhost which are to be excluded from the effects of Composer operations.
This is intended e.g. to protect the current version of an extension you are developing from being overwritten by an older version stored in a repository.
These directories need to exist only by the time Composer is invoked.
empty
PHP_...
php_...
Environment variables prefixed with PHP_ or php_ become php.ini settings with the prefix removed, e.g. --env php_post_max_size=5M becomes post_max_size=5M. These settings override prior settings and MODE. none

Credits

TODO

Licenses

Scripts in this repository are licensed under the GPL 3.0.

This document is licensed under the Creative Commons license CC BY-SA 3.0.

As for any pre-built image usage, it is the image user's responsibility to ensure that any use of this image complies with any relevant licenses for all software contained within. More information on this subject may be found in this discussion.