DEV Community

Cristiano Pacheco for run_as_root GmbH

Posted on

Configuring a docker environment for a Magento 2 project

This post will demonstrate how to configure a docker environment with the Warden tool for an existing Magento 2 project.

Table of contents

What is Warden?

Warden is a CLI utility for orchestrating Docker-based developer environments that fully support Magento 1, Magento 2, Laravel, Symfony, and Shopware 6 on macOS, Linux and Windows (via WSL2).

Why Warden?

  • Warden lets you run multiple environments simultaneously without conflicting ports.
  • Allows you to configure stack versions easily via .env file configuration.
  • Provides the full stack needed for a Magento 2 development environment.
  • You can extend it and add new features according to your needs.
  • No need to version the docker environment in the project.

Quickstart

We will configure two Magento 2 projects, the first project will have one website and one store view, and the second project will have multiple websites and store views.

The commands exposed here will work in Linux or macOS environment.

We will use the ~/Sites directory to place the projects. Feel free to put your project in any path on your computer if you change the commands informed here.

For each project, the following directory structure will be used:



📦project-name
 ┣ 📂code-base
 ┗ 📂docker


Enter fullscreen mode Exit fullscreen mode
  • The project-name/code-base directory will contain the Magento 2 project code
  • The project-name/docker directory will contain the warden template for our docker environment

Note: The structure above is just a personal taste to use in my projects, you can structure as you see fit. For example using the ~/.warden directory

Your Magento 2 project can be versioned alone in the repository, and there is no need to change the directory architecture.

Here we'll use a fork of the Warden Magento 2 Template that have a Makefile and a few common commands to facilitate the day-to-day work.

Requirements

All you need is Docker, docker-compose and Warden installed on your computer.

Project Stack:

For a practical example, we will set up the development environment for an existing Magento 2 project with the stack below:

  • Magento 2.4.4 open source
  • Nginx 1.16
  • PHP 8.1
    • Composer 2
    • Xdebug 3
  • MariaDB 10.4
  • Elastic Search 7.16
  • Redis 6.2
  • RabbitMQ 3.9

More details about the required stack for Magento 2 here.

Configuring a single website/store Magento 2 project

1 Creating the project folder


mkdir ~/Sites/magento244


Enter fullscreen mode Exit fullscreen mode
2 Enter the created directory


cd ~/Sites/magento244


Enter fullscreen mode Exit fullscreen mode
3 Clone the Magento 2 code-base into the code-base folder


git clone git@github.com:cristiano-pacheco/magento244.git code-base


Enter fullscreen mode Exit fullscreen mode
4 Clone the Warden Magento 2 template


git clone git@github.com:cristiano-pacheco/warden-env-magento2.git docker


Enter fullscreen mode Exit fullscreen mode
5 Update the warden .env file

Enter the docker directory



cd ~/Sites/magento244/docker


Enter fullscreen mode Exit fullscreen mode

Update the .env file with the content below:



WARDEN_ENV_NAME=magento244
WARDEN_ENV_TYPE=magento2
WARDEN_WEB_ROOT=/../code-base

TRAEFIK_DOMAIN=magento244.test
TRAEFIK_SUBDOMAIN=app

WARDEN_DB=1
WARDEN_ELASTICSEARCH=1
WARDEN_VARNISH=0
WARDEN_RABBITMQ=1
WARDEN_REDIS=1

ELASTICSEARCH_VERSION=7.16
MARIADB_VERSION=10.4
NODE_VERSION=10
PHP_VERSION=8.1
PHP_XDEBUG_3=1
COMPOSER_VERSION=2
RABBITMQ_VERSION=3.9
REDIS_VERSION=6.2
VARNISH_VERSION=7.0

MYSQL_USER=magento
MYSQL_PASSWORD=magento
MYSQL_DATABASE=magento

WARDEN_SYNC_IGNORE=

