Docker4Drupal 2.1 for Development
Dalibor Stojaković
● Lead Developer & Architect in Websolutions Agency
● Over 10 years in Information Technology & Development
● Worked on various programming languages & frameworks
● In PHP world worked on Drupal, Symfony, Laravel, Phalcon,
FuelPHP,...
● Working on Drupal on big projects and loving it :)
● Very passionate about pretty much anything related to
Information Technology and Development and trying to
constantly be up-to-date with new and exciting technologies
What is Docker4Drupal?
● Set of docker optimized containers for Drupal
● Designed for local development
● Simply use docker-compose.yml and modify it according to
your needs
● Supported Drupal version: 6, 7 & 8
● Supported PHP versions: 5.3, 5.6, 7.0, 7.1
● Requirements: install docker > 1.12 & additionally docker
compose for linux
Downside
By default Docker has a poor performance on macOS (OS X).
However there's a workaround based on docker-sync project
Check below links for more info:
● https://github.com/EugenMayer/docker-sync
Container Versions Service name Image Default enabled?
Nginx 1.10 nginx wodby/drupal-nginx Yes
Drupal 6,7,8 php wodby/drupal Yes
PHP 5.3, 5.6, 7.0, 7.1 php wodby/drupal-php
MariaDB 10.1 mariadb wodby/mariadb Yes
Redis 3.2 redis wodby/redis
Varnish 4.1 varnish wodby/drupal-varnish
Solr 5.5, 6.3, 6.4 solr wodby/drupal-solr
Memcached 1.4 memcached wodby/memcached
Mailhog latest mailhog mailhog/mailhog Yes
phpMyAdmin latest pma phpmyadmin/phpmyadmin
Node.js 7 node _/node
Traefik latest traefik _/traefik
Why Docker4Drupal?
Accelerate developers:
● Stop wasting time on creating environments, setting up new
instances, copies running locally
● Docker gets you up and running much faster than vagrant
because there is no need for extra VM on linux environments
Usage
You can run Docker4Drupal in two ways:
● Run Vanilla Drupal from Image
(default)
○ wodby/drupal:8-7.1-2.1.2
○ wodby/drupal:8-7.0-2.1.2
○ wodby/drupal:7-7.1-2.1.2
○ wodby/drupal:7-7.0-2.1.2
○ wodby/drupal:7-5.6-2.1.2
○ wodby/drupal:6-5.6-2.1.2
○ wodby/drupal:6-5.3-2.1.2
● Mount your own Drupal Codebase
○ wodby/drupal-php:7.1-2.1.0
○ wodby/drupal-php:7.0-2.1.0
○ wodby/drupal-php:5.6-2.1.0
○ wodby/drupal-php:5.3-2.1.0
Before starting fix permission issues
To avoid potential permissions problems between host machine and containers (for
example: can't access files generated by PHP) you can add a group on your host machine
with ID 82, this is a standard GID/UID for www-data user in Alpine Linux
● LINUX - Create a new group with ID 82 and add yourself to this group
○ sudo groupadd -r -g 82 alpine-www-data
○ sudo usermod -a -G alpine-www-data $(id -un)
● On MAC group with 82 already exists (_clamav) so just add yourself to this group
○ sudo dseditgroup -o edit -a $(id -un) -t user _clamav
Usage - Run Vanilla Drupal from Image
1. Download docker-compose.yml file
2. NOTE: You need to update php and nginx images tags in docker-compose.yml if you
want to run Drupal 6 or 7 (by default it is set to Drupal 8)
a. Standard is wodby/drupal:[DRUPAL_VERSION]-[PHP_VERSION]-[STABILITY_TAG]
3. Run containers with: docker-compose up -d
4. Wait a few seconds for containers to initialize
5. Done! Visit your new site at http://drupal.docker.localhost:8000.
6. Default settings:
a. db user, db password and db name are all drupal
b. database host is mariadb
Usage - Mount your own Drupal Codebase:
● Download docker-compose.yml file to your Drupal project root
● Replace php image:
○ wodby/drupal:some_tag (PHP + vanilla Drupal) → to wodby/drupal-php:some_tag (just PHP)
○ Standard for images is wodby/drupal-php:[PHP_VERSION]-[STABILITY_TAG]
○ depending on your Drupal version use appropriate tags for php and nginx images
● Update nginx and php volumes to mount your codebase:
○ ./:/var/www/html
● Update NGINX_SERVER_ROOT to unless your project is based on composer template
○ /var/www/html
○ Example: for drupal-project composer template you would set this up to
/var/www/html/web
● Ensure your drupal settings.php uses the same credentials as mariadb service
Usage - Mount your own Drupal Codebase:
● Optional: import existing database (check example under mariadb container slide)
● Optional: uncomment lines in the compose file to run redis, solr, etc.... (check
example under each container slide)
● Optional: configure domains (we’ll go through traefik setup next - by default its set
to http://drupal.docker.localhost:8000
● Run containers with:
○ docker-compose up -d
● Done! Your website should be up and running at
http://drupal.docker.localhost:8000 if you didn’t change your domains specifications
Domains configuration
● Docker4Drupal uses traefik container for routing.
● Default setup is using port 8000 to avoid potential conflicts but if port 80 is free
on your host machine you can just replace traefik's ports definition in the
docker-compose.yml file (check default domains below)
Service Domain
nginx http://drupal.docker.localhost:8000
pma http://pma.drupal.docker.localhost:8000
mailhog http://mailhog.drupal.docker.localhost:8000
solr http://solr.drupal.docker.localhost:8000
node http://front.drupal.docker.localhost:8000
varnish http://varnish.drupal.docker.localhost:8000
Domains customisation
● Each container accessible via web has labels entry/definition which you can change
● NOTE: if your domains end with docker.localhost you don't need to add records to
/etc/hosts file
Example for phpMyAdmin (project replace with your project name in
pma.project.docker.localhost ) in docker-compose.yml file:
labels:
- 'traefik.backend=pma'
- 'traefik.port=80'
- 'traefik.frontend.rule=Host:pma.project.docker.localhost'
How to access/use your containers?
● General usage for accessing container:
○ docker-compose exec [service] sh
● use user www-data (82) for Nginx and PHP containers
○ docker-compose exec --user=82 php sh
● detached mode running in background only print container names
○ docker-compose up -d
● stop containers without removing them:
○ docker-compose stop
● stops containers and REMOVES containers, networks, volumes, and images created by `up`, DON’T USE IT
UNLESS YOU WANT TO REMOVE MENTIONED
○ docker-compose down
● Pulls latest version of images
○ docker-compose pull
● Restart app
○ docker-compose restart
Running Multiple projects with Traefik
Steps to set up two projects on one host
● Create some directory that will be parent for two projects I’ll call it traefik_test
● Create two dirs inside traefik_test directory where you will host two projects. Let's
name them "site1" and "site2".
● Copy docker-compose.yml file to both site directories (site1 and site2).
● Copy traefik.yml (you can find it on Docker4Drupal git repo) to the parent dir
(traefik_test)
● Edit traefik.yml and change "project1-dir_default" to "site1_default" and
"project2-dir_default" to "site2_default".
○ Those are docker networks default names that are created automatically from the directory name
where docker-compose.yml is located.
Steps to set up two projects on one host
● Edit site1's docker-compose.yml file (you’ll have to do this for both site2
docker-compose.yml file also just replace site1 with site2 from below)
○ in nginx service, under labels, change name of the container from :
○ 'traefik.backend=nginx' → 'traefik.backend=site1_nginx_1'
■ you can check names when with docker ps when containers are running
○ Change traefik.frontend.rule :
■ "Host:drupal.docker.localhost" → "Host:site1.docker.localhost
○ Comment out all lines of code for traefik service at the bottom of docker-compose.yml file
● Run docker-compose up -d in both site1 and site2 folders
● Run stand-alone traefik to start up traefik reverse proxy:
○ docker-compose -f traefik.yml up -d
● You’re DONE and you can access your sites on:
○ http://site1.docker.localhost
○ http://site2.docker.localhost
version: '2'
services:
traefik:
image: traefik
restart: unless-stopped
command: -c /dev/null --web --docker --logLevel=DEBUG
networks:
- project1
- project2
ports:
- '80:80'
- '8080:8080'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
project1:
external:
name: site1_default
project2:
external:
name: site2_default
Traefik.yml example
Docker container logs
● docker-compose logs [service]
● docker-compose logs -f php #real-time logs of the PHP container
NGINX
● Nginx images available are based on syntax:
○ wodby/drupal-nginx:[DRUPAL_VERSION]-[NGINX_VERSION]-[STABILITY_TAG]
● Available images:
○ wodby/drupal-nginx:8-1.10-2.1.0
○ wodby/drupal-nginx:7-1.10-2.1.0
○ wodby/drupal-nginx:6-1.10-2.1.0
NGINX - example config
nginx:
image: wodby/drupal-nginx:8-1.10-2.1.0
depends_on:
- php
environment:
NGINX_STATIC_CONTENT_OPEN_FILE_CACHE: "off"
NGINX_ERROR_LOG_LEVEL: debug
NGINX_BACKEND_HOST: php
NGINX_SERVER_ROOT: /var/www/html/web
volumes:
- ./:/var/www/html
labels:
- 'traefik.backend=nginx'
- 'traefik.port=80'
- 'traefik.frontend.rule=Host:site.docker.localhost'
NGINX - Environment Variables
Environment Variable Type Default Value
NGINX_SERVER_NAME String drupal
NGINX_SERVER_ROOT String /var/www/html
NGINX_STATIC_CONTENT_EXPIRES String 30d
NGINX_STATIC_CONTENT_OPEN_FILE_CACHE String max=3000 inactive=120s
NGINX_STATIC_CONTENT_OPEN_FILE_CACHE_VALID String 45s
NGINX_STATIC_CONTENT_OPEN_FILE_CACHE_MIN_USES Int 2
NGINX_DRUPAL_TRACK_UPLOADS String NGINX_DRUPAL_TRACK_UPLOADS
NGINX_STATIC_CONTENT_ACCESS_LOG String off
NGINX_SERVER_EXTRA_CONF_FILEPATH String
PHP
● used with Nginx via PHP-FPM
● Images are available with PHP versions: 5.3, 5.6, 7.0, 7.1
● List of Environment Variables you can set is pretty long and you can check it at
https://github.com/wodby/php
● It comes preinstalled with drush, composer and drupal launcher. Drupal console
itself must be installed per project manually via composer.
● Drush example:
○ docker-compose exec --user 82 php drush (run with user 82 as webserver is running with
user 82 also)
○ NOTE: If you have web root in subfolder for example web you’ll have to access your container
(docker-compose exec--user 82 php sh ) and run it from container from your web folder
● Composer example:
○ docker-compose exec --user 82 php composer update
PHP - Xdebug
● Uncomment below if you want to start using Xdebug before starting containers
○ PHP_XDEBUG: 1 # Enable Xdebug extension
○ PHP_XDEBUG_DEFAULT_ENABLE: 1 # Comment out to disable (default).
● If you would like to autostart xdebug, uncomment this line:
○ PHP_XDEBUG_REMOTE_AUTOSTART: 1 # Comment out to disable (default).
PHP Xdebug for Mac
● For Mac you’ll also have to uncomment two items below:
○ PHP_XDEBUG_REMOTE_CONNECT_BACK: 0 # Disabled for remote.host to work (enabled by
default)
○ PHP_XDEBUG_REMOTE_HOST: "10.254.254.254" # Setting the host (localhost by default)
● You also need to have loopback alias with IP from above.
○ Temporarily: You need this only once and that settings stays active until logout or restart
■ sudo ifconfig lo0 alias 10.254.254.254
○ Permanently:
■ To add the loopback alias after a reboot, add the following contents to
/Library/LaunchDaemons/docker4drupal.loopback.plist
Mac - docker4drupal.loopback.plist
<plist version="1.0">
<dict>
<key>Label</key>
<string>Default Loopback alias</string>
<key>ProgramArguments</key>
<array>
<string>/sbin/ifconfig</string>
<string>lo0</string>
<string>alias</string>
<string>10.254.254.254</string>
<string>netmask</string>
<string>255.255.255.0</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
PHP Xdebug for Windows
● You should do same things as for Mac OS. Enable Xdebug as described in the
previous sections and replace value of PHP_XDEBUG_REMOTE_HOST to your
DockerNAT ip assigned (by default it should be 10.0.75.1)
○ PHP_XDEBUG_REMOTE_HOST: "10.0.75.1" # Setting the host (localhost by default)
● Also check firewall so that it doesn’t block your connection
PHPUnit
1. Inside your drupal/core directory, copy the file phpunit.xml.dist file and
rename it to phpunit.xml
2. Open that file and make sure that you update SIMPLETEST_BASE_URL to
http://nginx
3. In order to make sure that your DB connection is working as well, update
SIMPLETEST_DB to mysql://username:password@mariadb/database
PHP - example config
php:
image: wodby/drupal-php:7.0-2.0.0
environment:
PHP_SENDMAIL_PATH: /usr/sbin/sendmail -t -i -S mailhog:1025
PHP_FPM_CLEAR_ENV: "no"
PHP_XDEBUG: 1
PHP_XDEBUG_DEFAULT_ENABLE: 1
volumes:
- ./:/var/www/html
MariaDB
● List of Environment Variables you can check at https://github.com/wodby/mariadb
● MariaDB uses a persistent volume defined in Dockerfile
IMPORTANT NOTES:
● DON’T USE docker-compose down because it will purge MariaDB volume.
● USE use docker-compose stop
● If you restart Docker you WILL NOT lose your MariaDB data
MariaDB - import db
● If you want to import db files initially you can create the volume directory
./mariadb-init in the same directory as the compose file and put there your SQL
file(s). All SQL files will be automatically imported once MariaDB container has
started then uncomment this line in docker-compose.yml
○ - ./mariadb-init:/docker-entrypoint-initdb.d # Place init .sql file(s) here
● with drush using php container like on example below
○ docker-compose exec --user 82 php drush sqlc < somedb.sql
○ Above will not work if your web root is not in document root. In that case you can use:
■ docker-compose exec --user 82 php sh
■ cd web (or whatever your directory is called)
■ drush sqlc < dbfile.sql
● using phpMyAdmin if you’ll use that image
MariaDB - export db
Exporting all databases:
● docker-compose exec mariadb sh -c 'exec mysqldump
--all-databases -uroot -p"root-password"' > databases.sql
Exporting single specific db:
● docker-compose exec mariadb sh -c 'exec mysqldump -uroot
-p"root-password" my-db' > my-db.sql
Of course you can export db same way as importing via drush (drush sql-dump in php
container) as in previous example for import or also via phpMyAdmin if you’ll use that
image
MariaDB - example config file
services:
mariadb:
image: wodby/mariadb:10.1-2.1.0
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: drupal
MYSQL_USER: drupal
MYSQL_PASSWORD: drupal
# volumes:
# - ./mariadb-init:/docker-entrypoint-initdb.d # Place init
.sql file(s) here for import
# - /path/to/mariadb/data/on/host:/var/lib/mysql # If you
want to manage volumes manually.
Redis
● List of all environment variables is available at https://github.com/wodby/redis
Usage:
● Uncomment following lines with redis service definition in the compose file.
○ # redis:
# image: wodby/redis:3.2-2.1.0
● Download and install redis module
● Add the following lines to the settings.php file (or settings.local.php): based on your
Drupal version
Redis - Drupal 7 config
$contrib_path = is_dir('sites/all/modules/contrib') ? 'sites/all/modules/contrib' :
'sites/all/modules';
$conf['redis_client_base'] = 0;
$conf['redis_client_interface'] = 'PhpRedis';
$conf['lock_inc'] = $contrib_path . '/redis/redis.lock.inc';
$conf['path_inc'] = $contrib_path . '/redis/redis.path.inc';
$conf['cache_backends'][] = $contrib_path . '/redis/redis.autoload.inc';
$conf['cache_default_class'] = 'Redis_Cache';
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
$conf['redis_client_host'] = 'redis';
$conf['redis_client_port'] = '6379';
Redis - Drupal 8 config
$contrib_path = is_dir('sites/all/modules/contrib') ? 'sites/all/modules/contrib' :
'sites/all/modules';
$settings['redis.connection']['host'] = 'redis';
$settings['redis.connection']['port'] = '6379';
$settings['redis.connection']['password'] = '';
$settings['redis.connection']['base'] = 0;
$settings['redis.connection']['interface'] = 'PhpRedis';
$settings['cache']['default'] = 'cache.backend.redis';
$settings['cache']['bins']['bootstrap'] = 'cache.backend.chainedfast';
$settings['cache']['bins']['discovery'] = 'cache.backend.chainedfast';
$settings['cache']['bins']['config'] = 'cache.backend.chainedfast';
$settings['container_yamls'][] = $contrib_path . '/redis/example.services.yml';
Memcached
● Uncomment lines with memcached service definition in the compose file.
○ # memcached:
# image: wodby/memcached:1.4-2.0.0
● Download and install memcache module
● Add the following lines to the settings.php (or settings.local.php) file:
$contrib_path = is_dir('sites/all/modules/contrib') ?
'sites/all/modules/contrib' : 'sites/all/modules';
$conf['memcache_extension'] = 'memcached';
$conf['cache_backends'][] = $contrib_path . '/memcache/memcache.inc';
$conf['lock_inc'] = $contrib_path . '/memcache/memcache-lock.inc';
$conf['memcache_stampede_protection'] = TRUE;
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
$conf['memcache_servers'] = array('memcached:11211' => 'default');
Apache Solr
● wodby/drupal-solr:[DRUPAL_VERSION]-[SOLR_VERSION]-[STABILITY_TAG]
○ wodby/drupal-solr:8-6.4-2.0.0
○ wodby/drupal-solr:8-6.3-2.0.0
○ wodby/drupal-solr:8-5.5-2.0.0
○ wodby/drupal-solr:7-6.4-2.0.0
○ wodby/drupal-solr:7-6.3-2.0.0
○ wodby/drupal-solr:7-5.5-2.0.0
● If you didn’t change domain config, Solr admin UI can be accessed by
http://solr.drupal.docker.localhost:8000
● Solr container has a persistent volume defined in Dockerfile as MariaDB, so your
data won't be lost if you stop the container
● Solr cores can be found under /opt/solr/server/solr
Apache Solr - Integration with Search API Solr Module
1. Uncomment solr code in docker-compose.yml (example on next slide)
2. Create new solr core with command
a. docker exec -ti [ID] make core=core1 -f /usr/local/bin/actions.mk
i. your id [ID] will probably be something like project-name_solr_1. You
can check it with docker-compose ps
3. The new core will already include config files from Search API Solr module
4. Download and enable Search API Solr module
5. Open module configuration page in drupal and add a new search server
6. Choose Solr as a backend and Standard Solr Connector
7. Specify solr as a Solr host, 8983 as a port, /solr as a solr path and your core name
(core1 from step 1)
8. Done!!!
Apache Solr - example config
solr:
image: wodby/drupal-solr:8-5.5-2.0.0
environment:
SOLR_HEAP: 1024m
labels:
- 'traefik.backend=solr'
- 'traefik.port=8983'
- 'traefik.frontend.rule=Host:solr.irt.docker.localhost'
Varnish
● Uncomment lines with varnish service definition in the compose file (example config
on next slide)
● Download and install varnish module
● Add the following lines to the settings.php file:
$conf['varnish_version'] = 4;
$conf['varnish_control_terminal'] = 'varnish:6082';
$conf['varnish_control_key'] = 'secret';
Varnish example config
varnish:
image: wodby/drupal-varnish:4.1-2.1.0
depends_on:
- nginx
environment:
VARNISH_SECRET: secret
VARNISH_BACKEND_HOST: nginx
VARNISH_BACKEND_PORT: 80
labels:
- 'traefik.backend=varnish'
- 'traefik.port=6081'
- 'traefik.frontend.rule=Host:varnish.drupal.docker.localhost'
Varnish - environment variables
Environment Variable Type Default Value
VARNISH_BACKEND_HOST (required) String
VARNISH_BACKEND_PORT String 80
VARNISH_ERRORS_TTL String 10m
VARNISH_GRACE String 6h
VARNISH_BACKEND_FIRST_BYTE_TIMEOUT String 300s
VARNISH_BACKEND_CONNECT_TIMEOUT String 5s
VARNISH_BACKEND_BETWEEN_BYTES_TIMEOUT String 2s
Docker additional helpful commands
● docker volume list - listing all docker volumes
● docker volume rm volume_name - remove docker volume
● docker ps -a - list all docker containers and check statuses
● docker kill $(docker ps -q) - kill all running containers
● docker rm $(docker ps -a -q) - delete all stopped containers (including
data-only containers)
● docker rmi $(docker images -q -f dangling=true) - delete all
'untagged/dangling' images
● docker rmi $(docker images -q) - delete all images
Interested in topic and need more?
● http://docs.docker4drupal.org
● https://traefik.io
● https://www.docker.com
● https://docs.docker.com/compose/
● https://docs.docker.com
Download code
● You can download traefik_test code on link below:
○ https://drive.google.com/open?id=0B20IyE5jr4iZelhzWkVLMlBNSWs
QUESTIONS ?
THE END :)

