How to set up Docker for Sylius projects

Joaquín Ruiz - 21st April 2019

How to set up Docker for Sylius projects
  • Date:   21st April 2019
  • Category:

      Docker

  • Comments:

      0

Why using Docker for Sylius projects? I used to develop my projects locally, installing all the dependencies and managing all the configuration myself… That’s OK when you code only under one framework, one technology. But then you want to upgrade your OS (Scary time for Mac OS users right?)

The Docker platform is the only container platform to build, secure and manage the widest array of applications from development to production both on premises and in the cloud. 

docker.com


Then Docker came to the rescue. In this post I will explain how to configure Docker to use with a new (or existing) Sylius project.

Set-up Docker inside your Sylius project

First of all, download your current Sylius project, or a new one from the Official Repository.

git clone https://github.com/Sylius/Sylius-Standard.git

Then, check that you have docker-compose installed

cd Sylius-Standard
docker-compose --version

If you don’t have docker-compose installed, install it! https://docs.docker.com/compose/install/

1. Create our Docker Compose configuration file

The official docker repository comes with a docker-compose.yml file. But we will create our own following the guidelines from Sylius.

First create a docker/ folder on your project to keep all the configurations

Sylius structure with Docker | Tutorial how to set up Docker for a Sylius project
Sylius structure with Docker | Tutorial how to set up Docker for a Sylius project

Then create a docker-compose.yml file inside that folder.

This is how our file will look like :

version: '3.4'

services:
  php:
    build: php
    depends_on:
      - mysql
    environment:
      - APP_ENV=dev
      - APP_DEBUG=1
      - APP_SECRET=EDITME
      - DATABASE_URL=mysql://sylius:nopassword@mysql/sylius
      - MAILER_URL=smtp://localhost
      - PHP_DATE_TIMEZONE=${PHP_DATE_TIMEZONE:-UTC}
    volumes:
      - ../:/srv/sylius:rw,cached
      - ../public:/srv/sylius/public:rw,delegated
      - ../public/media:/srv/sylius/public/media:rw

  mysql:
    image: percona:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-nopassword}
      - MYSQL_DATABASE=sylius
      - MYSQL_USER=sylius
      - MYSQL_PASSWORD=${MYSQL_PASSWORD:-nopassword}
    volumes:
      - ./mysql/data:/var/lib/mysql:rw,delegated
    ports:
      - "3306:3306"

  nodejs:
    build: nodejs
    depends_on:
      - php
    environment:
      - GULP_ENV=dev
      - PHP_HOST=php
      - PHP_PORT=9000
    volumes:
      - ../:/srv/sylius:rw,cached
      - ../public:/srv/sylius/public:rw,delegated
    ports:
      - "35729:35729"

  nginx:
    build: nginx
    depends_on:
      - php
      - nodejs
    volumes:
      - ../public:/srv/sylius/public:ro
      - ../public/media:/srv/sylius/public/media:ro
    ports:
      - "80:80"

  mailhog:
    image: mailhog/mailhog:latest
    environment:
      - MH_STORAGE=maildir
    volumes:
      - ./mailhog/maildir:/maildir:rw,delegated
    ports:
      - "8025:8025"

volumes:
  mysql-data:
  public-media:

There are five services defined in that file: PHP, MySQL, NodeJS, Nginx, and MailHog.

After that, we need to create a Dockerfile for each build (PHP, NodeJS and Nginx), for MySQL and MailHog we just get a default image.

This is how our Docker folder will look like:

Docker folder structure | Tutorial how to set up Docker for a Sylius project
Docker folder structure | Tutorial how to set up Docker for a Sylius project

2. Create the Dockerfile files

PHP

Create a file named Dockerfile inside the docker/php/ folder.

Following the official Sylius docs, our file should look like this:

ARG PHP_VERSION=7.2
FROM php:${PHP_VERSION}-fpm-alpine

RUN apk add --no-cache \
		acl \
		file \
		gettext \
		git \
		mariadb-client \
	;