WARDEN_ALLURE=0
WARDEN_SELENIUM=0
WARDEN_SELENIUM_DEBUG=0
WARDEN_BLACKFIRE=0
WARDEN_SPLIT_SALES=0
WARDEN_SPLIT_CHECKOUT=0
WARDEN_TEST_DB=0
WARDEN_MAGEPACK=0

BLACKFIRE_CLIENT_ID=
BLACKFIRE_CLIENT_TOKEN=
BLACKFIRE_SERVER_ID=
BLACKFIRE_SERVER_TOKEN=


Enter fullscreen mode Exit fullscreen mode

A brief explanation of the keys in the .env file:

  • WARDEN_ENV_NAME It will be the prefix of the docker containers name and will also serve to configure the xdebug in your IDE Example:

warden-env-name

  • WARDEN_ENV_TYPE
    It will define the docker compose yaml files that will be used in the environment, which can vary according to the chosen platform.

  • WARDEN_WEB_ROOT
    Self explained, you have to inform the root directory of the project.

  • TRAEFIK_DOMAIN
    Traefik is used to route the requests to the services (containers) dynamically. For example, when there is the cookie XDEBUG_SESSION with the value PHPSTORM, it will send the requests to the php-debug container that has the xdebug enabled. On the contrary, the php-fpm container will receive the request.
    You can set the domain you want, just pay attention to the .test suffix, it you configure a domain with a different value you will lost the Automatic DNS Resolution feature.

  • TRAEFIK_SUBDOMAIN
    It is used to set a subdomain for your application, in our example the store can be accessed with the address https://TRAEFIK_SUBDOMAIN.TRAEFIK_DOMAIN that is: https://app.magento244.test

  • WARDEN_DB, WARDEN_ELASTICSEARCH, WARDEN_VARNISH, WARDEN_RABBITMQ, WARDEN_REDIS

The keys above you can use 0 to disable and 1 to enable. When the value is 0 the container will not run.

  • _VERSION
    The keys with the suffix _VERSION is to set a specific version to the service. For Magento 2.4.3, for example, you may use PHP 7.4. To do it, you can leave the key as: PHP_VERSION=7.4

  • PHP_XDEBUG_3
    If you set this key with value 1, a different tag of the container php-fpm image will be used. Let's look at the docker-compose yaml generated by warden with the command warden env config:

warden-env-config

  • COMPOSER_VERSION If it has the value = 1 or you ommit this key composer in version 1 will be the default executable, however you can run composer in version 2 with the command composer2.

Example:
If you omit or set the value 1 for COMPOSER_VERSION
composer

If you set the value 2 for COMPOSER_VERSION:
composer2

I prefer to inform the value 2 and already run composer in version 2 with the composer command.

There are more interesting things to configure such as Magento 2 tests, live reload, elastic search and more. You can see this information here.

6 Run the docker environment

Inside the ~/Sites/magento244/docker directory type:



make docker-up


Enter fullscreen mode Exit fullscreen mode
7 Run composer install

Inside the ~/Sites/magento244/docker run the command
below to access the PHP container



warden shell


Enter fullscreen mode Exit fullscreen mode

Run the composer install command



composer install


Enter fullscreen mode Exit fullscreen mode
8 Copy and rename the env.warden.php file

It will copy the file to the code-base/etc directory with the command below:



cp ~/Sites/magento244/code-base/app/etc/env.warden.php ~/Sites/magento244/code-base/app/etc/env.php


Enter fullscreen mode Exit fullscreen mode

The env.warden.php file has the default configuration entries with the warden hosts for the Mysql database, Redis (session and store cache), RabbitMQ, and Elastic Search.

9 Import the Magento 2 database

There is a sample database inside our Magento project, so copy the ~/Sites/magento244/code-base/dump.sql.gz file to ~/Sites/magento244/docker/backfill/magento-db.sql.gz with the command below:



