Docker
https://github.com/docker/cli https://github.com/docker/compose
Docker is a platform for developing, shipping, and running applications in containers.
Vortex provides a configuration for Docker and Docker Compose to run the project in all environments using containers.
Special thanks to Lagoon for providing the container images that make this possible.
Lagoon images are production-grade and are used in production environments. They receive regular updates and are maintained by the Lagoon team.
If you are using Lagoon as your hosting provider, then all of your environments are using identical images to run the project.
About Docker and Docker Compose
Below is a brief overview of Docker and Docker Compose. For more information, see the official documentation.
Docker is a technology that allows to define services such as a web server or a database server as standalone containers, which are then run in an isolated environment and can talk to each other.
The containers are started from images - templates that define what is installed in the container and how it is configured. Images allow to run containers with consistent content and configuration.
Docker is an engine that runs containers, built from images, allowing them to
share host system resources and communicate to each other. When run locally,
Docker can be controlled with Docker CLI command, called docker
.
Docker Compose is a tool that allows to define and run multi-container Docker
applications in a single docker-compose.yml
file: multiple containers that
work together can be described in a single file, which makes it easier to
manage them.
When working with Drupal, which requires multiple service containers to run, a
developer would normally use Docker Compose CLI commands (rather than Docker CLI
commands) called docker compose
. Note that this
commands runs in the context of the current directory, so it is important to
run them from the project root directory. This means that the issued commands
will only affect the containers defined in the docker-compose.yml
file in the
current directory and will not affect any other containers running on the host.
When a project is fully configured, the usage of Docker-based application comes down to a handful of commands to manage the state of the containers (per project):
docker compose up -d
- start the containers in the background.docker compose down
- stop and remove the containers.docker compose exec <service>
- run a command in a running<service>
container.docker compose logs -f
- follow the logs of all the containers.docker compose ps
- list all running containers.
More advanced commands are normally used when adjusting the project Docker configuration and services.
Using Docker
Vortex uses Docker to run the project in a containerized environment locally and in CI.
Some of the commands are wrapped in the Ahoy script as a shorthand. But all
the commands can be run directly using docker compose
command.
Specific commands are described in the relevant workflows sections.
Understanding docker-compose.yml
Docker Compose reads the configuration from the docker-compose.yml
and
docker-compose.override.yml
files. The configuration files are written in
YAML, which support anchors and references
that help to reduce duplication.
The file provided by Vortex contains the following sections:
Volumes definitions
Volumes are used to share data between containers. If the host supports volume mounting, then the data can be shared between containers through the host, making it possible to access and modify the data from the host.
This is used during development to share the application code between the container and the host, so that the changes made on the host are immediately reflected in the running application.
There are 2 volumes defined:
- Project root directory
.
maps to/app
directory within a container. This is where a PHP engine accesses the application code. - Files directory
./web/sites/default/files
maps to/app/web/sites/default/files
directory within a container as an override to the default volume definition. This allows to use different type of syncing to optimise performance, because files are not changed as often as the code.
There are 2 more volumes defined and commented out - these are used in environments without volume mounting support, such as CircleCI. These volumes definitions are automatically uncommented in CI environment, and they replace the host volume mounting, which is removed.
VOLUME_FLAGS
environment variable allows to define the consistency of the data
within mounted volumes. The values are:
default
: Equivalent toconsistent
.consistent
: Full consistency. The container runtime and the host maintain an identical view of the mount at all times.cached
: The host's view of the mount is authoritative. There may be delays before updates made on the host are visible within a container.delegated
: The container runtime's view of the mount is authoritative. There may be delays before updates made in a container are visible on the host.
The default value is delegated
, so that any changes done in the container are
immediately visible on the host.
Default user
The default user is defined as 1000
- this is the user ID that is used in the
container to run the application. This is the same user ID as the host user, so
that the files created in the container are owned by the host user.
Changes this value if your user ID is different.
Environment variables
By default, the Docker Composer reads environment variables from the .env
file. Vortex provides an additional capability to read files from .env.local
file as well. This allows to override the environment variables locally without
modifying the .env
file.
The variables read from .env
and .env.local
files then passed into the
containers.
This section only defines 2 types of variables:
- Variables that are specific to the stack and require a default value (
like
LAGOON_ROUTE
). - Variables that cannot be stored in
.env
file and are injected from the actual environment (like secrets).
Any other variables should be defined in the .env
file.
Consider the example:
TZ: ${VORTEX_TZ:-Australia/Melbourne}
# Local development URL.
VORTEX_LOCALDEV_URL: &default-url ${COMPOSE_PROJECT_NAME:-example-site}.docker.amazee.io
# Local development route used in Lagoon images and Pygmy to route requests.
LAGOON_ROUTE: *default-url
where
TZ: ${VORTEX_TZ:-Australia/Melbourne}
- defines a variableTZ
with a default value ofAustralia/Melbourne
, but only ifVORTEX_TZ
variable is not defined.VORTEX_LOCALDEV_URL: &default-url ${COMPOSE_PROJECT_NAME:-example-site}.docker.amazee.io
- defines a variable
VORTEX_LOCALDEV_URL
with a default value of${COMPOSE_PROJECT_NAME:-example-site}.docker.amazee.io
, but only ifVORTEX_LOCALDEV_URL
variable is not defined. The value of the variable is also stored in a YAML anchordefault-url
for later use.
- defines a variable
LAGOON_ROUTE: *default-url
- defines a variableLAGOON_ROUTE
with a value of*default-url
, which is a reference to thedefault-url
YAML anchor defined above.
See more information about environment variables in the official documentation.
Services
Services section describes the configuration for each container.
The following services are defined in the docker-compose.yml
file provided by
Vortex:
cli
- a container that runs a shell. This container is used to run commands in the context of the project, such ascomposer
ordrush
. This is also a container where cron jobs are run within a hosting environment (if that environment supports containerisation).nginx
- a container that runs a web server. This container is used to serve the application and pass requests to the PHP container.php
- a container that runs a PHP engine. This container is used to run the application code and execute commands in the context of the application. It is different from thecli
container in that it does not have certain development dependencies installed, has a smaller size and is optimised for scalability.mariadb
- a container that runs a database server. This container is used to store the application data. It can be accessed from the host via a randomly assigned port - rundocker compose port mariadb 3306
to get the port number.redis
- an optional container that runs a Redis server. This container is used to store the application cache.solr
- an optional container that runs a Solr server. This container is used to store the application search index. It can be accessed from the host via a randomly assigned port - rundocker compose port solr 8983
to get the port number.clamav
- an optional container that runs a ClamAV antivirus server. This container is used to scan uploaded files for viruses.chrome
- container that runs a Chrome browser. This container is used to run Behat tests. It is based on the official Selenium image which has additional required tools, like virtual desktop, installed.
wait_dependencies
- a container that runs a script to wait for applications within other containers to become available. Docker itself can coordinate startup of containers, but it does not know when the application within the container is ready to accept connections. This container is used to wait for specified application ports to become available. The whole stack is considered ready to be worked with only when this container exits with a zero exit code.
Networks
Networks section defines the networks that are used to connect containers to
each other. Pygmy provides the default amazeeio-network
network
that
is used to connect all containers together.
Validate docker-compose.yml
After updating the docker-compose.yml
file, it is useful sometimes to validate
it before running the build. This can be done with the following command:
docker compose -f docker-compose.yml config