How to deploy Joomla 3.9.27 in docker swarm behind Caddy v2.4.
- Rajasekhar Gundala
- 03 Jul, 2021
Joomla is a free and open-source content management system (CMS) for publishing web content on websites. Web content applications include discussion forums, photo galleries, e-Commerce, and user communities, and numerous other web-based applications.
In this post, I am going to show you how to deploy Joomla, a free and open-source content management system (CMS) for publishing web content behind Caddy 2.4.3 to our Docker Swarm Cluster using the Docker Compose tool.
Web content applications include discussion forums, photo galleries, e-Commerce, and user communities, and numerous other web-based applications.
Joomla is developed by a community of volunteers supported with the legal, organisational and financial resources of Open Source Matters, Inc.
Let’s start with actual deployment…
Prerequisites
Please make sure you should fulfill the below requirements before proceeding to the actual deployment.
- Docker Swarm Cluster with GlusterFS as persistent tool.
- Caddy as reverse proxy to expose micro-services to external.
- Database stack to host application databases.
Introduction
Joomla is one of the world’s most popular software packages. It is used to build, organize, manage and publish content for small businesses, governments, non-profits, and large organizations worldwide.
Joomla is supported by a large ecosystem and powers:
- Nearly 2 Millions active websites
- Over 9% of all known business websites
- Over 6% of the CMS Market World wide
- Over 3% of the entire Web
Joomla offers a great opportunity to grow your business by building websites and applications.
The rock solid code base and large global community will help you to build web sites fast.
Whether you are looking to build websites or develop applications, develop templates or extensions or something completely new based on our framework, with Joomla, the possibilities are endless.
Please go through the below links if you want to know more about Joomla
Joomla Features
Joomla is written in PHP, uses object-oriented programming techniques and software design patterns, stores data in a MySQL database.
Joomla includes features such as page caching, RSS feeds, blogs, search, and support for language internationalisation.
It is built on a model–view–controller web application framework that can be used independently of the CMS.
Over 6,000 extensions are available from the Joomla website and more are available from other sources.
As of 2021, it was estimated to be the third most used CMS on the Internet, after WordPress and Shopify.
Here are some of the features that we think that you’ll love
- SEO (Search engine optimisation) out of the box
- Multi-User Permission Level
- Mobile Friendly
- Unlimited Design
- Multilingual
- Flexible & Fully Extensible
If you want to learn more about Joomla features, please go through the Official Joomla Link.
Persist Joomla Data
Containers are fast to deploy and make efficient use of system resources. Developers get application portability and programmable image management and the operations team gets standard run time units of deployment and management.
With all the known benefits of containers, there is one common misperception that the containers are ephemeral, which means if we restart the container or in case of any issues with it, we lose all the data for that particular container. They are only good for stateless micro-service applications and that it’s not possible to containerize stateful applications.
I am going to use GlusterFS to overcome the ephemeral behavior of Containers.
I already set up a replicated GlusterFS volume to have data replicated throughout the cluster if I would like to have some persistent data.
The below diagram explains how the replicated volume works.
Volume will be mounted on all the nodes, and when a file is written to the
/mnt
partition, data will be replicated to all the nodes in the Cluster
Note
Persistent application state or data needs to survive application restarts and outages. We are storing the data or state in GlusterFS and had periodic backups performed on it.
Joomla site will be available if something goes wrong with any of the nodes on our Docker Swarm Cluster. The data will be available to all the nodes in the cluster because of GlusterFS Replicated Volume.
I am going to create a folder joomla
in /mnt
directory to map container volume /var/www/html
.
cd /mnt
sudo mkdir -p joomla
Tip
Prepare Joomla Environment
I am going to use docker-compose to prepare the environment file for deploying Joomla. The compose file is known as YAML ( YAML stands for Yet Another Markup Language) and has extension .yml or .yaml
I am going to create application folders in
/opt
directory on manager node in our docker swarm cluster to store configuration files, nothing but docker compose files (.yml or .yaml).
Also, I am going to use the caddy overlay network created in the previous Caddy post.
Now it’s time to create a folder, joomla
in /opt
directory to place configuration file, i.e, .yml
file for Joomla.
Use the below commands to create the folder.
Go to /opt
directory by typing cd /opt
in Ubuntu console
make a folder, joomla
in /opt
with sudo mkdir -p joomla
Let’s get into joomla
folder by typing cd joomla
Now create a docker-compose file inside the WordPress folder using sudo touch joomla.yml
Open joomla.yml
docker-compose file with nano editor using sudo nano joomla.yml
and copy and paste the below code in it.
Joomla Docker Compose
Here is the docker-compose file for Joomla. I am going to utilize the MariaDB stack as a back-end database for it that was deployed earlier.
version: "3.7"
services:
joomla:
image: joomla
depends_on:
- maindb
volumes:
- /mnt/joomla:/var/www/html
environment:
- JOOMLA_DB_HOST=maindb:3306
- JOOMLA_DB_USER=joomla
- JOOMLA_DB_NAME=joomladb
- JOOMLA_DB_PASSWORD=somesecret
networks:
- caddy
ports:
- "8009:8080"
deploy:
placement:
constraints: [node.role == worker]
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
volumes:
joomla:
driver: "local"
networks:
caddy:
external: true
Joomla does not support secrets as of now.
Caddyfile – Joomla
The Caddyfile is a convenient Caddy configuration format for humans.
Caddyfile is easy to write, easy to understand, and expressive enough for most use cases.
Please find Production-ready Caddyfile for Joomla.
Learn more about Caddyfile here to get familiar with it.
{
email you@example.com
default_sni joomla
cert_issuer acme
# Production acme directory
acme_ca https://acme-v02.api.letsencrypt.org/directory
# Staging acme directory
#acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
servers {
protocol {
experimental_http3
allow_h2c
strict_sni_host
}
timeouts {
read_body 10s
read_header 10s
write 10s
idle 2m
}
max_header_size 16384
}
}
joomla.example.com {
log {
output file /var/log/caddy/joomla.log {
roll_size 20mb
roll_keep 2
roll_keep_for 6h
}
format console
level error
}
root * /var/www/html
reverse_proxy joomla:80
encode gzip zstd
}
Please go to Caddy Post to get more insight to deploy it in the docker swarm cluster.
Final Joomla Docker Compose (Including caddy server configuartion)
Please find the full docker-compose file below. You can deploy as many sites as you want using it.
Don’t forget to map site data directories like
/mnt/joomla:/var/www/html
in Caddy configurationcaddy.yml
.
I already wrote an article Caddy in Docker Swarm. Please go through if you want to learn more.
version: "3.7"
services:
caddy:
image: tuneitme/caddy
ports:
- "80:80"
- "443:443"
networks:
- caddy
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- /mnt/caddydata:/data
- /mnt/caddyconfig:/config
- /mnt/caddylogs:/var/log/caddy
- /mnt/joomla:/var/www/html
deploy:
placement:
constraints:
- node.role == manager
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
joomla:
image: joomla
depends_on:
- maindb
volumes:
- /mnt/joomla:/var/www/html
environment:
- JOOMLA_DB_HOST=maindb:3306
- JOOMLA_DB_USER=joomla
- JOOMLA_DB_NAME=joomladb
- JOOMLA_DB_PASSWORD=somesecret
networks:
- caddy
ports:
- "8009:8080"
deploy:
placement:
constraints: [node.role == worker]
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
volumes:
caddydata:
driver: "local"
caddyconfig:
driver: "local"
caddylogs:
driver: "local"
joomla
driver: "local"
networks:
caddy:
external: true
Here I used a custom Caddy docker container with plugins, like Cloudflare DNS, Caddy Auth Portal etc…
Please find the custom caddy docker image below.
Deploy Joomla Stack using Docker Compose
Now it’s time to deploy our docker-compose file above, joomla.yml
using the below command
docker stack deploy --compose-file joomla.yml joomla
In the above command, you have to replace joomla.yml
with your docker-compose file name and Joomla with whatever name you want to call this particular application.
With docker compose in docker swarm what ever we are deploying is called as docker stack and it has multiple services in it as per the requirement.
As mentioned earlier I named my docker-compose as joomla.yml
and named my application stack as joomla
Check the status of the stack by using docker stack ps joomla
Check caddy
stack logs using docker service logs joomla_joomla
One thing we observe is that it automatically re-directs to https
with Letsencrypt generated certificate. The information is stored in /data a directory.
I will be using this
caddy stack
as a reverse proxy / load balancer for the applications I am going to deploy to Docker Swarm Cluster.
Also I use docker network
caddy
to access the applications externally.
Access / Install Joomla
Now open any browser and type joomla.example.com
to access the site. it will automatically be redirected to https://joomla.example.com/installation/index.php ( Be sure to replace example.com with your actual domain name
).
Warning
joomla.example.com
) in your DNS Management Application.Please find below images for your reference.
Deployment of Joomla behind Caddy in our Docker Swarm is successful
If you enjoyed this tutorial, please give your input/thought on it by commenting below. It would help me to bring more articles that focus on Open Source to self-host.
Stay tuned for other deployments in coming posts… 🙄