cp ~/Sites/magento244/code-base/dump.sql.gz ~/Sites/magento244/docker/backfill/magento-db.sql.gz


Enter fullscreen mode Exit fullscreen mode

Open a new tab in your terminal and enter the directory ~/Sites/magento244/docker and type the command below:



make db-import


Enter fullscreen mode Exit fullscreen mode

The db-import command is one of the custom commands inside the Makefile.

This command imports the Magento-db.sql.gz database dump to the Magento database in the warden MySQL docker container.

In addition to importing the database, the ~/Sites/magento244/docker/tools/set-default-config.sh script is then executed to define the project's base URL and create a user for the Magento administrative panel.

In the ~/Sites/magento244/docker/tools/set-default-config.sh file, I usually put all the relevant settings to the Magento 2 environment to avoid errors and also to speed up the restoration of the environment as faithful as possible to the actual project.

Example of settings that are added in this file:

  • Project base URLs
  • Media and asset URLs
  • Payment test credentials
  • Changing the Algolia index to the development index, etc.
An Example of the content of this set-default-config.sh script:


#!/usr/bin/env bash

source $(dirname $0)/common.sh

:: Import the config from files
warden env exec -T php-fpm bin/magento app:config:import

:: Set BASE URL Config
warden env exec -T php-fpm bin/magento config:set web/unsecure/base_url ${URL_FRONT}
warden env exec -T php-fpm bin/magento config:set web/secure/base_url ${URL_FRONT}
warden env exec -T php-fpm bin/magento config:set web/unsecure/base_link_url ${URL_FRONT}
warden env exec -T php-fpm bin/magento config:set web/secure/base_link_url ${URL_FRONT}

:: Create an admin user
warden env exec -T php-fpm bin/magento admin:user:create --admin-user=admin --admin-password=123123q --admin-email=admin@example.com --admin-firstname=Admin --admin-lastname=Admin



Enter fullscreen mode Exit fullscreen mode
10 Sign the SSL certificate

Still, inside the ~/Sites/magento244/docker directory, type the command below:



warden sign-certificate app.magento244.test


Enter fullscreen mode Exit fullscreen mode
11 Update your /etc/hosts file with the store domain:


sudo echo '127.0.0.1 app.magento244.test' >> /etc/hosts


Enter fullscreen mode Exit fullscreen mode

Note Do the step above only if dnsmasq is not being used.

12 Installing the sample data (Optional)

Access the php container:



warden shell


Enter fullscreen mode Exit fullscreen mode

Run the command below to install the sample data:



bin/magento sampledata:deploy


Enter fullscreen mode Exit fullscreen mode

Run the command below to update the project database



bin/magento setup:upgrade


Enter fullscreen mode Exit fullscreen mode

Now you're able to access the store with the URLS \o/:

Store Address: https://app.magento244.test
Backend admin panel: https://app.magento244.test/backend

Store with single domain

Configuring a multiple website/store view Magento 2 project

This Magento 2 store has been configured with the below structure of websites/stores/store views:

store views

So, the main difference is how to configure a local warden environment to support multiple websites/store views with different domains.

1 Create a project folder


mkdir ~/Sites/magento244-multisite


Enter fullscreen mode Exit fullscreen mode
2 Enter the created multisite directory


cd ~/Sites/magento244-multisite


Enter fullscreen mode Exit fullscreen mode
3 Clone the Magento 2 code-base into the multisite code-base folder


git clone git@github.com:cristiano-pacheco/magento244-multisite.git code-base


Enter fullscreen mode Exit fullscreen mode
4 Clone the Warden Magento 2 template


git clone git@github.com:cristiano-pacheco/warden-env-magento2.git docker


Enter fullscreen mode Exit fullscreen mode
5 Change the warden .env file

Enter the docker directory



cd ~/Sites/magento244-multisite/docker


Enter fullscreen mode Exit fullscreen mode

Update the .env file with the content below:



