reach-digital / docker-devbox

reach-digital/docker-devbox

Reach Digital Docker+local hybrid development environment.

  • Paul Hachmang
magento2-component Compatibility: 2.4.7-2.4.9 Code Quality: Warning Tests: N/A Security: Pass Apache-2.0

🐳 Reach Digital Magento 2.4 Docker+local hybrid development environment. 🐳

Docker for services, PHP locally. No sync, no mental overhead, no performance
penalties.

Services included: php, nginx, https, http/2, varnish, mysql,
elasticsearch, rabbitmq, mailcrab.

PHP runs outside of Docker for optimal performance and being able to just run
your tooling (i.e. bin/magento) from your local terminal.

Due to Docker VMM's improved performance, we use bind mounts to share files for
the services that need it (nginx). We use guest-only volumes for services
that don't need to share data for optimal performance (mysql, elasticsearch,
etc.)

Goals

  • It should be possible for a frontend developer without any backend skills to
    easily set up a development environment.
  • It should be possible for a backend developer to add or upgrade services.
  • It should be possible for a backend developer to propagate the changes to the
    rest of the team with version control.

Principles

  • No magic: As few CLI tools that will automatically 'fix' things. Do not use
    wrappers around existing tools: docker / etc. Exception: php runs locally,
    needs to be set up.
  • Declarative: Developer should define the final state instead of running
    upgrade scripts (hence, docker).
  • Minimal: Use as few cpu cycles and memory as possible.

Requirements

  • Recent macOS
  • Recent Docker
  • Apple Silicon (for Docker VMM support)

Global installation (only once)

Cleanup your system

Since we're running some things locally it probably is a good time to clean some
stuff up.

  • Run brew doctor and make sure you don't have errors.
  • Run brew update to update to the latest version.

You should not have any services running like.

  • php: find them with brew list | grep php, uninstall them using
    brew uninstall —f <packages>. With the force flag you'll delete all
    installed versions of formula.
  • httpd:
    Disable apache
    that is OSX native. http://localhost/ should not return anything.
  • mysql: uninstall or disable mysql, or at least make sure it doesn't run on
    the default MySQL port.
  • nginx: uninstall

Take a look at ~/.bash_profile or ~/.zshrc and make sure it doesn't contain
any references to $BREW_PREFIX/Cellar/php*.

Installing PHP and php-fpm services

Since we're running a hybrid docker+local system we need to set up PHP to run
locally. An install.sh script is provided for this, which you can run locally
after cloning this repository.

For running the script directly, use:

# Cleans existing brew php (will not remove Valet stuff) + installs php on macOS
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/ho-nl/docker-development-box/master/install.sh)"

It will (re)install multiple php-fpm services, one for each version (port: 9072,
9073, 9074, etc.) and one for each version with xdebug (port: 9172, 9173, 9174, etc.).

Switching between PHP versions

You can switch between CLI PHP versions using brew link. For example to switch to 8.2:

brew unlink [email protected] && brew link --force --overwrite [email protected]

Should now show the right version (check with php -v). If it doesn't there might be still be a
version linked, or your ~/.bash_profile should be cleaned up, or you need to
reopen your CLI.

For easy switching between versions you can set up aliases like so:

alias link-php74='brew unlink [email protected] && brew link --force --overwrite [email protected]'
alias link-php81='brew unlink [email protected] && brew link --force --overwrite [email protected]'
alias link-php82='brew unlink [email protected] && brew link --force --overwrite [email protected]'
alias link-php83='brew unlink [email protected] && brew link --force --overwrite [email protected]'
alias link-php84='brew unlink [email protected] && brew link --force --overwrite [email protected]'

Install docker

  1. Install latest version of
    docker for mac.
  2. Start Docker
  3. Exclude ~/Library/Containers from your backups
  4. brew install ctop: can be used to show container metrics.
  5. Open Docker -> Settings -> Resources, set memory to 6-8 GB
  6. Open Docker -> Settings -> General, set virtual machine manager
    to Docker VMM

