www.drupaleurope.org

Modular software, modular infrastructure

Jakub Piasecki

Jakub Piasecki

Drupal CTO @linkfactory
traveller
drupal contributor
drupaldocker.org founder

What is this session about

  • Infrastructure as a code
  • Infrastructure's modularity
  • Concerns
  • Best practices
  • Resources

Glossary

  • Application
  • Infrastructure
  • Project
  • What happens when we want to upgrade one of the components
  • What happens when we require new components, such as solr or elasticsearch
  • What happens when we must scale the application
Application heavily depends on the infrastructure, therefore infrastructure must be considered a part of the project.

Infrastructure as is a Code.

It must follow basic coding principles.

If there's only a tool...

  • Vagrantfile
  • Ansible
  • Terraform
  • Docker
  • more...

Dockerfile


							FROM php:7.0-fpm-alpine
							MAINTAINER drupal-docker

							RUN apk add --no-cache --virtual .dd-build-deps libpng-dev libjpeg-turbo-dev postgresql-dev libxml2-dev $PHPIZE_DEPS \
								&& docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \
								&& docker-php-ext-install gd mbstring pdo_mysql pdo_pgsql zip \
								&& docker-php-ext-install opcache bcmath soap \
								&& pecl install redis-3.1.1 \
								&& docker-php-ext-enable redis \
								&& apk add --no-cache libpng libjpeg libpq libxml2 \
								&& apk del .dd-build-deps

							COPY drupal-*.ini /usr/local/etc/php/conf.d/
						

http://drupaldocker.org
https://github.com/drupal-docker
  • Architecture
  • Security
  • Performance

Does Docker follow programming principles?

Let's find out together

DRY

Do not repeat yourself

DRY

Dockerfile


							FROM php:7.0-fpm-alpine
							MAINTAINER drupal-docker

							RUN apk add --no-cache --virtual .dd-build-deps libpng-dev libjpeg-turbo-dev postgresql-dev libxml2-dev $PHPIZE_DEPS \
								&& docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \
								&& docker-php-ext-install gd mbstring pdo_mysql pdo_pgsql zip \
								&& docker-php-ext-install opcache bcmath soap \
								&& pecl install redis-3.1.1 \
								&& docker-php-ext-enable redis \
								&& apk add --no-cache libpng libjpeg libpq libxml2 \
								&& apk del .dd-build-deps

							COPY drupal-*.ini /usr/local/etc/php/conf.d/
            			

KISS

Keep it simple stupid

KISS

Dockerfile


							FROM drupaldocker/php:7.0-fpm-2.x
							MAINTAINER drupal-docker

							RUN apk add --no-cache --virtual .dd-build-deps $PHPIZE_DEPS \
							 && pecl install xdebug-2.6.0beta1 \
							 && docker-php-ext-enable xdebug \
							  && apk del .dd-build-deps

							COPY drupal-*.ini /usr/local/etc/php/conf.d/
            			

YAGNI

You ain't gonna need it

YAGNI

Dockerfile


							FROM php:7.0-alpine
							MAINTAINER drupal-docker

							WORKDIR /var/www/html

							RUN apk add --no-cache --virtual .dd-build-deps libpng-dev libjpeg-turbo-dev postgresql-dev libxml2-dev $PHPIZE_DEPS \
							  && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \
							  && docker-php-ext-install gd mbstring pdo_mysql pdo_pgsql zip \
							  && docker-php-ext-install opcache bcmath soap \
							  && pecl install redis-3.1.1 \
							  && docker-php-ext-enable redis \
							  && curl -sS https://getcomposer.org/installer | php \
							  && mv composer.phar /usr/local/bin/composer \
							  && curl -L -o drush.phar https://github.com/drush-ops/drush-launcher/releases/download/0.4.2/drush.phar \
							  && chmod +x drush.phar \
							  && mv drush.phar /usr/local/bin/drush \
							  && curl -L -o drupal.phar https://drupalconsole.com/installer \
							  && chmod +x drupal.phar \
							  && mv drupal.phar /usr/local/bin/drupal \
							  && echo "export PATH=~/.composer/vendor/bin:\$PATH" >> ~/.bash_profile \
							  && apk add --no-cache sudo git libpng libjpeg libpq libxml2 mysql-client openssh-client rsync patch \
							  && apk del .dd-build-deps

							COPY drupal-*.ini /usr/local/etc/php/conf.d/
							COPY cli/drupal-*.ini /usr/local/etc/php/conf.d/
						

YAGNI

Dockerfile


							FROM php:7.0-fpm-alpine
							MAINTAINER drupal-docker

							RUN apk add --no-cache --virtual .dd-build-deps libpng-dev libjpeg-turbo-dev postgresql-dev libxml2-dev $PHPIZE_DEPS \
							 && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \
							 && docker-php-ext-install gd mbstring pdo_mysql pdo_pgsql zip \
							 && docker-php-ext-install opcache bcmath soap \
							 && pecl install redis-3.1.1 \
							 && docker-php-ext-enable redis \
							 && apk add --no-cache libpng libjpeg libpq libxml2 \
							 && apk del .dd-build-deps

							COPY drupal-*.ini /usr/local/etc/php/conf.d/
						
  • Architecture
  • Security
  • Performance