WARDEN_ENV_NAME=magento244-multisite
WARDEN_ENV_TYPE=magento2
WARDEN_WEB_ROOT=/../code-base

TRAEFIK_DOMAIN=magento244-multisite.test
TRAEFIK_SUBDOMAIN=app

WARDEN_DB=1
WARDEN_ELASTICSEARCH=1
WARDEN_VARNISH=0
WARDEN_RABBITMQ=1
WARDEN_REDIS=1

ELASTICSEARCH_VERSION=7.16
MARIADB_VERSION=10.4
NODE_VERSION=10
PHP_VERSION=8.1
PHP_XDEBUG_3=1
COMPOSER_VERSION=2
RABBITMQ_VERSION=3.9
REDIS_VERSION=6.2
VARNISH_VERSION=7.0

MYSQL_USER=magento
MYSQL_PASSWORD=magento
MYSQL_DATABASE=magento

WARDEN_SYNC_IGNORE=

WARDEN_ALLURE=0
WARDEN_SELENIUM=0
WARDEN_SELENIUM_DEBUG=0
WARDEN_BLACKFIRE=0
WARDEN_SPLIT_SALES=0
WARDEN_SPLIT_CHECKOUT=0
WARDEN_TEST_DB=0
WARDEN_MAGEPACK=0

BLACKFIRE_CLIENT_ID=
BLACKFIRE_CLIENT_TOKEN=
BLACKFIRE_SERVER_ID=
BLACKFIRE_SERVER_TOKEN=


Enter fullscreen mode Exit fullscreen mode

More details about the configuration above was shared in the step 5 of Configuring a single website/store Magento 2 project

6 Define custom variables for the store domains

We will define custom variables in ~/Sites/magento244-multisite/docker/tools/common.sh to be able to reuse them later in our set-default-configs.sh file:



URL_WEBSITE_TWO_FRONT=https://app.magento244-website-two.test/
URL_STORE_VIEW_THREE_US_FRONT=https://app.magento244-store-view-three-us.test/
URL_STORE_VIEW_THREE_DE_FRONT=https://app.magento244-store-view-three-de.test/


Enter fullscreen mode Exit fullscreen mode
7 Updates the the defaults config script

Add the content of this file to the ~/Sites/magento244-multisite/docker/tools/set-default-configs.sh file.

The goal of the set-default-configs.sh script was explained here.

8 Run the docker environment

Inside the ~/Sites/magento244-multisite/docker directory type:



make docker-up


Enter fullscreen mode Exit fullscreen mode
9 Composer install

Inside the ~/Sites/magento244-multisite/docker run the command below to access the PHP container



warden shell


Enter fullscreen mode Exit fullscreen mode

Run the composer install command



composer install


Enter fullscreen mode Exit fullscreen mode
10 Copy and rename the env.warden.php file into the etc folder


cp ~/Sites/magento244-multisite/code-base/app/etc/env.warden.php ~/Sites/magento244-multisite/code-base/app/etc/env.php


Enter fullscreen mode Exit fullscreen mode
11 Import the Magento 2 multisite database

There is a sample database inside our Magento project, so copy the ~/Sites/magento244-multisite/code-base/dump.sql.gz file to ~/Sites/magento244-multisite/docker/backfill/magento-db.sql.gz with the command below:



cp ~/Sites/magento244-multisite/code-base/dump.sql.gz ~/Sites/magento244-multisite/docker/backfill/magento-db.sql.gz


Enter fullscreen mode Exit fullscreen mode

Open a new tab in your terminal and enter the directory ~/Sites/magento244-multisite/docker and type the command below:



make DB-import


Enter fullscreen mode Exit fullscreen mode
12 Sign the SSL certificates for all domains

Still, type the commands below inside the ~/Sites/magento244-multisite/docker directory.

To sign the certificate to the main and the admin store:



warden sign-certificate app.magento244-multisite.test


Enter fullscreen mode Exit fullscreen mode

