Kickstart Drupal 8 Commerce on Docker environment
“The factory of the future will have only two employees, a man, and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” Warren G. Bennis
This post requires basic knowledge of Docker, composer, bash linux. You need to have docker, docker-compose, composer installed on a linux-like environment.
Commerce (Here I refer to 2.x) is a set of Drupal 8 modules, which in turn depend on other best-of-breed modules and libraries. Commerce 2.x currently requires Drupal 8.5.0 or newer. Generally we require each minor release, as it contains improvements that we use, or to reduce our code base.
Alternative DDEV and Drupal VM. I tested them found them cool but too overwhelming and non so transparent.
You will need composer
PHP requirements: Drupal Commerce requires that you have the bcmath extension installed: php-bcmath
When using a Docker setup you now have a layer between you and your code, which means command line tools are a little harder. If you feel overwhelmed you can just log into the container and run your command. To log into the container use the following command docker exec -ti nameofcontainer /bin/bash
then you’re in the root of your project on that server. From there you have drupal console, drush, composer, git and other normal command line tools.
I use an environment called .env
file to manage all the version of the containers:
PROJECT_NAME=d8commerce
DRUPAL_VERSION=8.6.12
PHP_VERSION=7.2-fpm
NGINX_TAG=alpine
NGINX_PORT=8080:80
DRUPAL_TAG=8.6-fpm-alpine
MYSQL_VERSION=10.4
MYSQL_TAG=8
DB_NAME=drupal
DB_USER=drupal
DB_PASSWORD=drupal
DB_ROOT_PASSWORD=password
The constants are used in the docker-compose.yml
file:
note: volumes are outer_volume:internal_volume. The internal_volume needs to match the Dockerfile filesystem.
Check the image Dockerfile on hub.docker.io
You need to put docker-compose.yml
file in a folder identically named as ${PROJECT_NAME}
version: "3.7"
services:
web:
image: nginx:$NGINX_TAG
container_name: "${PROJECT_NAME}_nginx"
ports:
- $NGINX_PORT
volumes:
- "/var/www/html/${PROJECT_NAME}:/var/www/html/"
- "/etc/nginx/conf.d/site.conf:/etc/nginx/conf.d/default.conf"
depends_on:
- php
- mariadb
php:
image: php:$PHP_VERSION
container_name: "${PROJECT_NAME}_php"
volumes:
- "/var/www/html/${PROJECT_NAME}:/var/www/html/"
restart: always
depends_on:
- mysql
mariadb:
image: mariadb:$MYSQL_VERSION
container_name: "${PROJECT_NAME}_mysql"
restart: always
volumes:
- mariadb-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: qwerty
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
ports:
- 8000:80
environment:
- PMA_ARBITRARY=1
- PMA_HOST=mariadb
depends_on:
- mariadb
volumes:
mariadb-data:
Data persistence. Data is stored in a created volume: mariadb-data
. You can find it inside your project tree. This is where all db data will be stored, even if container is restarted, data will be there.
Environment variables: MYSQL_ROOT_PASSWORD: qwerty
- sets root password for mariadb container.
Environment variable PMA_ARBITRARY=1
- adds “server” input field to phpmyadmin login page (this way you can use this phpmyadmin with an external MySQL DB, and not just this local setup) environment variable PMA_HOST=mariadb - told phpmyadmin how to connect to mariadb map ports for phpmyadmin - 8000:80 - this maps inner port 80 from inside the container, to port 8000 on my host machine “depends_on” - prevents container to start before other container, on which it depends
Manage the containers
After everything is ready, we can turn on the containers (nginx, php, and MySQL)
docker-compose up -d
You can now visit http://localhost:8080
and start to install a new Drupal 8 project.
composer create-project drupalcommerce/project-base mystore --prefer-source --stability dev
The bin folder contains any library binaries, such as Drupal Console, PHPUnit, Behat, etc. The web folder represents the document root. If you host your site on Acquia Cloud or another service that requires Drupal in a subdirectory other than web, these instructions describe how you can relocate the docroot. Composer commands are always run from the site root (mystore in this case). See the Composer template for Drupal projects README for more details.
You can run php -S localhost:8080 from within your Drupal site to allow the tests to run.
When you are done, you can turn off the containers: docker-compose down
Export and Import database
If you already have an existing project you can put the project under drupal/web folder without running the installation script. After that, you can export and import database by using these commands
Maintenance
For export database
docker exec drupal8_mysql /usr/bin/mysqldump -u root --password=password drupal > drupal/backup.sql
To import database
cat drupal/backup.sql | docker exec -i drupal8_mysql /usr/bin/mysql -u root --password=password drupal
Enable Commerce
The instructions below use Drupal Console
drupal module:install commerce_product commerce_checkout commerce_cart
Update / upgrade Commerce
To update Drupal Commerce and all contributed projects extending Drupal Commerce:
composer update --with-dependencies "drupal/commerce*"
If you want to only upgrade Drupal Commerce, run this command:
composer update --with-dependencies drupal/commerce drupal/commerce_price drupal/commerce_product drupal/commerce_order drupal/commerce_payment drupal/commerce_payment_example drupal/commerce_checkout drupal/commerce_tax drupal/commerce_cart drupal/commerce_log drupal/commerce_store drupal/commerce_promotion drupal/commerce_number_pattern
Once the Drupal.org infrastructure issue is resolved, the command will be
composer update drupal/commerce --with-dependencies
Please note the --with-dependencies
option. Without this option specified, any needed, contributed projects and libraries will not update. Only the Drupal Commerce module will be updated.
Run your Drupal updates once all of the dependencies are updated. We recommend running them on the command line rather than the update.php script. See the example below.
drupal debug:update
drupal update:execute
Composer update tips
If your composer update command isn’t working, you can try: Run composer why-not to check dependency issues. Run composer remove then composer require to reinstall the project. Delete the composer.lock file and entire /vendor directory from your project and then run composer install. Run composer clear-cache. Run composer self-update.
I can go to:
myapp.loc/
- and still see phpinfo page
myapp.loc:8000
- see phpmyadmin, I can login using root/qwerty credentials
- What if I need database to be up and running with some initial DB inside, and not empty? This can be achieved by modifying mariadb section with: command: “mysqld –init-file /data/application/init.sql”
and
volumes:
- ./init.sql:/data/application/init.sql
init.sql - is an existing DB dump. using volumes I copy this file to container’s /data/application/init.sql location using “mysqld –init-file” command - I tell mysql to start and import init.sql
Once DB running, how to export/import DB?
To see list of containers and learn container id or name of mariadb container: docker container ls To import:
docker exec -i docker_mariadb_1 mysql -uroot -pqwerty DB_NAME < your_local_db_dump.sql
To export:
docker exec -i docker_mariadb_1 mysqldump -uroot -pqwerty DB_NAME > your_local_db_dump.sql