Develop and Deploy SilverStripe 4 applications with Docker - Nginx version

Thor Chen
3 min readAug 3, 2018

Docker is a great tool if we want to set up a deterministic and isolated environment for development and/or deployment, and there is a great article that discussed using Docker with SilverStripe (it also provides an out-of-box Docker image to use, which is configured to use Apache).

But there are two significant features I want to have in the Docker image: using Nginx and adapt to the latest file structure of SilverStripe 4 (that is, the /public folder). If you have the same need and just want a ready-to-use Docker image, here it is. If you want to change some parameters and build your own, this is the repository that contains the dockerfile and supplementary files.

The rest of the article will discuss how I built the image and the caveats of using it.

The dockerfile can be split into the parts below:

FROM ubuntu:18.04

The top line claims that the image should be built upon ubuntu:18.04, which is the latest LTS version of Ubuntu.

RUN apt-get update && apt-get install -y tzdata && rm -rf /var/lib/apt/lists/*
ENV TZ Pacific/Auckland

In this line, I install tzdata and set the timezone to Pacific/Auckland. This might be a place that you may want to tweak for your own, or just change the TZ environment variable later on.

RUN apt-get update && apt-get install -y \
php7.2 \
php7.2-fpm \
php7.2-mbstring \
php7.2-mysql \
php7.2-dom \
php7.2-gd \
php7.2-curl \
php7.2-tidy \
php7.2-intl \
php7.2-xdebug \
nginx \
zip \
unzip \
nano \
composer \
&& rm -rf /var/lib/apt/lists/*

In this line, I install everything we need to run the application (nginx, php) and make further interaction with the container (nano, composer, zip, unzip).

RUN  mkdir /var/www/project
VOLUME /var/www/project

These two lines claim that the image works with a mounted volume at /var/www/project. This should be the root path of a SilverStripe project. When we execute docker run, we will need to specify -v parameter to mount a path in host machine to this entry point.

COPY php-fpm.ini /etc/php/7.2/fpm/php.ini
COPY nginx-site /etc/nginx/sites-enabled/default
COPY xdebug.ini /etc/php/7.2/fpm/conf.d/20-xdebug.ini
COPY start.sh /root/start.sh
RUN chmod a+x /root/start.sh
CMD /root/start.sh
EXPOSE 80

These lines are just some housekeeping tasks, such as configure php.ini, nginx, and xdebug. You may want to modify these files to suit your needs. The start.sh script will start the nginx and php-fpm services once your container started. Finally, it exposes port 80 to the host, so that you can use -p parameter to map the inner port of container to the host.

There are several caveats I want to mention:

  1. The performance of SilverStripe is heavily relying on the disk I/O, and Docker for Mac doesn’t do well in this part due to the difficulty of fulfilling host-container file system consistency. Based on my experience, mounting the volume with delegated mode improves the performance.
  2. When there is a need to access host machine via the network from the inside of the container, you can use host.docker.internal. For example, you can specify the database server in the config file like this: SS_DATABASE_SERVER=”host.docker.internal”
  3. If you want to use SilverStripe-DebugBar, you need to set the check_local_ip option to false due to the Docker’s way of dealing with network.

--

--

Thor Chen

Passionate JavaScript/TypeScript Developer with a Full-stack Background