Install local certificate

  • Download the raw .pem file (Open Raw, then CMD + S):
  • ./hitch/*.localhost.reachdigital.io.pem
  • Open keychain.app, add this file (you can drag and drop this file in the keychain
    app, under the Login tab).
  • Open certificate and trust the certificate (do this by right-clicking on the entry,
    choosing 'Get Info', and choose 'Always trust' under the 'Trust' section)

You are now done with the global installation 🎉

Project installation

This covers initially adding docker-devbox support to a Magento project; if your project
already has docker-devbox support added, please refer to the projects' own README.

  • Install (and commit) this package in the project: composer require reach-digital/docker-devbox ^5.0.0
  • Install static-content-deploy patch and
    remove existing static symlinked content: rm -rf pub/static/*/*.
  • Copy the provided docker-compose.example.yml file to docker-compose.yml
    • When updating the docker-devbox package in the future, you may want to check changes in the example file to include in your project's copy.
  • Change docker-composer.yml as required for your project and commit this file as part of your project:
    • Change the FPM_PORT and FPM_XDEBUG variables for the nginx service for the correct PHP version
    • You should match the MySQL docker image version to that of your production environment
  • You can use env.php as a base for your local env.php, which is drop-in compatible with all docker
    services:
    • Change the crypt.key value (take this from an existing production environment, or from the initially generated env.php if this is an entirely new project)
    • Change the base URLs (system.default.web.*.base_url) as desired

Usage

  • Start: docker-compose up -d
  • Logging: ctop
  • Stop: docker-compose down

You now have all services set up 🎉. See individual services below to set urls,
caches, etc.

Deleting data (mysql/elasticsearch):

To delete the data for (for example) MySQL, stop your containers and remove
the associated docker volume:

docker-compose down
docker volume rm ${PROJECT_NAME}_mysql-mount
docker-compose up -d

You can use docker-compose volumes to see the volumes associated with your project.

Be sure to give MySQL a minute or two to re-initialize the data directory - during
this time it will not accept connections.

Usage and setup

Configuring Magento

Configuration for all the services is included in the example env.php

How do I use xdebug?

  • Web: Xdebug should work by default when you have the
    Xdebug Helper
    installed + PHPStorm is listening to connections.
  • Command line: you can add the following alias to your ~/.bash_profile or ~/.zshrc, this will auto-detect
    your active PHP version, and let you debug using something like phpd bin/magento ...:
    alias phpd="XDEBUG_SESSION=1 php -c \$(brew --prefix)/etc/php/\$(php -v | head -n1 | cut -c 5-7)/php-xdebug.ini"
    
  • Tests: Create a local interpreter in PhpStorm, the PHP version you're looking for should
    be suggested. Configure the 🐞 Xdebug path: to enable xdebug (from the output of the installation script). The path
    is something like /usr/local/Cellar/php/7.4.3/pecl/20190902/xdebug.so. You can look up your exact path in your php-xdebug.ini.

How do I set up my cron?

default setup

Where can I find logs?

  • For all other services, start ctop and press <- on your keyboard.
  • phplogs: tail -f `brew --prefix`/var/log/php* (will probably be empty as it will
    only output true errors)

How do I set up urls/https?

https only with hitch. The docker
container does not support http, only https.

bin/magento config:set --lock-env web/unsecure/base_url https://blabla.localhost.reachdigital.io/
bin/magento config:set --lock-env web/secure/base_url https://blabla.localhost.reachdigital.io/
# You can use any domain that points to 127.0.0.1, you can't use https://localhost because Magento can't handle that.
# *.localhost.reachdigital.io always resolves to 127.0.0.1

How do I set up multiple websites?

To allow our nginx setup to work with multiple websites we need change the
nginx environment parameter MAGE_RUN_TYPE from store to website

