Another development environment for Magento on Docker and Docker Compose, that is simple by default, yet still feature-rich.
- Wide range of supported PHP versions (5.6, 7.0, 7.1, 7.2, 7.3, 7.4)
- Pre-built images, as well as customizable source code
- Using NGINX + FastCGI
- MySQL storage using internal Docker volume, as well as user directory
- Support for non-standard HTTP ports
- Well-integrated with Composer
- Support for legacy Magento
- Built-in XDebug extension
- Optional proxying through third-party services
- PHP's mail function to use any SMTP server
- Built-in NodeJS for assets compilation
- Easy setup using .env file
- Third-party services examples
- PHPMyAdmin
- Varnish
- Redis
- Elasticsearch
- Mailcatcher
- Flexible and highly customizable
This environment mounts Magento directory within containers to make it easy to work on. It can be used either with existing installation of Magento or with a fresh directory to initialize new project.
-
Clone this repository anywhere you want. It's good practice to use every clone of the repo for each project, as it may contain settings corresponding to a single Magento installation.
-
Copy .env.example file to .env.
-
Edit .env file to configure your installation. All variables that are uncommented by default are required or recommended (apart from
COMPOSER_AUTH
). -
Make sure you have existing directories for Composer and NPM cache (
~/.composer/cache
,~/.npm
) or point them to your custom directories in .env. -
Make sure your
~/.ssh
directory exists. -
Optionally validate your configuration by executing script in the environment's root directory
./validate.sh
-
If you want to use pre-built docker images (recommended), you need to pull them from Docker Hub
docker-compose pull
If you want to build images by yourself, type
docker-compose build
-
Finally run the environment
docker-compose up
-
Optionally, copy docker-compose.custom.yml.example to docker-compose.custom.yml, uncomment some services or write your own and run
docker-compose -f docker-compose.yml -f docker-compose.custom.yml up
The best way to figure out how the environment with all its features work, is to examine docker-compose.yml and images source files (docker/mariadb, docker/nginx, docker/php). The most important thing to know is that, by default, it uses three services responsible for different tasks:
app
container - includes PHP interpreter with extensions that Magento requires, PHP-FPM daemon for web server, tools such as Composer, NodeJS & NPM for assets building and some configurations to make custom features work.web
container - includes NGINX web server configured for Magento.db
container - includes MariaDB database server with configuration to support flexible variable storage placement.
-
COMPOSE_PROJECT_NAME
: Variable used by Docker Compose. Indicates the prefix for all Docker objects like containers, images and networks. Should be unique for a given project. Interfering project names will make the environment unable to initialize. -
UID
andGID
: Unix user and group identificators for new processes that may modify data in user directory. Should be the same as for the current user. You can check that usingid -u # for UID id -g # for GID
-
PHP_VERSION
: Self explanatory. Can be one of:- 5.6
- 7.0
- 7.1
- 7.2
- 7.3
- 7.4
-
MAGENTO_PATH
: Application directory. The path should be in UNIX format, though it can be relative or absolute. The directory may contain Magento files or be empty for new project init. When using default mode, the/pub
subdirectory will be used as a web server document root. When usingMAGENTO_1_MODE
, the directory will be document root itself. -
HTTP_EXTERNAL_PORT
: A port number to use for the HTTP daemon. The value may contain an integer, as well as the address with port in case you want to bind on different interface (by default 0.0.0.0 is used, so that the server listens on all interfaces). For instance, you can limit it to just the localhost (127.0.0.1:80
) or to local area network (192.168.1.1:80
).
-
MYSQL_ROOT_PASSWORD
,MYSQL_USER
,MYSQL_PASSWORD
,MYSQL_DATABASE
: Settings for the database server. Oncedb
container is initialized, those values should not be changed, unless you plan to reinitialize MariaDB by deleting its files. -
MYSQL_HOST
(optional): You can use different database server providing a hostname. Note that the host must be accessible from theapp
container. -
MYSQL_USER_DIRECTORY
(optional): If set,db
container will use provided path as variable storage for MariaDB server. This should be a UNIX-formatted path, and the directory has to exist and be writable by the current user. The database server daemon process will run on specifiedUID
andGID
permissions, so generated files will have the correct ownership and group.
-
COMPOSER_AUTH_FILE
(optional): JSON formatted file path to be mounted inside theapp
container to provide authentication credentials for Composer. See more here: https://getcomposer.org/doc/articles/http-basic-authentication.md -
COMPOSER_AUTH
(optional): Instead of providing a file path, you may want to save the credentials directly in the .env file. The value should be a valid JSON inline string. -
COMPOSER_INSTALL_ON_BOOT
(optional): When set to true, thecomposer install
command will be automatically triggered when theapp
container is starting.
You may want to customize some of the mounted directories - for example you may want to use a separate Composer cache directory for single Magento project, or avoid mounting your ~/.ssh
folder by providing /dev/null
instead. You can change those using following variables:
SSH_DIRECTORY
NPM_DIRECTORY
COMPOSER_CACHE_DIRECTORY
By default, the app
container entrypoint will try to guess how you run your environment. If host.docker.internal
hostname can be resolved, it will be used. Unfortunately, this doesn't work the same with every Docker Engine implementation, and for now, it will only work this way on MacOS. If it's not resolvable, connect_back
mechanism will be used - which only works on Docker on Linux. Though connection target can be customized using following vars:
-
XDEBUG_REMOTE_HOST
(optional): Target IP address of the host you're running your debugger at. This IP has to be reachable from the container. You may need to check your firewall settings if you're sure that's the correct address, but XDebug still can't connect. -
XDEBUG_REMOTE_PORT
(optional): By default it's 9000, but you can use any available port you like.
When using XDebug from container, you will also need to configure paths mapping in your debugger. Inside the container, the app root that points to MAGENTO_PATH
is /app
.
This feature enables proxying HTTP traffic to your Magento instance through a third-party service. It can be useful when there's a need to test if a custom module behaves well with full page cache (like Varnish), or you want to use a debugging or monitoring tool. The idea is to point where the HTTP traffic has to go and then, on external service, go back to the web
container. Specifically, additional service has to proxy again to http://web:58080
in order to make it work.
PROXY_THOROUGH
(optional): HTTP URL to use as a proxy. The service that it points must be reachable by theweb
container. If you want to use Varnish service definition fromdocker-compose.custom.yml.example
, this value can behttp://varnish
.
You might need to test outgoing emails, e.g. while coding a custom message template. Magento uses PHP's mail function, which then calls system command (by default it's sendmail
) to send the message. The environment uses MSMTP client allowing you to use any SMTP server for the delivery. The docker-compose.custom.yml.example
contains Mailcatcher service, which is very convenient, because it catches every single email, no matter where it's being sent. Some external SMTP servers like Mailtrap.io can be used as well.
The configuration will be set in the container only if the SENDMAIL_SMTP_HOST
is defined.
SENDMAIL_SMTP_HOST
(optional): Can be a name of docker-compose service or any external host name/IPSENDMAIL_SMTP_PORT
(optional): SMTP server port number. Default: 25SENDMAIL_SMTP_AUTH
(optional): Can be 'on' or 'off'. Default: offSENDMAIL_SMTP_TLS
(optional): Can be 'on' or 'off'. Default: offSENDMAIL_SMTP_USER
(optional): SMTP username. Default: userSENDMAIL_SMTP_PASSWORD
(optional): SMTP password. Default: passwordSENDMAIL_SMTP_FROM
(optional): Default: magento@internal.app
For common tasks like Composer package management or dealing with Magento configuration, we use CLI interface. We need to do that from within the container in order to use the proper PHP version, access the database and use the same PHP configuration as the Magento accessed through the web server. For the sake of simplicity, we only talk to the app
container.
You can run bash session inside app container with a simple call
docker-compose exec app bash
Or you can run every command directly by replacing bash
with whatever you want. By default, it will always use the defined MAGENTO_PATH
as a working directory. For example you can run every Magento CLI command by calling
docker-compose exec app php bin/magento ...
docker-compose exec -T app mysql < /path/to/file.sql
docker-compose exec -T app mysqldump db-name> /path/to/file.sql
The app
container has both node
and npm
commands available. Currently, it uses NodeJS v12 LTS.
docker-compose exec app npm i # install Node modules
docker-compose exec app node_modules/grunt/bin/grunt watch # run a Grunt task