Hosting Joomla with Docker and Memcached

In this post I’ll show you how you can quickly and easily setup a fast Joomla! site running in Docker, and using Memcached for caching. We’ll also be using Docker Compose to make managing the relationships between containers easier.

Docker Compose makes the task of managing multiple Docker containers (in our case, Apache, MySQL, and Memcached) much easier than doing them individually. It also makes it easier if you want to develop this site on your local environment and later push it to a remote server with docker — although that’s a topic for another tutorial.

Install Docker and Docker Compose

If you haven’t installed Docker on your machine yet, follow these instructions. Check out the docs for your environment. The instructions for Ubuntu 14.04 (LTS) are below. Be sure to run them as root! If you already have Docker skip on to installing Docker Compose if you don’t already have it.

apt-get update
apt-get install apt-transport-https ca-certificates
apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" >> /etc/apt/sources.list.d/docker.list
apt-get update
apt-get install linux-image-extra-$(uname -r) apparmor docker-engine
service docker start

Next install docker compose:

curl -L https://github.com/docker/compose/releases/download/1.6.2/docker-compose-`uname -s`-`uname -m` >> /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose -v

You should see docker-compose output its version information. Something like: docker-compose version 1.6.2, build 4d72027.

Prepare Joomla and Docker files

Next up we need to create the docker compose files and get the Joomla files ready to use:

mkdir -p ./mysite/website_source ./mysite/mysql
cd mysite

Create a Dockerfile

Next create a Dockerfile (e.g. vim Dockerfile) that tells Docker to base your webserver code off of a PHP5 image, and include your source code.

FROM php:5-fpm

# Install dependencies
RUN apt-get update -y && apt-get install -y php5-json php5-xmlrpc libxml2-dev php5-common zlib1g-dev libmemcached-dev

# Install mysqli extension
RUN docker-php-ext-install mysqli

# Install memcache extension
RUN pecl install memcache && docker-php-ext-enable memcache

# Add sources to image
ADD ./website_source /site

Create the Docker Compose config file

And then create the docker-compose.yml file (e.g. vim docker-compose.yml). The docker-compose file lays out how your website is structured. It says that your site is composed of three services: web which is an Apache/PHP image with your source code baked in, db which is the MySQL database, and cache which is the memcached image. It also tells docker how to connect these docker containers so that they can communicate with each other. Lastly, it tells docker to bind port 80 to the web container. Lastly, the mysql container will mount the mysql directory on the host and place the database files there. This way if the container is removed or anything you don’t lose your database.

version: '2'
services:
  web:
    build: .
    command: php -S 0.0.0.0:80 -t /site
    ports:
      - "80:80"
    depends_on:
      - db
      - cache
    volumes:
      - ./website_source:/site
  db:
    image: orchardup/mysql
    environment:
      MYSQL_DATABASE: joomla
      MYSQL_ROOT_PASSWORD: my_secret_pass
    volumes:
      - ./mysql:/var/lib/mysql
  cache:
    image: memcached

By sure to replace my_secret_pass with a secure password for the mysql user!

Get Joomla! Sources

Now that you have a Dockerfile and docker-compose.yml you just need to get the sources for Joomla and install them:

wget https://github.com/joomla/joomla-cms/releases/download/3.4.8/Joomla_3.4.8-Stable-Full_Package.zip
unzip Joomla*.zip -d ./website_source
mv ./website_source/htaccess.txt ./website_source/.htaccess
mv ./website_source/robots.txt.dist ./website_source/robots.txt

Note that if you don’t have unzip installed you can install it by running apt-get install unzip.

Build and Run Docker Containers

Now that you have everything setup its time to test everything by building and running the docker containers. This is accomplished with docker-compose:

docker-compose build
docker-compose up

This will run the whole application in the foreground of your terminal. Go to http://localhost:80 and complete the Joomla Installer! You’ll use the mysql username and password you specified in your docker-compose.yml file. The mysql host is also specified in the docker-compose.yml file as the name of the database service. In our case, this is db. Once you’re finished you can use CTRL+C to stop the containers.

Configuring Joomla Installation

Configuring Joomla for Memcached

Now that your Joomla site is running under docker it’s time to connect it to the memcached server to make sure that things stay speedy!

To enable memcached edit website_sources/configuration.php and replace

public $caching = '0';
public $cache_handler = 'file';

with this:

public $caching = '2';
public $cache_handler = 'memcache';
public $memcache_server_host = 'cache';
public $memcache_server_port = '11211'

Add your changes to the container image with docker-compose build and then run docker-compose up, log into the Joomla administration page and go to “Global Configuration” -> “System”. You can tweak the settings under “Cache Settings” or leave them as they are.

Joomla Cache Settings

Running on Server Start

The last step in setting up a web application with docker is to have the web server started when the server starts.

Create the file /etc/init/mydockersite.conf with the contents:

description "Website Docker Compose"
author "MichaelBlouin"
start on filesystem and started docker
stop on runlevel [!2345]
respawn
script
  /usr/local/bin/docker-compose -f /var/www/mysite/docker-compose.yml up
end script

Be sure to replace /var/www/mysite/docker-compose.yml with the full path to your docker-compose.yml!

Save the file and run the following to register the service, and to start it:

initctl reload-configuration
service mydockersite start

And there you go! You can view logs for your service by running docker-compose logs while in the same directory as your docker-compose.yml or by reading the logfile at /var/log/upstart/mydockersite.log.

Congrats, you now have a speedy Joomla! install running in Docker! If you liked this tutorial consider following @michaelblouin on Twitter!

, ,

6 Responses to Hosting Joomla with Docker and Memcached

  1. ignaciolflores April 4, 2016 at 1:10 pm #

    In order to get your application running on start up, you can use “restart: always” in docker-compose.yml

    • Michael Blouin April 13, 2016 at 12:06 pm #

      Thanks for the tip! I wasn’t aware of that

  2. Peter Perhac October 8, 2016 at 12:17 pm #

    Lovely! Thanks for neat and working instructions to setup a joomla installation with memcached and all that jazz. took a couple minutes and worked! unlike other manuals on the interwebz

    • Michael Blouin October 8, 2016 at 12:22 pm #

      I’m glad it helped! That’s the magic of Docker – it should always work the same wherever you run it if done correctly!

  3. Giancarlo Mascetti February 14, 2017 at 11:34 pm #

    Hi Michael,
    It works perfectly!
    Any suggestion how to add letsencrypt certificate in order to use Joomla via HTTPS?

    Thanks in advance…

    • Michael Blouin February 15, 2017 at 11:52 am #

      Hey Giancarlo,

      I’m working on this problem myself. If you only have a single docker machine (all containers on the same physical machine) then I think the steps are as follows:
      1. Create an image that runs a foreground version of cron
      2. Add letsencrypt to that image and configure it to renew certs daily using cron config
      3. Create a folder that contains the SSL certs in /certs/domain/ssl
      4. Create a folder for ACME challenges in /certs/domain/acme
      5. Mount the SSL and acme folders for the domain in the Joomla container so that the acme folder is served when .well-known is requested from the domain
      6. Do the initial cert request in the letsencrypt container
      7. Configure Joomla to use that cert.

      I am working on a blog post that would provide examples of this, although it’s also going to solve the issue of doing this on a Docker Swarm cluster with many instances of the web server so it’s a tad more complicated. Stay tuned!

Leave a Reply

Proudly made in Canada