To define our website or storeview codes we have to add a new configuration
file, for example nginx-map.conf, to map$MAGE_RUN_CODE to the relevant
website_code or storeview_code.

map $http_host $MAGE_RUN_CODE {
    default '';
    example-dutch.localhost.reachdigital.io 'example_dutch';
    example-german.localhost.reachdigital.io 'example_german';
}

Add the file path to the nginx volumes, for example:

    volumes:
      - ./nginx-map.conf:/etc/nginx/conf.d/map.conf:ro

Your website or storeview should now be available.

For more information check the magento docs:
https://experienceleague.adobe.com/docs/commerce-operations/configuration-guide/multi-sites/ms-nginx.html

Managing Varnish

  • You can use bin/magento cache:clean or cache:flush to flush Varnish.
  • You can use CMD+SHIFT+R to bypass Varnish for any page.
  • You can use port 6082 and docker-devbox-varnish-secret as shared secret
    to connect with the Varnish management interface.

Managing Redis

To flush Redis directly when bin/magento is broken, run
docker-compose exec redis redis-cli flushall.

Using Mailcrab

The Mailcrab webinterface is available at http://localhost:8025/.

As of Magento 2.4.6, a third party SMTP delivery module is no longer required.

For Magento versions older than 2.4.6, see
https://github.com/ho-nl/docker-development-box/tree/741d193a68200c976cd13987a986d7063a984b1d?tab=readme-ov-file#how-do-i-set-up-mailhog

Using ngrok

Uncomment the ngrok service in your docker-compose.yml to use Ngrok. This
exposes your local environment to the public internet over secure tunnels.

http://localhost:4551
Update base urls with tunnel url shown on webpage.

You will need to register an account at https://ngrok.com/ and configure a
token to make use of this service:

  - PARAMS=http -region=eu --authtoken=<token> nginx:80

Connecting to contains through SSH

  1. Open up ctop
  2. ⮐ on your service
  3. exec shell

Please note that the containers are as minimal as possible, so not all common
tools are available, but you should be able to get around.

Customizing dockerized services

Everything is set up via the docker-compose.yml file. You see paths to the
configuration files used, various environment variables, and commandline
options there and can change these as needed for your project.

  1. Change the path to your custom configuration file.
  2. Run docker-compose down && docker-compose up -d
  3. Changes should be applied, check ctop if your container is able to start.

Restarting the php-fpm service

These run as macOS services (for each PHP version and with/without xdebug) on
the host, and can all be restarted with: pkill php-fpm

Commits

Commits are validated with https://github.com/conventional-changelog/commitlint

Gittower: Gittower doesn't properly read your PATH variable and thus commit
validation doesn't work. Use gittower . to open this repo.

Troubleshooting

The Compose file './docker-compose.yml' is invalid

ERROR: The Compose file './docker-compose.yml' is invalid because: Unsupported config option for services.mailhog: 'platform'

Please update Docker to fix this error. This error happens because your Docker version
is too low and does not support the platform option. This option is used in recent
versions of docker-development-devbox to enable support for both Intel and Apple
Silicon macbooks.

docker-composer and/or ctop are not able to connect to the Docker daemon

ERROR: Couldn't connect to Docker daemon. You might need to start Docker for Mac.

This may happen if you've upgraded from an old version of Docker. In more recent
versions of docker, the socket file through which one can connect with the deamon
was moved to ~/.docker/run/docker.sock. Programs like ctop and
docker-composer use the symlink at /var/run/docker.sock which may still point
to the old path.

To correct this, run the following:

sudo ln -sf ~/.docker/run/docker.sock /var/run/docker.sock

Changelog

All notable changes to this project will be documented in this file, in reverse
chronological order by release.

The format is based on Keep a Changelog,
and this project adheres to
Semantic Versioning.

[HEAD]

Added

  • Varnish bypass for blackfire.io
  • Install: Added zsh support
  • Magento: Added static-content-deploy relative symlink patch.