ARG APCU_VERSION=5.1.11
RUN set -eux; \
	apk add --no-cache --virtual .build-deps \
		$PHPIZE_DEPS \
		coreutils \
		freetype-dev \
		icu-dev \
		libjpeg-turbo-dev \
		libpng-dev \
		libtool \
		libwebp-dev \
		libzip-dev \
		mariadb-dev \
		zlib-dev \
	; \
	\
	docker-php-ext-configure gd --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include --with-webp-dir=/usr/include --with-freetype-dir=/usr/include/; \
	docker-php-ext-configure zip --with-libzip; \
	docker-php-ext-install -j$(nproc) \
		exif \
		gd \
		intl \
		pdo_mysql \
		zip \
	; \
	pecl install \
		apcu-${APCU_VERSION} \
	; \
	pecl clear-cache; \
	docker-php-ext-enable \
		apcu \
		opcache \
	; \
	\
	runDeps="$( \
		scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \
			| tr ',' '\n' \
			| sort -u \
			| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
	)"; \
	apk add --no-cache --virtual .sylius-phpexts-rundeps $runDeps; \
	\
	apk del .build-deps

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
COPY php.ini /usr/local/etc/php/php.ini
COPY php-cli.ini /usr/local/etc/php/php-cli.ini

ENV COMPOSER_ALLOW_SUPERUSER=1
RUN set -eux; \
	composer global require "hirak/prestissimo:^0.3" --prefer-dist --no-progress --no-suggest --classmap-authoritative; \
	composer clear-cache
ENV PATH="${PATH}:/root/.composer/vendor/bin"

WORKDIR /srv/sylius

We also copy in this folder the php.ini and php-cli.ini files that come with the official repository.

php/php.ini

apc.enable_cli = 1
date.timezone = ${PHP_DATE_TIMEZONE}
opcache.enable_cli = 1
session.auto_start = Off
short_open_tag = Off

# http://symfony.com/doc/current/performance.html
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.memory_consumption = 256
realpath_cache_size = 4096K
realpath_cache_ttl = 600

post_max_size = 6M
upload_max_filesize = 5M

php/php-cli.ini

apc.enable_cli = 1
date.timezone = ${PHP_DATE_TIMEZONE}
opcache.enable_cli = 1
session.auto_start = Off
short_open_tag = Off

# http://symfony.com/doc/current/performance.html
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.memory_consumption = 256
realpath_cache_size = 4096K
realpath_cache_ttl = 600

memory_limit = 2G
post_max_size = 6M
upload_max_filesize = 5M

NodeJS

Create a file named Dockerfile inside docker/nodejs/.

ARG NODE_VERSION=10
FROM node:${NODE_VERSION}-alpine

WORKDIR /srv/sylius

RUN set -eux; \
	apk add --no-cache --virtual .build-deps \
		g++ \
		gcc \
		git \
		make \
		python \
	;

WORKDIR /srv/sylius

Nginx

And finally, create a file named Dockerfile inside docker/nginx/.

ARG NGINX_VERSION=1.15
FROM nginx:${NGINX_VERSION}-alpine

COPY conf.d/default.conf /etc/nginx/conf.d/

We also copy in this folder the conf.d/default.conf file that come with the official repository.

/nginx/conf.d/default.conf

server {
    root /srv/sylius/public;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass php:9000;

        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        # FPM.
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        internal;
    }

    location ~ \.php$ {
      return 404;
    }

    client_max_body_size 6m;
}

3. Build the Containers.

docker-compose build

Docker will download all needed files and will build PHP, NodeJS, Nginx and MySql images which you will be able to run later on.

4. Start the Containers.

docker-compose up -d
Docker Compose Up | Tutorial how to set up Docker for a Sylius project
Docker Compose Up | Tutorial how to set up Docker for a Sylius project

This is what you should see on your terminal screen.

Install Sylius

1. Composer Dependencies

To run the composer install command inside the Docker execute the following command in your terminal

docker-compose run php composer install

2. Install Sylius

And finally, if it is your first time, install Sylius.

docker-compose run php php bin/console sylius:install
Sylius installed with Docker | Tutorial how to set up Docker for a Sylius project
Sylius installed with Docker | Tutorial how to set up Docker for a Sylius project

And tada! we have our Sylius working!

Sylius frontend with Docker | Tutorial how to set up Docker for a Sylius project
Sylius frontend with Docker | Tutorial how to set up Docker for a Sylius project

3. Install the assets

And finally, we’ll use the NodeJS container to see a fully functional front-end, by installing its assets.

 docker-compose run nodejs yarn install
docker-compose run nodejs yarn build

And there we go, we have our Sylius fully functional working with Docker! 🙂

Sylius fully functional with Docker | Tutorial how to set up Docker for a Sylius project
Sylius fully functional with Docker | Tutorial how to set up Docker for a Sylius project

The Author

Joaquín Ruiz (aka Joki)
Joki is a Computer Engineer, Senior Full-Stack Developer and Lead Developer, specialized in web and e-commerce. Joki has also a wide international experience as freelance and working in agencies.