To sign the certificate to the website-two:



warden sign-certificate app.magento244-website-two.test


Enter fullscreen mode Exit fullscreen mode

To sign the certificate to the Store View Three US:



warden sign-certificate app.magento244-store-view-three-us.test


Enter fullscreen mode Exit fullscreen mode

To sign the certificate to the Store View Three DE:



warden sign-certificate app.magento244-store-view-three-de.test


Enter fullscreen mode Exit fullscreen mode
13 Append your /etc/hosts file with the store domains


127.0.0.1 app.magento244-multisite.test
127.0.0.1 app.magento244-website-two.test
127.0.0.1 app.magento244-store-view-three-us.test
127.0.0.1 app.magento244-store-view-three-de.test


Enter fullscreen mode Exit fullscreen mode

Note Do the step above only if dnsmasq is not being used.

14 Configuring the application domains:

According to the Warden documentation we have to create a warden-env.yml file inside the .warden directory. Type the commands below:

Create the .warden-env.yml file



touch ~/Sites/magento244-multisite/docker/.warden/warden-env.yml


Enter fullscreen mode Exit fullscreen mode

Put the content below to the .warden-dev.yml file:



version: "3.5"
services:
  nginx:
    labels:
      - traefik.http.routers.${WARDEN_ENV_NAME}-nginx.rule=
        HostRegexp(`{subdomain:.+}.${TRAEFIK_DOMAIN}`)
        || Host(`${TRAEFIK_DOMAIN}`)
        || HostRegexp(`{subdomain:.+}.magento244-multisite.test`)
        || Host(`magento244-multisite.test`)
        || HostRegexp(`{subdomain:.+}.magento244-website-two.test`)
        || Host(`magento244-website-two.test`)
        || HostRegexp(`{subdomain:.+}.magento244-store-view-three-us.test`)
        || Host(`magento244-store-view-three-us.test`)
        || HostRegexp(`{subdomain:.+}.magento244-store-view-three-de.test`)
        || Host(`magento244-store-view-three-de.test`)


Enter fullscreen mode Exit fullscreen mode

You can have a copy of this file here.

When you're done with the settings, look at the traefik address to see where this mapping ended up. It will be like as:

traefik

Create stores.php the Add the Magento 2 run params to the project:



cd touch ~/Sites/magento244-multisite/code-base/app/etc/stores.php


Enter fullscreen mode Exit fullscreen mode

Add the content of this file in the file above.

Add the app/etc/stores.php to the composer.json file.

It should look like the image below after the change:

multi-store-config

It will force composer to load this file on every request. the file then sets up the store for Magento to load based on the domain, passing the MAGE_RUN_CODE and MAGE_RUN_TYPE variables to Nginx.

Now you're able to access the stores with the URLS \o/:

Default Store Address:
https://app.magento244-multisite.test

Backend admin panel:
https://app.magento244-multisite.test/backend

Website Two Address:
https://app.magento244-multisite.test

Store View Three US Address:
https://app.magento244-store-view-three-us.test

Store View Three DE Address:
https://app.magento244-store-view-three-de.test

Note:
Inside the directory ~/Sites/magento244-multisite/code-base, type the command make, and you will see an output like:

make-command

That's it. If you have any questions, please let us know in the comments 👋

Top comments (3)

Collapse
 
shahid23dev profile image
shahid23-dev

this file not generated "~/Sites/magento244/code-base/dump.sql.gz". what to do ?

Collapse
 
qixiano profile image
Cristiano Pacheco

You can grab a copy here

Collapse
 
huynguyen206 profile image
HuyNguyen206

Hi Pacheco, the docker repo is this github.com/wardenenv/warden-env-ma..., right?
I try git clone git@github.com:cristiano-pacheco/warden-env-magento2.git docker but it seems I don't have permission or the repo not exist anymore

'
ERROR: Repository not found.
fatal: Could not read from remote repository.
'