Docker4Drupal 2.1 for Development

  • 1.
  • 2.
    Dalibor Stojaković ● LeadDeveloper & Architect in Websolutions Agency ● Over 10 years in Information Technology & Development ● Worked on various programming languages & frameworks ● In PHP world worked on Drupal, Symfony, Laravel, Phalcon, FuelPHP,... ● Working on Drupal on big projects and loving it :) ● Very passionate about pretty much anything related to Information Technology and Development and trying to constantly be up-to-date with new and exciting technologies
  • 3.
    What is Docker4Drupal? ●Set of docker optimized containers for Drupal ● Designed for local development ● Simply use docker-compose.yml and modify it according to your needs ● Supported Drupal version: 6, 7 & 8 ● Supported PHP versions: 5.3, 5.6, 7.0, 7.1 ● Requirements: install docker > 1.12 & additionally docker compose for linux
  • 4.
    Downside By default Dockerhas a poor performance on macOS (OS X). However there's a workaround based on docker-sync project Check below links for more info: ● https://github.com/EugenMayer/docker-sync
  • 5.
    Container Versions Servicename Image Default enabled? Nginx 1.10 nginx wodby/drupal-nginx Yes Drupal 6,7,8 php wodby/drupal Yes PHP 5.3, 5.6, 7.0, 7.1 php wodby/drupal-php MariaDB 10.1 mariadb wodby/mariadb Yes Redis 3.2 redis wodby/redis Varnish 4.1 varnish wodby/drupal-varnish Solr 5.5, 6.3, 6.4 solr wodby/drupal-solr Memcached 1.4 memcached wodby/memcached Mailhog latest mailhog mailhog/mailhog Yes phpMyAdmin latest pma phpmyadmin/phpmyadmin Node.js 7 node _/node Traefik latest traefik _/traefik
  • 6.
    Why Docker4Drupal? Accelerate developers: ●Stop wasting time on creating environments, setting up new instances, copies running locally ● Docker gets you up and running much faster than vagrant because there is no need for extra VM on linux environments
  • 7.
    Usage You can runDocker4Drupal in two ways: ● Run Vanilla Drupal from Image (default) ○ wodby/drupal:8-7.1-2.1.2 ○ wodby/drupal:8-7.0-2.1.2 ○ wodby/drupal:7-7.1-2.1.2 ○ wodby/drupal:7-7.0-2.1.2 ○ wodby/drupal:7-5.6-2.1.2 ○ wodby/drupal:6-5.6-2.1.2 ○ wodby/drupal:6-5.3-2.1.2 ● Mount your own Drupal Codebase ○ wodby/drupal-php:7.1-2.1.0 ○ wodby/drupal-php:7.0-2.1.0 ○ wodby/drupal-php:5.6-2.1.0 ○ wodby/drupal-php:5.3-2.1.0
  • 8.
    Before starting fixpermission issues To avoid potential permissions problems between host machine and containers (for example: can't access files generated by PHP) you can add a group on your host machine with ID 82, this is a standard GID/UID for www-data user in Alpine Linux ● LINUX - Create a new group with ID 82 and add yourself to this group ○ sudo groupadd -r -g 82 alpine-www-data ○ sudo usermod -a -G alpine-www-data $(id -un) ● On MAC group with 82 already exists (_clamav) so just add yourself to this group ○ sudo dseditgroup -o edit -a $(id -un) -t user _clamav
  • 9.
    Usage - RunVanilla Drupal from Image 1. Download docker-compose.yml file 2. NOTE: You need to update php and nginx images tags in docker-compose.yml if you want to run Drupal 6 or 7 (by default it is set to Drupal 8) a. Standard is wodby/drupal:[DRUPAL_VERSION]-[PHP_VERSION]-[STABILITY_TAG] 3. Run containers with: docker-compose up -d 4. Wait a few seconds for containers to initialize 5. Done! Visit your new site at http://drupal.docker.localhost:8000. 6. Default settings: a. db user, db password and db name are all drupal b. database host is mariadb
  • 10.
    Usage - Mountyour own Drupal Codebase: ● Download docker-compose.yml file to your Drupal project root ● Replace php image: ○ wodby/drupal:some_tag (PHP + vanilla Drupal) → to wodby/drupal-php:some_tag (just PHP) ○ Standard for images is wodby/drupal-php:[PHP_VERSION]-[STABILITY_TAG] ○ depending on your Drupal version use appropriate tags for php and nginx images ● Update nginx and php volumes to mount your codebase: ○ ./:/var/www/html ● Update NGINX_SERVER_ROOT to unless your project is based on composer template ○ /var/www/html ○ Example: for drupal-project composer template you would set this up to /var/www/html/web ● Ensure your drupal settings.php uses the same credentials as mariadb service
  • 11.
    Usage - Mountyour own Drupal Codebase: ● Optional: import existing database (check example under mariadb container slide) ● Optional: uncomment lines in the compose file to run redis, solr, etc.... (check example under each container slide) ● Optional: configure domains (we’ll go through traefik setup next - by default its set to http://drupal.docker.localhost:8000 ● Run containers with: ○ docker-compose up -d ● Done! Your website should be up and running at http://drupal.docker.localhost:8000 if you didn’t change your domains specifications
  • 12.
    Domains configuration ● Docker4Drupaluses traefik container for routing. ● Default setup is using port 8000 to avoid potential conflicts but if port 80 is free on your host machine you can just replace traefik's ports definition in the docker-compose.yml file (check default domains below) Service Domain nginx http://drupal.docker.localhost:8000 pma http://pma.drupal.docker.localhost:8000 mailhog http://mailhog.drupal.docker.localhost:8000 solr http://solr.drupal.docker.localhost:8000 node http://front.drupal.docker.localhost:8000 varnish http://varnish.drupal.docker.localhost:8000
  • 13.
    Domains customisation ● Eachcontainer accessible via web has labels entry/definition which you can change ● NOTE: if your domains end with docker.localhost you don't need to add records to /etc/hosts file Example for phpMyAdmin (project replace with your project name in pma.project.docker.localhost ) in docker-compose.yml file: labels: - 'traefik.backend=pma' - 'traefik.port=80' - 'traefik.frontend.rule=Host:pma.project.docker.localhost'
  • 14.
    How to access/useyour containers? ● General usage for accessing container: ○ docker-compose exec [service] sh ● use user www-data (82) for Nginx and PHP containers ○ docker-compose exec --user=82 php sh ● detached mode running in background only print container names ○ docker-compose up -d ● stop containers without removing them: ○ docker-compose stop ● stops containers and REMOVES containers, networks, volumes, and images created by `up`, DON’T USE IT UNLESS YOU WANT TO REMOVE MENTIONED ○ docker-compose down ● Pulls latest version of images ○ docker-compose pull ● Restart app ○ docker-compose restart
  • 15.
  • 16.
    Steps to setup two projects on one host ● Create some directory that will be parent for two projects I’ll call it traefik_test ● Create two dirs inside traefik_test directory where you will host two projects. Let's name them "site1" and "site2". ● Copy docker-compose.yml file to both site directories (site1 and site2). ● Copy traefik.yml (you can find it on Docker4Drupal git repo) to the parent dir (traefik_test) ● Edit traefik.yml and change "project1-dir_default" to "site1_default" and "project2-dir_default" to "site2_default". ○ Those are docker networks default names that are created automatically from the directory name where docker-compose.yml is located.
  • 17.
    Steps to setup two projects on one host ● Edit site1's docker-compose.yml file (you’ll have to do this for both site2 docker-compose.yml file also just replace site1 with site2 from below) ○ in nginx service, under labels, change name of the container from : ○ 'traefik.backend=nginx' → 'traefik.backend=site1_nginx_1' ■ you can check names when with docker ps when containers are running ○ Change traefik.frontend.rule : ■ "Host:drupal.docker.localhost" → "Host:site1.docker.localhost ○ Comment out all lines of code for traefik service at the bottom of docker-compose.yml file ● Run docker-compose up -d in both site1 and site2 folders ● Run stand-alone traefik to start up traefik reverse proxy: ○ docker-compose -f traefik.yml up -d ● You’re DONE and you can access your sites on: ○ http://site1.docker.localhost ○ http://site2.docker.localhost
  • 18.
    version: '2' services: traefik: image: traefik restart:unless-stopped command: -c /dev/null --web --docker --logLevel=DEBUG networks: - project1 - project2 ports: - '80:80' - '8080:8080' volumes: - /var/run/docker.sock:/var/run/docker.sock networks: project1: external: name: site1_default project2: external: name: site2_default Traefik.yml example
  • 19.
    Docker container logs ●docker-compose logs [service] ● docker-compose logs -f php #real-time logs of the PHP container
  • 20.
    NGINX ● Nginx imagesavailable are based on syntax: ○ wodby/drupal-nginx:[DRUPAL_VERSION]-[NGINX_VERSION]-[STABILITY_TAG] ● Available images: ○ wodby/drupal-nginx:8-1.10-2.1.0 ○ wodby/drupal-nginx:7-1.10-2.1.0 ○ wodby/drupal-nginx:6-1.10-2.1.0
  • 21.
    NGINX - exampleconfig nginx: image: wodby/drupal-nginx:8-1.10-2.1.0 depends_on: - php environment: NGINX_STATIC_CONTENT_OPEN_FILE_CACHE: "off" NGINX_ERROR_LOG_LEVEL: debug NGINX_BACKEND_HOST: php NGINX_SERVER_ROOT: /var/www/html/web volumes: - ./:/var/www/html labels: - 'traefik.backend=nginx' - 'traefik.port=80' - 'traefik.frontend.rule=Host:site.docker.localhost'
  • 22.
    NGINX - EnvironmentVariables Environment Variable Type Default Value NGINX_SERVER_NAME String drupal NGINX_SERVER_ROOT String /var/www/html NGINX_STATIC_CONTENT_EXPIRES String 30d NGINX_STATIC_CONTENT_OPEN_FILE_CACHE String max=3000 inactive=120s NGINX_STATIC_CONTENT_OPEN_FILE_CACHE_VALID String 45s NGINX_STATIC_CONTENT_OPEN_FILE_CACHE_MIN_USES Int 2 NGINX_DRUPAL_TRACK_UPLOADS String NGINX_DRUPAL_TRACK_UPLOADS NGINX_STATIC_CONTENT_ACCESS_LOG String off NGINX_SERVER_EXTRA_CONF_FILEPATH String
  • 23.
    PHP ● used withNginx via PHP-FPM ● Images are available with PHP versions: 5.3, 5.6, 7.0, 7.1 ● List of Environment Variables you can set is pretty long and you can check it at https://github.com/wodby/php ● It comes preinstalled with drush, composer and drupal launcher. Drupal console itself must be installed per project manually via composer. ● Drush example: ○ docker-compose exec --user 82 php drush (run with user 82 as webserver is running with user 82 also) ○ NOTE: If you have web root in subfolder for example web you’ll have to access your container (docker-compose exec--user 82 php sh ) and run it from container from your web folder ● Composer example: ○ docker-compose exec --user 82 php composer update
  • 24.
    PHP - Xdebug ●Uncomment below if you want to start using Xdebug before starting containers ○ PHP_XDEBUG: 1 # Enable Xdebug extension ○ PHP_XDEBUG_DEFAULT_ENABLE: 1 # Comment out to disable (default). ● If you would like to autostart xdebug, uncomment this line: ○ PHP_XDEBUG_REMOTE_AUTOSTART: 1 # Comment out to disable (default).
  • 25.
    PHP Xdebug forMac ● For Mac you’ll also have to uncomment two items below: ○ PHP_XDEBUG_REMOTE_CONNECT_BACK: 0 # Disabled for remote.host to work (enabled by default) ○ PHP_XDEBUG_REMOTE_HOST: "10.254.254.254" # Setting the host (localhost by default) ● You also need to have loopback alias with IP from above. ○ Temporarily: You need this only once and that settings stays active until logout or restart ■ sudo ifconfig lo0 alias 10.254.254.254 ○ Permanently: ■ To add the loopback alias after a reboot, add the following contents to /Library/LaunchDaemons/docker4drupal.loopback.plist
  • 26.
    Mac - docker4drupal.loopback.plist <plistversion="1.0"> <dict> <key>Label</key> <string>Default Loopback alias</string> <key>ProgramArguments</key> <array> <string>/sbin/ifconfig</string> <string>lo0</string> <string>alias</string> <string>10.254.254.254</string> <string>netmask</string> <string>255.255.255.0</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>
  • 27.
    PHP Xdebug forWindows ● You should do same things as for Mac OS. Enable Xdebug as described in the previous sections and replace value of PHP_XDEBUG_REMOTE_HOST to your DockerNAT ip assigned (by default it should be 10.0.75.1) ○ PHP_XDEBUG_REMOTE_HOST: "10.0.75.1" # Setting the host (localhost by default) ● Also check firewall so that it doesn’t block your connection
  • 28.
    PHPUnit 1. Inside yourdrupal/core directory, copy the file phpunit.xml.dist file and rename it to phpunit.xml 2. Open that file and make sure that you update SIMPLETEST_BASE_URL to http://nginx 3. In order to make sure that your DB connection is working as well, update SIMPLETEST_DB to mysql://username:password@mariadb/database
  • 29.
    PHP - exampleconfig php: image: wodby/drupal-php:7.0-2.0.0 environment: PHP_SENDMAIL_PATH: /usr/sbin/sendmail -t -i -S mailhog:1025 PHP_FPM_CLEAR_ENV: "no" PHP_XDEBUG: 1 PHP_XDEBUG_DEFAULT_ENABLE: 1 volumes: - ./:/var/www/html
  • 30.
    MariaDB ● List ofEnvironment Variables you can check at https://github.com/wodby/mariadb ● MariaDB uses a persistent volume defined in Dockerfile IMPORTANT NOTES: ● DON’T USE docker-compose down because it will purge MariaDB volume. ● USE use docker-compose stop ● If you restart Docker you WILL NOT lose your MariaDB data
  • 31.
    MariaDB - importdb ● If you want to import db files initially you can create the volume directory ./mariadb-init in the same directory as the compose file and put there your SQL file(s). All SQL files will be automatically imported once MariaDB container has started then uncomment this line in docker-compose.yml ○ - ./mariadb-init:/docker-entrypoint-initdb.d # Place init .sql file(s) here ● with drush using php container like on example below ○ docker-compose exec --user 82 php drush sqlc < somedb.sql ○ Above will not work if your web root is not in document root. In that case you can use: ■ docker-compose exec --user 82 php sh ■ cd web (or whatever your directory is called) ■ drush sqlc < dbfile.sql ● using phpMyAdmin if you’ll use that image
  • 32.
    MariaDB - exportdb Exporting all databases: ● docker-compose exec mariadb sh -c 'exec mysqldump --all-databases -uroot -p"root-password"' > databases.sql Exporting single specific db: ● docker-compose exec mariadb sh -c 'exec mysqldump -uroot -p"root-password" my-db' > my-db.sql Of course you can export db same way as importing via drush (drush sql-dump in php container) as in previous example for import or also via phpMyAdmin if you’ll use that image
  • 33.
    MariaDB - exampleconfig file services: mariadb: image: wodby/mariadb:10.1-2.1.0 environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: drupal MYSQL_USER: drupal MYSQL_PASSWORD: drupal # volumes: # - ./mariadb-init:/docker-entrypoint-initdb.d # Place init .sql file(s) here for import # - /path/to/mariadb/data/on/host:/var/lib/mysql # If you want to manage volumes manually.
  • 34.
    Redis ● List ofall environment variables is available at https://github.com/wodby/redis Usage: ● Uncomment following lines with redis service definition in the compose file. ○ # redis: # image: wodby/redis:3.2-2.1.0 ● Download and install redis module ● Add the following lines to the settings.php file (or settings.local.php): based on your Drupal version
  • 35.
    Redis - Drupal7 config $contrib_path = is_dir('sites/all/modules/contrib') ? 'sites/all/modules/contrib' : 'sites/all/modules'; $conf['redis_client_base'] = 0; $conf['redis_client_interface'] = 'PhpRedis'; $conf['lock_inc'] = $contrib_path . '/redis/redis.lock.inc'; $conf['path_inc'] = $contrib_path . '/redis/redis.path.inc'; $conf['cache_backends'][] = $contrib_path . '/redis/redis.autoload.inc'; $conf['cache_default_class'] = 'Redis_Cache'; $conf['cache_class_cache_form'] = 'DrupalDatabaseCache'; $conf['redis_client_host'] = 'redis'; $conf['redis_client_port'] = '6379';
  • 36.
    Redis - Drupal8 config $contrib_path = is_dir('sites/all/modules/contrib') ? 'sites/all/modules/contrib' : 'sites/all/modules'; $settings['redis.connection']['host'] = 'redis'; $settings['redis.connection']['port'] = '6379'; $settings['redis.connection']['password'] = ''; $settings['redis.connection']['base'] = 0; $settings['redis.connection']['interface'] = 'PhpRedis'; $settings['cache']['default'] = 'cache.backend.redis'; $settings['cache']['bins']['bootstrap'] = 'cache.backend.chainedfast'; $settings['cache']['bins']['discovery'] = 'cache.backend.chainedfast'; $settings['cache']['bins']['config'] = 'cache.backend.chainedfast'; $settings['container_yamls'][] = $contrib_path . '/redis/example.services.yml';
  • 37.
    Memcached ● Uncomment lineswith memcached service definition in the compose file. ○ # memcached: # image: wodby/memcached:1.4-2.0.0 ● Download and install memcache module ● Add the following lines to the settings.php (or settings.local.php) file: $contrib_path = is_dir('sites/all/modules/contrib') ? 'sites/all/modules/contrib' : 'sites/all/modules'; $conf['memcache_extension'] = 'memcached'; $conf['cache_backends'][] = $contrib_path . '/memcache/memcache.inc'; $conf['lock_inc'] = $contrib_path . '/memcache/memcache-lock.inc'; $conf['memcache_stampede_protection'] = TRUE; $conf['cache_default_class'] = 'MemCacheDrupal'; $conf['cache_class_cache_form'] = 'DrupalDatabaseCache'; $conf['memcache_servers'] = array('memcached:11211' => 'default');
  • 38.
    Apache Solr ● wodby/drupal-solr:[DRUPAL_VERSION]-[SOLR_VERSION]-[STABILITY_TAG] ○wodby/drupal-solr:8-6.4-2.0.0 ○ wodby/drupal-solr:8-6.3-2.0.0 ○ wodby/drupal-solr:8-5.5-2.0.0 ○ wodby/drupal-solr:7-6.4-2.0.0 ○ wodby/drupal-solr:7-6.3-2.0.0 ○ wodby/drupal-solr:7-5.5-2.0.0 ● If you didn’t change domain config, Solr admin UI can be accessed by http://solr.drupal.docker.localhost:8000 ● Solr container has a persistent volume defined in Dockerfile as MariaDB, so your data won't be lost if you stop the container ● Solr cores can be found under /opt/solr/server/solr
  • 39.
    Apache Solr -Integration with Search API Solr Module 1. Uncomment solr code in docker-compose.yml (example on next slide) 2. Create new solr core with command a. docker exec -ti [ID] make core=core1 -f /usr/local/bin/actions.mk i. your id [ID] will probably be something like project-name_solr_1. You can check it with docker-compose ps 3. The new core will already include config files from Search API Solr module 4. Download and enable Search API Solr module 5. Open module configuration page in drupal and add a new search server 6. Choose Solr as a backend and Standard Solr Connector 7. Specify solr as a Solr host, 8983 as a port, /solr as a solr path and your core name (core1 from step 1) 8. Done!!!
  • 40.
    Apache Solr -example config solr: image: wodby/drupal-solr:8-5.5-2.0.0 environment: SOLR_HEAP: 1024m labels: - 'traefik.backend=solr' - 'traefik.port=8983' - 'traefik.frontend.rule=Host:solr.irt.docker.localhost'
  • 41.
    Varnish ● Uncomment lineswith varnish service definition in the compose file (example config on next slide) ● Download and install varnish module ● Add the following lines to the settings.php file: $conf['varnish_version'] = 4; $conf['varnish_control_terminal'] = 'varnish:6082'; $conf['varnish_control_key'] = 'secret';
  • 42.
    Varnish example config varnish: image:wodby/drupal-varnish:4.1-2.1.0 depends_on: - nginx environment: VARNISH_SECRET: secret VARNISH_BACKEND_HOST: nginx VARNISH_BACKEND_PORT: 80 labels: - 'traefik.backend=varnish' - 'traefik.port=6081' - 'traefik.frontend.rule=Host:varnish.drupal.docker.localhost'
  • 43.
    Varnish - environmentvariables Environment Variable Type Default Value VARNISH_BACKEND_HOST (required) String VARNISH_BACKEND_PORT String 80 VARNISH_ERRORS_TTL String 10m VARNISH_GRACE String 6h VARNISH_BACKEND_FIRST_BYTE_TIMEOUT String 300s VARNISH_BACKEND_CONNECT_TIMEOUT String 5s VARNISH_BACKEND_BETWEEN_BYTES_TIMEOUT String 2s
  • 44.
    Docker additional helpfulcommands ● docker volume list - listing all docker volumes ● docker volume rm volume_name - remove docker volume ● docker ps -a - list all docker containers and check statuses ● docker kill $(docker ps -q) - kill all running containers ● docker rm $(docker ps -a -q) - delete all stopped containers (including data-only containers) ● docker rmi $(docker images -q -f dangling=true) - delete all 'untagged/dangling' images ● docker rmi $(docker images -q) - delete all images
  • 45.
    Interested in topicand need more? ● http://docs.docker4drupal.org ● https://traefik.io ● https://www.docker.com ● https://docs.docker.com/compose/ ● https://docs.docker.com
  • 46.
    Download code ● Youcan download traefik_test code on link below: ○ https://drive.google.com/open?id=0B20IyE5jr4iZelhzWkVLMlBNSWs
  • 47.
  • 48.