Before we begin the Docker setup, it is a good idea to understand what Docker is and what it can do for you.
On the Docker website, it says,
"A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings."
Basically, Docker is a program ran on your host machine as processes at runtime within an environment which helps to manage all the dependencies for each package you download to use.
You have the Docker engine which manages the environment you run. Each application you run are Docker containers, these are images you pull in from Docker hub to use. Below is a diagram:
In the diagram, App A to App F are Docker containers. Then you have Docker which is the engine that runs in the background, followed by host operating System which is your machine you are currently using (ie, Windows, Mac or Linux) and Dockers runs on top of it. Unlike virtual machine, more on that later. The infrastructure are the processes Docker runs to manage the whole self contained environment so it can exist on top of any host operating system you are using.
You can easily assume Docker might be some kind of Virtual Machine (like Vagrant) but you will be wrong. Docker is far more superior as it actually runs an environment separated from your host machine but exist alongside it. This explains why you can bind Docker volumes to any existing directory on your host machine. It also means Docker runs much faster and do away with all the bulk virtual machine brings because VM are really just running another operating system inside of your existing operating system (ie, your host machine) separately.
It also helps to simplify and better maintain your development workflow because each Docker images can be copied/deployed to any host machine or server with the exact environment so to avoid any bugs that may arise from the software packages (for example, Web, DB servers, PHP environment or versions and etc) you are using to built your website or custom app. Once you are finished, you could even destroy it and spin up a new Docker any time in less than 2 minutes.
To learn more about Docker, a good read will be to visit: https://opensource.com/resources/what-docker
Let the fun begin:
Ok, so we‘re going to deploy Drupal 8 with two docker containers: Apache2 + PHP and MariaDB (MySQL fork). or this tutorial, i'm using Linux Mint on my machine.
wget -qO- https://get.docker.com/ | sh
Check if your installation is ok and spin up Docker as well:
docker -D info
Here we can see that we have neither images nor containers, docker version, etc. By default, docker uses AUFS which allows docker to use versioning for docker images like in git, i.e. when you want to update the existing image, it won’t be downloaded entirely again, only new layers will be fetched.
Ok, now let’s download docker images. We’re going to use official images of MariaDB and Drupal. By default, if you don’t specify the absolute URL to the image it will be searched and downloaded from Docker Hub. Tag “latest” will be used by default since we don’t need any specific version.
docker pull mariadb
Now let’s download Drupal image. Let's pull the latest version. If you specify the tag: 8.0.1 (ie, drupal:8.0.1) it will fetch the 8.0.1 version instead.
docker pull drupal:latest
Let’s take a quick look at the Dockerfile of this image. As you can see it’s inherited from the official PHP docker image with Apache2. Then Apache’s rewrite module is enabled, additional libraries and PHP extensions are installed, opcache settings are updated and finally Drupal itself is downloaded.
Let’s see our images:
The images are quite heavy because they are assembled in Debian Jessie with its APT packaging system, fetching a lot of weighty dependencies.
Now, let’s run a container with MariaDB. By using key v (volume) we tell Docker to create a new mount from the host where our data will be stored. By default, the data will be stored inside of the container and this means it will be lost after rebuilding the container (you might need it to apply MariaDB updates).
In the output, we see the hash (identifier) of the running container.
docker run -e MYSQL_ROOT_PASSWORD=admin -e MYSQL_DATABASE=drupal8 -e MYSQL_USER=drupal8 -e MYSQL_PASSWORD=drupal8 -v mariadb:/var/lib/mysql -d --name mariadb mariadb
Now we run Drupal container with a link to just created MariaDB and the binding to the 80-th port. The link is just a record in /etc/hosts specifying IP of the container with MariaDB in a virtual network created by Docker during its installation.
docker run --name drupal8 --link mariadb:mysql -p 80:80 -d drupal:latest
Let’s take a look at our containers:
Open our IP in a browser and see Drupal installation. The installation is usual, except one little thing – you need to specify database host: mysql instead of localhost. That’s the name of the binding we’ve created before.
Go thru the usual steps to install Drupal. And that is completed.
To work on your Drupal site, you need to access the container.
To bash into a running container, type this:
docker exec -t -i <container_name> /bin/bash
Replace <container_name> with the container ID. Your working Drupal site should be in /var/www/html
To exit from a container, just type:
Copying files from a Docker container
If you want to know how to copy files between your host machine and Docker volume, watch this video:
To stop a container running (use the name of the container):
docker container stop drupal8 docker container stop mariadb
To delete Docker images:
docker images docker rmi -f <IMAGE ID>
Replace <IMAGE ID> with your own. For example: 070ea248d0c6
Now if you run the command 'docker images' and 'docker ps', nothing should show up as they have been removed from Docker.
[This tutorial was loosely based on: https://blog.wodby.com/6-reasons-to-deploy-drupal-8-with-docker-how-to-guide-b2f073e61672]