Changed

  • Revert: Mysql: Disable stats for SHOW TABLE STATUS to improve performance.
  • Install: Cleaned output of install script
  • Install: Hide launchctl unload warning
  • Install: Better success message

[1.0.0-preview.1] - 2020-02-25

Changed

  • Updated README to make installation more clear.
  • Mysql: Disable stats for SHOW TABLE STATUS to improve performance.

[1.0.0-preview.0] - 2020-02-24

Added

  • Initial Release of the 🐳 Reach Digital Magento 2 Docker+local hybrid
    development environment. 🐳
    : Docker for services, php locally. No sync, no
    mental overhead, no performance penalties.
  • Supported srevices: php, nginx, https, http/2, varnish, mysql,
    elasticsearch, rabbitmq, mailhog
Versions
Version Stability QA Status Compatibility Released
5.0.2 stable Pass Magento 2.4.7-2.4.9 Details 2025-12-18 12:58:09
5.0.1 stable Not tested Not yet tested Details 2025-08-06 13:15:09
5.0.0 stable Not tested Not yet tested Details 2025-08-06 11:15:09
4.4.0 stable Not tested Not yet tested Details 2025-07-01 09:25:01
4.3.2 stable Not tested Not yet tested Details 2025-02-04 11:07:57
4.3.1 stable Not tested Not yet tested Details 2025-02-03 08:42:14
4.3.0 stable Not tested Not yet tested Details 2025-01-10 15:13:02
4.2.0 stable Not tested Not yet tested Details 2024-07-16 09:44:00
4.1.1 stable Not tested Not yet tested Details 2023-11-22 14:59:09
4.1.0 stable Not tested Not yet tested Details 2023-11-21 07:15:01
4.0.0 stable Not tested Not yet tested Details 2023-10-24 10:28:48
3.17.1 stable Not tested Not yet tested Details 2023-10-13 06:47:08
3.17.0 stable Not tested Not yet tested Details 2023-08-28 09:25:05
3.16.0 stable Not tested Not yet tested Details 2023-08-15 09:37:30
3.15.0 stable Not tested Not yet tested Details 2023-07-05 12:45:50
3.14.0 stable Not tested Not yet tested Details 2023-06-19 08:35:02
3.13.0 stable Not tested Not yet tested Details 2023-05-31 13:04:25
3.12.0 stable Not tested Not yet tested Details 2023-03-23 10:38:09
3.11.0 stable Not tested Not yet tested Details 2023-02-14 07:39:20
3.10.0 stable Not tested Not yet tested Details 2022-11-22 10:34:22
2.1.0 stable Not tested Not yet tested Details 2022-06-01 12:58:51
3.9.0 stable Not tested Not yet tested Details 2022-06-01 12:26:33
2.0.8 stable Not tested Not yet tested Details 2021-11-04 12:46:38
3.8.0 stable Not tested Not yet tested Details 2021-11-04 12:45:53
3.7.1 stable Not tested Not yet tested Details 2021-10-26 10:35:23
3.7.0 stable Not tested Not yet tested Details 2021-10-25 13:06:35
3.6.0 stable Not tested Not yet tested Details 2021-10-25 12:08:46
3.5.0 stable Not tested Not yet tested Details 2021-07-29 09:24:43
3.4.1 stable Not tested Not yet tested Details 2021-04-01 14:33:42
3.4.0 stable Not tested Not yet tested Details 2021-03-26 07:21:49
3.3.0 stable Not tested Not yet tested Details 2021-03-11 15:22:12
3.2.0 stable Not tested Not yet tested Details 2021-01-29 13:19:36
3.1.3 stable Not tested Not yet tested Details 2020-12-04 12:46:12
3.1.2 stable Not tested Not yet tested Details 2020-12-04 10:34:48
3.1.1 stable Not tested Not yet tested Details 2020-12-04 10:33:44
3.1.0 stable Not tested Not yet tested Details 2020-12-02 10:31:49
3.0.2 stable Not tested Not yet tested Details 2020-11-05 11:19:44
2.0.7 stable Not tested Not yet tested Details 2020-10-02 12:39:45
3.0.1 stable Not tested Not yet tested Details 2020-10-02 12:36:00
3.0.0 stable Not tested Not yet tested Details 2020-09-30 08:47:15
2.0.6 stable Not tested Not yet tested Details 2020-09-23 07:52:27
2.0.5 stable Not tested Not yet tested Details 2020-09-04 10:51:34
v2.0.4 stable Not tested Not yet tested Details 2020-09-01 13:30:21
2.0.3 stable Not tested Not yet tested Details 2020-09-01 13:23:34
2.0.2 stable Not tested Not yet tested Details 2020-06-18 13:40:15
2.0.1 stable Not tested Not yet tested Details 2020-06-08 09:10:44
2.0.0 stable Not tested Not yet tested Details 2020-06-05 10:25:20
1.1.1 stable Not tested Not yet tested Details 2020-06-04 08:10:17
1.1.0 stable Not tested Not yet tested Details 2020-06-03 08:10:43
1.0.0 stable Not tested Not yet tested Details 2020-06-03 08:05:13
1.0.0-preview.1 stable Not tested Not yet tested Details 2020-02-25 10:54:06
1.0.0-preview.0 stable Not tested Not yet tested Details 2020-02-24 12:50:32

