Warden is a CLI utility for orchestrating Docker developer environments, and enables multiple local environments to run simultaneously without port conflicts via the use of a few centrally run services for proxying requests into the correct environment's containers. Under the hood, docker-compose is used to to control everything which Warden runs (shared services as well as per-project containers) on Docker Engine.
- Homebrew package manager (for installing Warden and other dependencies)
- Docker for Mac or Docker for Linux (tested on Fedora 29 and Ubuntu 18.10)
docker-composeavailable in your$PATH(included with Docker for Mac, can be installed viabrew,aptordnfon Linux)- Mutagen v0.9.0 or later installed via Homebrew (required on macOS only; Warden will attempt to install this via
brewif not present when runningwarden sync start).
Warning: By default Docker Desktop allocates 2GB memory. This leads to extensive swapping, killed processed and extremely high CPU usage during some Magento actions, like for example running sampledata:deploy and/or installing the application. It is recommended to assign at least 6GB RAM to Docker Desktop prior to deploying any Magento environments on Docker Desktop. This can be corrected via Preferences -> Advanced -> Memory. While you are there, it wouldn't hurt to let Docker have the use of a few more vCPUs (keep it at least 4 less than the maximum CPU allocation however to avoid having macOS contend with Docker for use of cores)
pvinstalled and available in your$PATH(you can install this viabrew install pv) for use sending database files towarden db importand providing determinate progress indicators for the import. Alternativelycatmay be used wherepvis referenced in documentation but will not provide progress indicators.
Warden may be installed via Homebrew on both macOS and Linux hosts:
brew install davidalger/warden/warden
warden up
Alternatively Warden may also be installed by cloning the repository to the directory of your choice and adding it to your $PATH:
sudo mkdir /opt/warden
sudo chown $(whoami) /opt/warden
git clone -b master https://github.com/davidalger/warden.git /opt/warden
echo 'export PATH="/opt/warden/bin:$PATH"' >> ~/.bashrc
PATH="/opt/warden/bin:$PATH"
warden up
- Traefik for SSL termination and routing/proxying requests into the correct containers.
- Portainer for quick visibility into what's running inside the local Docker host.
- Dnsmasq to serve DNS responses for
.testdomains eliminating manual editing of/etc/hosts - An SSH tunnel for connecting from Sequel Pro or TablePlus into any one of multiple running database containers.
- Warden issued wildcard SSL certificates for running https on all local development domains.
- Full support for both Magento 1, Magento 2, and custom per-project environment configurations on macOS and Linux.
- Ability to override, extend, or setup completely custom environment definitions on a per-project basis.
After running warden up for the first time following installation, the following URLs can be used to interact with the UIs for services Warden runs globally:
The custom base images used by Warden environments can be found on Docker Hub or on Github: https://github.com/davidalger/docker-images-warden
In addition to these custom base images, Warden also utilizes official images such as redis, rabbitmq and mailhog for example.
Warden currently supports three environment types. These types are passed to env-init when configuring a project for local development for the first time. This list of environment types can also be seen by running warden env-init --help on your command line.
localThis environment type does nothing more than declare thedocker-composeversion and declare the externalwardennetwork which Traefik uses to proxy requests into the project's containers. When this is used, a.warden/warden-env.ymlmay be placed in the root directory of the project workspace to define the desired containers, volumes, etc needed for the project. An example of alocalenvironment type being used can be found in the m2demo project.magento2Provides the necessary containerized services for running Magento 2 in a local development context including Nginx, Varnish, php-fpm (PHP 7.0+), MariaDB, Elasticsearch, RabbitMQ and Redis. In order to achieve a well performing experience on macOS, source files are synced into the container using a Mutagen sync session (pub/mediaremains mounted using a delegated mount).magento1Supports development of Magento 1 projects, launching containers for Nginx, php-fpm (PHP 5.5, 5.6 or 7.0+), MariaDB and Redis. Files mounted using delegated mount on macOS and natively on Linux.
All environment types (other than local) come pre-configured with a mailhog container, with fpm services configured to use mhsendmail to ensure outbound email does not inadvertently send out, and allows for simpler testing of email functionality on projects. There are also two fpm containers, php-fpm and php-debug (more on this later) to provide Xdebug support enabled via nothing more than setting the XDEBUG_SESSION cookie in your browser to direct the request to the php-debug container.
For full details and a complete list of variables which may be used to adjusting things such as PHP or MySQL versions (by setting them in the project's .env file), and to see the docker-compose definitions used to assemble each environment type, look at the contents of the environments directory in this repository. Each environment has a base configuration YAML file, and optionally a darwin and linux-gnu file which add to the base definitions anything specific to a given host architecture (this is, for example, how the magento2 environment type works seamlessly on macOS with Mutagen sync sessions while using native filesystem mounts on Linux hosts). This directory also houses the configuration used for starting Mutagen sync sessions on a project via the warden sync start command.
The below example demonstrates the from-scratch setup of the Magento 2 application for local development. A similar process can easily be used to configure an environment of any other type. This assumes that Warden has been previously started via warden up as part of the installation procedure.
-
Create a new directory on your host machine at the location of your choice and then jump into the new directory to get started:
mkdir -p ~/Sites/exampleproject cd ~/Sites/exampleproject -
From the root of your new project directory, run
env-initto create the.envfile with configuration needed for Warden and Docker to work with the project.warden env-init exampleproject magento2The result of this command is a
.envfile in the project root (tip: commit this to your VCS to share the configuration with other team members) having the following contents:WARDEN_ENV_NAME=exampleproject WARDEN_ENV_TYPE=magento2 TRAEFIK_DOMAIN=exampleproject.test TRAEFIK_SUBDOMAIN=app -
Sign an SSL certificate for use with the project (the input here should match the value of
TRAEFIK_DOMAINin the above.envexample file):warden sign-certificate exampleproject.test -
Next you'll want to start the project environment:
warden env up -d warden sync start ## Omit this if running on a Linux host (or if not used by env type)If you encounter an error about
Mounts denied…, follow the instructions in the error message and runwarden env up -dagain. -
Drop into a shell within the project environment. Commands following this step in the setup procedure will be run from within the
php-fpmdocker container this launches you into:warden shell -
If you already have Magento Marketplace credentials configured, you may skip this step (
~/.composer/on the host is mounted into the container to share composer cache between projects, and has the effect of persisting theauth.jsonon the host machine as well):Note: To locate your authentication keys for Magento 2 repository, reference this page on DevDocs.
composer global config http-basic.repo.magento.com <username> <password> -
Initialize project source files using composer create-project and then move them into place:
composer create-project --repository-url=https://repo.magento.com/ \ magento/project-community-edition /tmp/exampleproject 2.3.x rsync -a /tmp/exampleproject/ /var/www/html/ rm -rf /tmp/exampleproject/ -
Install the application and you should be all set:
## Run application install process bin/magento setup:install \ --backend-frontname=backend \ --amqp-host=rabbitmq \ --amqp-port=5672 \ --amqp-user=guest \ --amqp-password=guest \ --db-host=db \ --db-name=magento \ --db-user=magento \ --db-password=magento \ --http-cache-hosts=varnish:80 \ --session-save=redis \ --session-save-redis-host=redis \ --session-save-redis-port=6379 \ --session-save-redis-db=2 \ --session-save-redis-max-concurrency=20 \ --cache-backend=redis \ --cache-backend-redis-server=redis \ --cache-backend-redis-db=0 \ --cache-backend-redis-port=6379 \ --page-cache=redis \ --page-cache-redis-server=redis \ --page-cache-redis-db=1 \ --page-cache-redis-port=6379 ## Generate an admin user ADMIN_PASS="$(cat /dev/urandom | base64 | head -n1 | sed 's/[^a-zA-Z0-9]//g' | colrm 17)" ADMIN_USER=localadmin bin/magento admin:user:create \ --admin-password="${ADMIN_PASS}" \ --admin-user="${ADMIN_USER}" \ --admin-firstname="Local" \ --admin-lastname="Admin" \ --admin-email="${ADMIN_USER}@example.com" printf "u: %s\np: %s\n" "${ADMIN_USER}" "${ADMIN_PASS}" -
Launch the application in your browser:
Note: To completely destroy the exampleproject environment we just created, run warden env down -v to tear down the project's Docker containers, volumes, etc, then warden sync stop as needed to terminate the Mutagen session.
Further information on customizing or extending an environment is forthcoming. For now, this section is limited to very simple and somewhat common customizations.
To configure your project with a non-default PHP version, add the following to the project's .env file and run warden env up -d to re-create the affected containers:
PHP_VERSION=7.2
The versions of MariaDB, Elasticsearch, Varnish, Redis, and NodeJS may also be similarly configured using variables in the .env file:
MARIADB_VERSIONELASTICSEARCH_VERSIONREDIS_VERSIONVARNISH_VERSIONRABBITMQ_VERSIONNODE_VERSION
The following variables can be added to the project's .env file to enable additional database containers for use with the Magento 2 (Commerce Only) split-database solution.
WARDEN_SPLIT_SALES=1WARDEN_SPLIT_CHECKOUT=1
If you need multiple domains pointing to the same server, you can follow the instructions below. In this example, we're going to add both an additional subdomain for an existing domain as well as add a couple of additional domains.
-
Sign certificates for your new domains:
warden sign-certificate exampleproject2.test warden sign-certificate exampleproject3.test -
Create a
.warden/warden-env.ymlfile with the contents below (this will be additive to the docker-compose config Warden uses for the env, anything added here will be merged in, and you can see the complete config usingwarden env config):version: "3.5" services: varnish: labels: traefik.frontend.rule: Host:${TRAEFIK_HOST_LIST} -
Add a comma-separated list of domains to the
.envfile (we're going to assume you want to continue to use theapp.exampleproject.testdomain for your primary application, so we're including that in the list):TRAEFIK_HOST_LIST=app.exampleproject.test,subdomain.exampleproject.test,exampleproject2.test,exampleproject3.test -
Run
warden env up -dto update the containers then each of the URLs should work as expected. It will be up to you to ensure your application properly handles traffic coming from each of those domains (by editing the nginx configuration or your application).
Drop into a shell within the project environment (this command opens a bash shell in the php-fpm container)
warden shell
Stopping a running environment (on linux, drop the sync command, it's not used on Linux)
warden env stop && warden sync stop
Starting a stopped environment (on linux, drop the sync command, it's not used on Linux)
warden env start && warden sync start
Watch the database processlist:
watch -n 3 "warden db connect -A -e 'show processlist'"
Tail environment access logs:
warden env logs --tail 0 -f nginx php-fpm php-debug
Tail the varnish activity log:
warden env exec -T varnish varnishlog
Run warden help and warden env -h for more details and useful command information.
There are two docker containers running FPM, php-fpm and php-debug. The php-debug container has the Xdebug extension pre-installed. Nginx will automatically route requests to the php-debug container when the XDEBUG_SESSION cookie has been set to PHPSTORM via the Xdebug Helper browser extension.
Xdebug will automatically connect back to the host machine on port 9000 for each request routed to the php-debug container (i.e. when the XDEBUG_SESSION cookie is set). When configuring Xdebug Helper in your browser, make sure it is setting this cookie with the value PHPSTORM. When it receives the first request, PHP Storm should prompt you if the "Server" configuration is missing. The below image demonstrates how this is setup; the important settings are these:
- Name:
clnt-docker(this is the value of theWARDEN_ENV_NAMEvariable in the.envfile appended with a-dockersuffix) - Host:
127.0.0.1 - Port:
80 - Debugger: Xdebug
- Use path mappings must be enabled, with a mapping to link the project root on the host with
/var/www/htmlwithin the container.
For information on what Blackfire is, please see the introduction to Blackfire in Blackfire documentation.
Blackfire may be enabled on both magento1 and magento2 env types by adding the following to the project's .env file (or exporting them to environment variables prior to starting the environment):
WARDEN_BLACKFIRE=1
BLACKFIRE_CLIENT_ID=<client_id>
BLACKFIRE_CLIENT_TOKEN=<client_token>
BLACKFIRE_SERVER_ID=<server_id>
BLACKFIRE_SERVER_TOKEN=<server_token>
Note: You can obtain the IDs and Tokens used in the above from within your Blackfire account under Account Settings -> Credentials or from the credentials are of the environment you're pushing profile information into.
For information what Magento Functional Testing Framework is - please follow to MFTF DevDocs.
MFTF is part of Magento 2. To run tests you need Selenium instance with Chrome Webdriver. Warden provides Docker setup that contains Selenium Standalone with Chrome. You can enable it by adding the following to the project's .env file (or exporting them to environment variables prior to starting the environment):
WARDEN_SELENIUM=1After generating MFTF configuration files (dev/tests/acceptance/.env generated by vendor/bin/mftf setup:env command), you need to provide selenium hostname:
SELENIUM_HOST=selenium-chrome
BROWSER=chromeTo preview the process of testing, you need any VLC client that provides SSH Tunnel support (eg. Remmina). To preview the process of testing, you need to use tunnel.warden.test:2222 (login: user):
This work is licensed under the MIT license. See LICENSE file for details.
This project was started in 2019 by David Alger.