Elevated privileges

  • Processes in containers should not run as root
  • Only trusted users should be allowed to control your Docker daemon
  • Don't mount docker.sock to untrusted image

Mind your images

  • Tainted, cryptomining images
  • Use official Docker images
  • Use images provided by hosting company
  • Use images provided by the comunity
  • Use images where you can reverse-engineer build process

vendor/name:tag

drupaldocker/php:7.x-cli-2.x

Mind image versions

  • Docker images are (not) versionable
  • Most users use default tag: :latest
  • Lack of semantic versioning slows down innovation
  • As a image creator: decide on tagging convention
  • As a image consumer: never use non-tagged/:latest images

Use networks

Use networks

Use networks

docker-compose.yml


							version: '3.5'
							services:
							  db:
								...
								networks:
								  - back-tier
							  php:
								...
								networks:
								  - back-tier
								  - front-tier
							  web:
								...
								networks:
								  - front-tier
								  - reverse-proxy
							  cli:
								...
								networks:
								  - back-tier
							networks:
							  front-tier:
							  back-tier:
							  reverse-proxy:
							    external:
							      name: my-reverse-proxy
						
  • Architecture
  • Security
  • Performance

Avoid multipurpose containers


							FROM php:7.0-alpine
							MAINTAINER drupal-docker

							WORKDIR /var/www/html

							RUN apk add --no-cache --virtual .dd-build-deps libpng-dev libjpeg-turbo-dev postgresql-dev libxml2-dev $PHPIZE_DEPS && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr && docker-php-ext-install gd mbstring pdo_mysql pdo_pgsql zip && docker-php-ext-install opcache bcmath soap && pecl install redis-3.1.1 && docker-php-ext-enable redis && apk add --no-cache sudo git libpng libjpeg libpq libxml2 mysql-client openssh-client rsync patch && apk del .dd-build-deps

							RUN apk add --no-cache nodejs

							RUN curl -sS https://getcomposer.org/installer | php \
							  && mv composer.phar /usr/local/bin/composer \
							  && curl -L -o drush.phar https://github.com/drush-ops/drush-launcher/releases/download/0.4.2/drush.phar \
							  && chmod +x drush.phar \
							  && mv drush.phar /usr/local/bin/drush \
							  && curl -L -o drupal.phar https://drupalconsole.com/installer \
							  && chmod +x drupal.phar \
							  && mv drupal.phar /usr/local/bin/drupal \
							  && echo "export PATH=~/.composer/vendor/bin:\$PATH" >> ~/.bash_profile

							COPY drupal-*.ini /usr/local/etc/php/conf.d/
							COPY cli/drupal-*.ini /usr/local/etc/php/conf.d/
						

Avoid multipurpose containers


							FROM nodejs:8-alpine
							MAINTAINER yourself

							# Add some global extensions if needed
						

Avoid multipurpose containers

docker-compose.yml


							version: '3.5'
							services:
							  phpcli:
								image: drupaldocker/php:7.1-cli-2.x
								command: /bin/sh
								...
							  nodejs:
								image: nodejs:8-alpine
								command: cd web/themes/custom/mytheme && npm run-script watch
								...
						

Layer caching

https://github.com/amazeeio/drupal-example


							FROM amazeeio/php:7.2-cli-drupal

							COPY composer.json composer.lock /app/
							COPY scripts /app/scripts
							RUN composer install --no-dev
							COPY . /app

							# Define where the Drupal Root is located
							ENV WEBROOT=web
						

Multistage builds

php - cli


							FROM amazeeio/php:7.2-cli-drupal

							COPY composer.json composer.lock /app/
							COPY scripts /app/scripts
							RUN composer install --no-dev
							COPY . /app

							# Define where the Drupal Root is located
							ENV WEBROOT=web
						

Multistage builds

php - fpm


							FROM amazeeio/php:7.2-fpm

							COPY composer.json composer.lock /app/
							COPY scripts /app/scripts
							RUN composer install --no-dev
							COPY . /app

							# Define where the Drupal Root is located
							ENV WEBROOT=web
						

Multistage builds

php - fpm


							FROM cli_image_we_just_built as cli

							FROM amazeeio/php:7.2-fpm

							COPY --from=cli /app /app
						

Så: Can we think of infrastructure as of code?

YES!

Så: Should we start thinking of infrastructure as of code!

DEFINITELY!

Where to start?

Nanos gigantum humeris insidentes
Bernard of Chartres
Standing on the shoulders of giants
Bernard of Chartres

Knowledge base


http://drupaldocker.org
https://github.com/drupal-docker

Summary

If you have to take only 5 things from this session

  • Think inheritance & composition
  • Think vendor credibility
  • Think image size
  • Think layers
  • Never use :latest