• Docker virtual machine
    • Docker Version 1.6.2 or later
    • Hosts Dockerfile images
  • Nginx load balancer
    • Accepts http requests and redirects them to https. Serves as a proxy to the Docker server.

Lets create a Joomla site for Voyager Elementary


Google took me to this repository, it has a great Dockerfile and scripts pre-configured with Nginx, Joomla and MariaDB. It was slightly out of date, and I had some custom configurations I needed, so I forked it.

Git clone  
cd joomla-docker  
docker build -t psd/joomla .  
  • psd/joomla: the name of the docker image.


Given the docker build completes successfully, create a new docker container from the joomla image.

docker run -d -p 5125:80 --name vge3x -e "" psd/joomla setup-joomla  
  • p: Port forwarding, 5125 is the Docker server port to forward to port 80 of the new container. Make sure you don't already have a docker container using the port you provide.

  • name: The Docker name, used accross the board by Docker. Without this docker will generate a random name for you.

  • e: Enviromental Variables, take a look in some of the scripts to see more variables to set. These are system wide during the Dockerfile deployment.

  • psd/joomla: make sure this matches with the image name given above.

  • setup-joomla: this is the script that is ran after the Dockerfile is loaded.

Check to ensure your container came up without issues:

#docker ps
CONTAINER ID        IMAGE                       COMMAND                CREATED             STATUS              PORTS                                   NAMES  
bdba84ce03d3        psd/joomla:latest           "/tmp/ setup   3 seconds ago       Up 2 seconds        22/tcp, 443/tcp,>80/tcp   vge3x  
c341a0700df8        psd/joomla:latest           "/tmp/ setup   5 days ago          Up 5 days           22/tcp, 443/tcp,>80/tcp   gms3x  
81393b9511ec        psd/joomla:latest           "/tmp/ setup   5 days ago          Up 5 days           22/tcp, 443/tcp,>80/tcp   ves3x  

if you run curl localhost:5125 a downloaded index.html from Joomla should appear in your current directory. cat index.html to ensure it isn't an Nginx error page.


The database requires some user interaction. The passwords and database name is not set in the script as this could be sensitive data. To run the script type the following command.

docker exec -i -t vge3x /tmp/

  • i: interactive, this allows us to interact with the script as if it were running on the local machine.

  • vge3x: name of the container

  • /tmp/ name of the script to execute.

After running the exec command, you will be prompted for the following information.

A username for the mysql user
Password for the new user
Password again for the new user
Set root password
Remove anonymous users? [Y/n]
Disallow root login remotely? [Y/n]
Remove test database and access to it? [Y/n]
Reload privilege tables now? [Y/n]

Web Traffic

By default, on the Docker container I am hosting on port 80. This is because we use a load balancer to handle external web requests and to hand out ssl certificates. Nginx is configured to load all files within /etc/nginx/sites-enabled. Standard practice is to create your sites inside /etc/nginx/sites-availible, then symlink them to the adjacent folder. This allows you to link and unlink sites as necessary.

Configuring Nginx

Create a new nginx config file vim /etc/nginx/sites-availible/ with the following contents (code blocks only).

server {  
  listen 80;
  rewrite ^/(.*)$1 permanent;

This listens for port 80 trafic and redirects requests to port 443 traffic, retaining the full URL.

server {  
  listen 443 ssl;

Ensuring port 443
Server name the DNS name to conditionaly watch for this server.

  location / {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
    dav_methods PUT DELETE;
    proxy_set_header HOST $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Headers need to be specific for nginx inside the docker container to accept forwarded requests. These work, for some reason or another.


Pass the request off to the local IP of the docker server on the port of the vge docker container.

    fastcgi_read_timeout 60000;
    fastcgi_send_timeout 60000;
    send_timeout 60000;
    proxy_read_timeout 60000;
    proxy_send_timeout 60000;

Timeout after 1 minute and close.

symlink your new nginx configuration
ln /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

restart the nginx service

service nginx restart

Final Touches

Now make sure the DNS name is actually pointing to the load balancer, visit the address and you should see a Joomla setup screen. Remember the mysql user and passwords you setup for the database. The default database name is joomla_db