LAMP env for Drupal 9 with Docker
Why using Docker?
Docker allows us to create containers with very easy to maintain and manipulate microservices.
But not only this, docker also allows that a developer team be able to work in the same environment with the same versions of the services they are executing, no matter the operating system host they are using. In this way, errors are reduced when more people are working in the same project and in different areas of the same.
The environment
In order to make a Drupal environment in a virtualization system like docker, it will be needed to have a web service and a database. Both services can be located in a single container or in more than one container. Nowadays, everything is moving in the direction of microservices, that is why in this project two separated containers will be achieved, one for the web environment and other for the database.
The project tree looks like this:
Let's build the system
docker-compose.yml
In this YAML file, the following parameters are defined. This file is found in the project root. So below, two services are configured with docker-compose.
version: "3.7" // Docker-compose version.
services: // The services to create.
web: // Microservice 1.
build: apache // Container to build (dockerfile Apache).
links: // Link to the database.
- db // Name of the service to link.
ports: // Mapping ports[Host]:[Container].
- "80:80" // HTTP port.
- "HTTPS port (Need ssl).
volumes: // Volume to create.
- ./www:/var/www/html // [Directory]:[Directory in container]
db: // Microservice 2.
build: mysql // Container to build (dockerfile Mysql).
ports: // Mapping port [Host]:[Container].
- "3306:3306" // Default database port.
apache/Dockerfile
FROM php:7.3-apache-stretch // PHP and Apache version
RUN useradd -u 1000 -m user // Adding user uid 1000
RUN apt-get update // Updating packages
RUN apt-get install -y \ // Install needed packages
#Container utilities
git \
wget \
vim \
#Connection
mysql-client \
#Libraries
libpng-dev \
libmcrypt-dev \
libicu-dev \
pecl install mcrypt-1.0.2 && \
apt-get install -y libmagickwand-dev --no-install-recommends && \
#PHP Extensions, needed for the CMS
docker-php-ext-install mbstring && \
docker-php-ext-install pdo_mysql && \
docker-php-ext-install mysqli && \
docker-php-ext-enable mcrypt && \
docker-php-ext-install opcache && \
docker-php-ext-install pcntl && \
docker-php-ext-install intl && \
docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && \ docker-php-ext-install gd && \
pecl install imagick && \
docker-php-ext-enable imagick && \
rm -r /var/lib/apt/lists/* && \
#Composer to manage dependencies
curl -sS https://getcomposer.org/installer | php && \
mv composer.phar /usr/bin/composer && \
#Enable PHP modules
a2enmod rewrite && \
a2enmod ssl && \
a2ensite default-ssl && \
curl -sL https://deb.nodesource.com/setup_12.x | bash -
#Enable SSL for HTTPS connection
RUN apt-get install nodejs -y && \
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/ssl-cert-user.key -out /etc/ssl/certs/ssl-cert-user.pem -subj '/'
#Add custom templates to different config paths in the container
ADD templates/apache2.conf /etc/apache2/
ADD templates/php.ini /usr/local/etc/php/
ADD templates/xdebug.ini /usr/local/etc/php/conf.d/
apache/templates/apache2.conf
In the following link, apache configurations for the debian system can be found: https://sources.debian.org/src/apache2/2.4.10-10/debian/config-dir/apac…
apache/templates/php.ini
[php]
register_globals = off
display_errors = On
error_reporting = E_ALL | E_STRICT
log_errors = On
error_log = /var/log/php_errors.log
date.timezone="Europe/London"
upload_max_filesize=64M
post_max_size=64M
memory_limit=1024M
mysql/Dockerfile
FROM mysql:5.7
ENV MYSQL_ROOT_PASSWORD Qwerty_1234
ADD templates/custom_config.cnf /etc/mysql/conf.d/
mysql/templates/custom_config.cnf
[mysqld]
// mysql daemon
max_allowed_packet=128M
default-storage-engine=InnoDB
collation-server = utf8mb4_unicode_ci
init-connect='SET NAMES utf8mb4'
character-set-server = utf8mb4
skip-character-set-client-handshake
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
scripts/drupal9.sh
#!/bin/bash
# Directories
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cd "$parent_path"
# Apache
docker-compose exec web sh -c "sed -i -e 's/www\/html/www\/html\/web/g' /etc/apache2/sites-enabled/000-default.conf"
docker-compose exec web sh -c "sed -i -e 's/www\/html/www\/html\/web/g' /etc/apache2/sites-enabled/default-ssl.conf"
rm -rf ../www;
# Drupal 9 with Composer
cd .. && COMPOSER_MEMORY_LIMIT=-1 composer create-project
drupal-composer/drupal-project:9.x-dev www
./stop.sh
./start.sh
#Drush and database
docker-compose exec --user=1000:1000 web sh -c 'vendor/bin/drush si standard --db-url=mysql://root:Qwerty_1234@db/drupal9 -y'
docker-compose exec web sh -c "ln -s /var/www/html/vendor/bin/drush /usr/local/bin/drush"
Let's get started!
To mount the containers, we will execute the script docker-compose up created in the document root. We created these scripts because they are going to be used a lot.
$ docker-compose up -d
The output of this command will be quite long, but it should end up as follows:
Now we can see which containers are active (two in our case, one for the web server and one for the database):
$ docker ps
Once we have the two containers active, it's time to run the Drupal 9 installation script with composer and drush.
$ ./scripts/drupal9.sh
Containers
- web
- usuario: docker-compose exec --user=1000:1000 web bash
- root: docker exec -it [container_web] bash
- mysql
- root: docker exec -it [container_db] bash