Requires 1

Package Constraint
magento/magento-composer-installer *

Compatibility

Each Magento release line is installed on its supported PHP versions, then the module is built (DI compilation + static-content deploy) and its unit and integration suites are run. The matrix shows the lines and PHP versions the module is confirmed to install and run on. Code-quality results further down (phpstan, phpcs, …) are reported separately and never affect compatibility.

Compatibility matrix (Magento × PHP)
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 Pass Pass
2.4.8 Pass Pass
2.4.9 Pass Pass

Code Quality

Advisory checks against the module's source. Static analysis runs once across the whole module; PHPStan re-runs per Magento + PHP version because resolvable symbols differ between releases. These NEVER affect the Compatibility badge — a phpcs finding can't make a module incompatible.

Static analysis

Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.

Static analysis results
Tool Status Findings Summary
PHPCS Warning 1 1 warning (ruleset: Magento2)
PHPMD Pass 0
Cpd Pass 0
Composer validate Info 1 valid; 1 advisory note (composer validate --strict)

PHPStan

Type-checks the module's PHP against a real Magento install at the configured gate level. Re-runs per Magento and PHP version because resolvable symbols differ between releases. Cell → details modal.

PHPStan results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 Pass Pass
2.4.8 Pass Pass
2.4.9 Pass Pass

Tests

Unit and integration suites, run for each applicable Magento and PHP version. A test failure speaks to the module's behaviour, not its compatibility with a Magento line, so it is reported here separately and never reddens the compatibility matrix.

Unit tests

Unit tests results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 N/A N/A
2.4.8 N/A N/A
2.4.9 N/A N/A

Integration tests

Integration tests results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 N/A N/A
2.4.8 N/A N/A
2.4.9 N/A N/A

Security

Security checks run directly against the module: an audit of its declared dependencies for known vulnerabilities (composer audit) and a scan of its source for malware and web-shell signatures. Each runs once. A malware detection fails the version outright.

Security results
Tool Status Findings Summary
Composer audit Pass 0
Malware scan Pass 0
License
Apache-2.0
Authors

More from reach-digital

View vendor
Make it pay

Turn an existing module into recurring revenue.

If you already maintain a Magento 2 module on GitHub or GitLab, listing it on Packagento takes about five minutes. We mirror your tags, handle distribution signing, and route paid licenses through Stripe Connect, so you can keep shipping the way you already do.