Create your Joomla website using Docker - Part 2
Create your persistent Joomla website with Docker in one command. This Part 2 guide focuses on advanced automation using compose.yaml and makefile.
This article is part of the Create your joomla website using Docker series:
Changelog

This guide details how to automate local Joomla development with Docker by
combining compose.yaml, .env, and makefile configurations to deploy
fully configured sites with a single command. It explains how to bypass the
standard installation wizard by pre-defining environment variables and
demonstrates how to manage multiple isolated projects with different Joomla
and PHP versions simultaneously on one machine. The tutorial provides specific
configuration examples to ensure data persistence and enable conflict-free
operation across concurrent instances.
At the end of 2023, I wrote a very long post about using Joomla with Docker: Create your Joomla website using Docker - Part 1.
It was a step-by-step introduction to Docker and the creation of a local Joomla-based website.
I explained, at length, the various steps involved in creating a website, choosing a database engine (MySQL, MariaDB or PostgreSQL), choosing a specific version of Joomla / database engine, the type of volumes (should the site and database be kept in RAM or on the hard disk (i.e. the notion of volumes)) and many other things such as choosing the port for the website, creating an alias (something like http://my_project.local instead of http://127.0.0.1). I strongly urge you to read or re-read this article before starting this one.
Caution
Here is the link to that article : Create your Joomla website using Docker - Part 1.
As Docker and Joomla are evolving rapidly, I propose here to start from where we were and see what has changed since then.
We're also going to take automation a step further, making much greater use of the concept of makefile and a configuration file called .env.
Resultβ
That's the whole deployment: Docker pulls Joomla, PHP, Apache and MySQL, wires them together, and a minute later the site is reachable in the browser β no manual database setup, no editing PHP files by hand.

Hey! did you notice?
We've created our Joomla website by just running one command. Don't trust? Open your browser and surf to http://127.0.0.1:8080.
Why it worksβ
compose.yaml,.envandmakefiletogether become a single point of configuration: one file to change the Joomla or PHP version, one for the port number and project name, andmaketargets so nobody has to remember the rawdocker composeincantations.depends_on+healthcheckincompose.yamlmake Joomla wait for the database to actually be ready before starting its own installation β no crash-on-boot race condition.- Because the whole setup lives in three small files, the same recipe scales to several isolated projects (different Joomla/PHP/MySQL versions) on the same machine, as the Advanced configuration and Starting three different projects sections below show.
Create the three configuration filesβ
In contrast to article Create your Joomla website using Docker - Part 1, where I began by explaining a few concepts before moving on to discuss the subject, let's do the opposite here: let's start with the three files we are going to use, and then see how they work. Please don't try too hard to understand the contents of the files; we'll come back to that later.
Create the three files in a folder on your hard disk for the time being (f.i. in /tmp/joomla), so that we can quickly get to the heart of the matter: creating a Joomla site with just one line of commands to run on your computer.
Our orchestration file: compose.yamlβ
We need a file that will explain to Docker how we want to configure Joomla and, also, the type of database we want.
Our orchestration file will also inform Docker that we want the Joomla site to be persistent, i.e. the files to be saved on our hard disk. The same applies to the database.
We need to do this so that, if we voluntarily remove the Docker container to release memory f.i., we want that the Joomla website is saved on disk. So, next time we will wake up our site, files and database tables will be restored.
Persistence
There are two types of persistence, the one managed natively by Docker (intern volumes) or the one where we'll see the files in our project's folder (mounted volumes). We'll opt for the latter. See my article Using volumes with Docker, use cases if you want to learn more.
We're also going to define a dependency (based on depends_on and healthcheck): Joomla must wait for the database server to be ready before starting its installation (in fact, if the Joomla installer tries to access MySQL before the system is even loaded, our project will crash during container loading).
As you can see, our compose.yaml file is of tremendous importance for the proper definition of our project.
Note
In recent months, the name of the file to be used has changed from docker-compose.yaml to compose.yaml; the old name is still supported for now, but might as well use the new one. See docs.docker.com if you want more info about this change.
Please create a new folder (f.i. mkdir /tmp/joomla && cd $_) on your hard disk and create the compose.yaml file with this content:
name: ${PROJECT_NAME:-your-project-name}
services: joomla: image: joomla:${JOOMLA_VERSION:-latest} container_name: ${CONTAINER_PREFIX:-joomla}-app restart: always ports: - ${WEB_PORT:-8080}:80 environment: - JOOMLA_DB_HOST=joomladb - JOOMLA_DB_NAME=${DB_NAME:-joomla} - JOOMLA_DB_PASSWORD=${DB_PASSWORD:-examplepass} - JOOMLA_DB_USER=${DB_USER:-joomla} depends_on: joomladb: condition: service_healthy user: ${UID:-1000}:${GID:-1000} volumes: - ./joomla_data:/var/www/html networks: - joomla_network
joomladb: image: mysql:${MYSQL_VERSION:-latest} container_name: ${CONTAINER_PREFIX:-joomla}-db restart: always ports: - ${MYSQL_PORT-:3306}:3306 environment: - MYSQL_DATABASE=${DB_NAME:-joomla} - MYSQL_PASSWORD=${DB_PASSWORD:-examplepass} - MYSQL_RANDOM_ROOT_PASSWORD='1' - MYSQL_USER=${DB_USER:-joomla} healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] timeout: 20s retries: 10 user: ${UID:-1000}:${GID:-1000} volumes: - ./db_data:/var/lib/mysql networks: - joomla_network
networks: joomla_network:This Docker Compose file sets up a two-container application: a Joomla web server and a MySQL database. It uses environment variables with fallback defaults so you can customize things like port numbers and credentials without editing this file directly. The containers are connected to each other through a shared network and include health checks to ensure they're running properly.
We'll use a configuration file called .envβ
We're also going to use a configuration file named .env (which is never anything more than a silly dictionary of keys - values) to differentiate our projects.
Please create a second file called .env with this content:
CONTAINER_PREFIX=joomlaDB_NAME=joomlaDB_PASSWORD=examplepassDB_USER=joomlaJOOMLA_VERSION=5.2.0-php8.3-apacheMYSQL_PORT=3306MYSQL_VERSION=8.4.2PROJECT_NAME=running-joomla-in-dockerWEB_PORT=8080This script sets up configuration variables for running a Joomla application in Docker containers. It defines names, versions, and connection details for the Joomla web server, MySQL database, and Docker containers that will be launched together.
Using a .env file is really useful so you no longer need to make changes to the compose.yaml file, which can stay standard across all your projects.
If you need two or more Joomla websites (you're a web agency starting to use Docker for your development), you'll be able to only do changes to the .env file by updating the WEB_PORT (each project should have his unique port) and, you'll probably update the PROJECT_NAME too to f.i. your customer name.
Information
WEB_PORT, PROJECT_NAME, ... are just variables. If you look back to your just copied/pasted compose.yaml content, you'll retrieve these variables like on the line image: joomla:${JOOMLA_VERSION:-latest}.
The ${XXX:-yyy} syntax means: if the variable exists, use it (the XXX part) otherwise use a default value (the yyy part).
So, here, if JOOMLA_VERSION exists and this is the case in our .env file, then use his value. We'll then use image: joomla:5.2.0-php8.3-apache. If JOOMLA_VERSION was missing in our .env, then we'll use latest and thus image: joomla:latest.
Let's make our lives simpler and lazier; using a makefileβ
The third and last file we'll use is being called makefile and that file will contain some scripts i.e. we'll create a script called up for building our website.
To be able to use a makefile, you should have GNU Make binary installed on your machine.
Caution
If you don't know if you already have GNU make, just run which make in the console. If you see make not found then please run sudo apt-get update && sudo apt-get install make to complete the installation.
So, please create a file called makefile in your current directory with this content:
include .env
config: @UID=$$(id -u) GID=$$(id -g) docker compose config
down: stop -@UID=$$(id -u) GID=$$(id -g) docker compose down
log: -@UID=$$(id -u) GID=$$(id -g) docker compose logs
reset: down -@rm -rf db_data joomla_data
start: @clear @printf "\033[1;33m%s\033[0m\n\n" "To start your site, please jump to http://127.0.0.1:${WEB_PORT}" @printf "\033[1;33m%s\033[0m\n\n" "Go to http://127.0.0.1:${WEB_PORT}/administrator to open your backend."
@printf "\033[1;104m%s\033[0m\n\n" "Below a summary of your current installation:"
@printf "\033[1;34m%s\033[0m\n\n" "JOOMLA" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Project name" "${PROJECT_NAME}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Version" "${JOOMLA_VERSION}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n\n" " * Port" "${WEB_PORT}"
@printf "\033[1;34m%s\033[0m\n\n" "DATABASE" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Host" "joomla-db" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * User name" "${DB_USER}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Password" "${DB_PASSWORD}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Database name" "${DB_NAME}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Version" "${MYSQL_VERSION}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n\n" " * Port" "${MYSQL_PORT}"
stop: -@UID=$$(id -u) GID=$$(id -g) docker compose stop
up: -@mkdir -p db_data joomla_data @UID=$$(id -u) GID=$$(id -g) docker compose up --detach --buildThis Makefile orchestrates a Docker-based Joomla development environment. It provides commands to start, stop, and configure the application, managing both the web server and database containers while injecting the current user's ID and group ID into Docker to handle file permissions correctly. The main entry point is the 'start' target, which displays formatted installation details pulled from environment variables.
Indentation should be TAB not spaces
It's terribly vicious because it's totally silent: the indentation in a makefile must be tabs, not spaces. When you copy/paste the above code to create your file, make sure your text editor uses tabs. If it doesn't, the commands defined in the file won't work.
Note
If you want to learn more about GNU Make, check my Linux Makefile - When to use a makefile article
Before startingβ
We're ready. Just before you begin, please check that you have the three files below (please run ls -alh):
Need help here? Click the "Help" button above for setup instructions.
Check our configurationβ
By running make config (config is an action we've defined in our makefile), we can display the configuration of our project on the screen (just display, nothing is fired).
We should see a lot of technical information starting with something like:
name: running-joomla-in-dockerservices: joomla: container_name: joomla-app depends_on: joomladb: condition: service_healthy required: true environment: JOOMLA_DB_HOST: joomladb JOOMLA_DB_NAME: joomla JOOMLA_DB_PASSWORD: examplepass JOOMLA_DB_USER: joomla image: joomla:5.2.0-php8.3-apache networks: joomla_network: null ports: - mode: ingress target: 80 published: "8080" protocol: tcp restart: always user: 1002:1002 volumes: - type: bind source: /tmp/joomla/joomla_data target: /var/www/html bind: create_host_path: true joomladb: container_name: joomla-db environment: MYSQL_DATABASE: joomla MYSQL_PASSWORD: examplepass MYSQL_RANDOM_ROOT_PASSWORD: "'1'" MYSQL_USER: joomla healthcheck: test: - CMD - mysqladmin - ping - -h - localhost timeout: 20s retries: 10 image: mysql:8.4.2 networks: joomla_network: null ports: - mode: ingress target: 3306 published: "3306" protocol: tcp restart: always user: 1002:1002 volumes: - type: bind source: /tmp/joomla/db_data target: /var/lib/mysql bind: create_host_path: truenetworks: joomla_network: name: running-joomla-in-docker_joomla_networkThis Docker Compose configuration sets up a Joomla web application with a MySQL database backend. The Joomla service depends on the database being healthy before starting, and both services run on a shared network with persistent storage volumes mounted from the host machine.
Information
The output here above is a partial content and just show the first lines displayed to the console by the make config command.
The objective of make config is to make sure that all files are correct (otherwise we'll get error messages) and that variables are well replaced by their values. You can see f.i. that the Joomla version is well the one we've specified in the .env file and the user line (the last line here above) is correctly initialised to the user_id:group_id of your current user.
UID/GID
The user_id:group_id will vary depending on your own configuration. It'll be 1000:1000 in the most situations, but this can be something else when, f.i., you've defined more than one user in your Linux distribution; the first user probably be 1000:1000, the second 1001:1001 and so on.
Let's wake up Joomla...β
Here we are at the heart of the subject: we would like to see a beautiful, fresh Joomla site. Is it possible to do this in a single command and even without having to install anything by hand?
The answer is "Yes" and make up will do the magic.
In your console, just run make up, and please wait one minute. The very first time, you'll get the console output shown at the top of this article.
What does that mean? Docker has retrieved (pulled) from the Internet our joomla and joomladb services (in other terms, has downloaded the Joomla CMS (including PHP and Apache) and MySQL).
By running then command below (or just docker container list to get all the columns), you'll get the list of running containers:
As we can see, yay!, we have our two services (named containers) which are Joomla and MySQL, and they are both Up (see the Status column). We see that Joomla uses port 8080 and MySQL uses port 3306.
Information
The port 8080 is the one we've specified in our .env (variable WEB_PORT) and, the same for MySQL, it uses port 3006 because that's the one we defined (MYSQL_PORT).
Note that 3306 is the standard port for MySQL.
... or let's ask him to fall asleep (keep containers)β
The opposite command to make up is make stop. The stop action will stop our Joomla and MySQL containers (read make them sleeping) but without removing files (your site and your database) from your hard drive. By running make up again, you'll retrieve them. up and stop are like a light switch.
... or let's ask him to remove containers (free more memory)β
The make down command will stop the containers as well remove them. But in our case, we'll still have files on our hard disk so we'll not lose our website.
... or let's ask him to suicide (remove containers and files)β
The make reset command will stop containers but, too, remove files on the disk.
Danger
By running make reset, you'll lose everything and be ready to create a new fresh website.
Time to starting the websiteβ
Once make up has been fired and your containers in a Up state, our Joomla site is ready.
You will need some information like credentials for the database; this is why the make start screen was defined.
Please run make start in console. You'll get a screen like the one below:
To start your site, please jump to http://127.0.0.1:8080
Go to http://127.0.0.1:8080/administrator to open your backend.
Below a summary of your current installation:
JOOMLA
* Project name running-joomla-in-docker
* Version latest
* Port 8080
DATABASE
* Host joomla-db
* User name joomla
* Password examplepass
* Database name joomla
* Version 8.4.2
* Port 3306
As you can see, the port number is 8080; the one we've specified in our .env file. Simply CTRL click on the URL if your terminal support this option (otherwise, manually start your preferred web browser and navigate to the specified URL) β you'll land on the installer screen shown at the top of this article.
Congratulations, you have successfully installed a fresh Joomla website using Docker!
You'll need to configure your new fresh site. In the Database Configuration screen, you'll need to fill in the Host, the username, the password and the database name. This information is displayed on the console; thanks make start. Just use these values when prompted.
Time for a breakβ
What have we seen so far?
- Without having anything other than Docker you can install Joomla and MySQL from the command line, in the version you want;
- That with an
.envfile we can vary certain values to allow us to have several projects on our hard drive (several Joomla sites); - That with the
compose.yamlfile we tell Docker what to do to make Joomla and MySQL talk to each other, and - The
compose.yamlfile is valuable since it allows you to define a number of configuration variables.
Let's go a little further.
Advanced configuration for Joomlaβ
The official Joomla Docker image is maintained by the Joomla community on Docker Hub: https://hub.docker.com/_/joomla.
You'll retrieve there a list of tags i.e. a list of versions you can install using Docker but you'll also find a How to use this image section and that one is really useful.
Below the list of variables supported by Joomla by the end of September 2024:
| Variable name | Description |
|---|---|
JOOMLA_DB_HOST | Defaults to the IP and port of the linked mysql container |
JOOMLA_DB_USER | Defaults to root |
JOOMLA_DB_PASSWORD | Defaults to the value of the MYSQL_ROOT_PASSWORD environment variable from the linked mysql container |
JOOMLA_DB_PASSWORD_FILE | Path to a file containing the database password |
JOOMLA_DB_NAME | Defaults to joomla |
JOOMLA_DB_TYPE | Defaults to mysqli; options: mysqli, pgsql |
The following environment variables are also recognized for configuring auto deployment (i.e. skip the browser setup) for your Joomla instance:
| Variable name | Description |
|---|---|
JOOMLA_SITE_NAME | Name of the Joomla site |
JOOMLA_ADMIN_USER | Full name of the Joomla administrator |
JOOMLA_ADMIN_USERNAME | Username of the Joomla administrator |
JOOMLA_ADMIN_PASSWORD | Password of the Joomla administrator |
JOOMLA_ADMIN_EMAIL | Email address of the Joomla administrator |
JOOMLA_EXTENSIONS_URLS | Semicolon-separated list of URLs to install Joomla extensions from |
JOOMLA_EXTENSIONS_PATHS | Semicolon-separated list of file paths to install Joomla extensions from |
JOOMLA_SMTP_HOST | SMTP host for outgoing email |
JOOMLA_SMTP_HOST_PORT | SMTP port for outgoing email |
Pay attention to the last table here above.
Pretty cool!
We could therefore completely ignore the Joomla configuration screens!!! By specifying certain values, we could therefore install a beautiful, fresh Joomla and already display a functional website.
Let's try.
We'll update our three files to skip the installation process by predefining values like the name and the password for our administrator.
Updated compose.yamlβ
We'll edit our compose.yaml file and add new entries:
name: ${PROJECT_NAME:-your-project-name}
services: joomla: image: joomla:${JOOMLA_VERSION:-latest} container_name: ${CONTAINER_PREFIX:-joomla}-app restart: always ports: - ${WEB_PORT:-8080}:80 environment: - JOOMLA_DB_HOST=joomladb - JOOMLA_DB_NAME=${DB_NAME:-joomla} - JOOMLA_DB_PASSWORD=${DB_PASSWORD:-examplepass} - JOOMLA_DB_USER=${DB_USER:-joomla} # highlight-next-line - JOOMLA_SITE_NAME=${JOOMLA_SITE_NAME:-Joomla} # highlight-next-line - JOOMLA_ADMIN_USER=${JOOMLA_ADMIN_USER:-Joomla Hero} # highlight-next-line - JOOMLA_ADMIN_USERNAME=${JOOMLA_ADMIN_USERNAME:-joomla} # highlight-next-line - JOOMLA_ADMIN_PASSWORD=${JOOMLA_ADMIN_PASSWORD:-joomla@secured} # highlight-next-line - JOOMLA_ADMIN_EMAIL=${JOOMLA_ADMIN_EMAIL:-joomla@example.com} depends_on: joomladb: condition: service_healthy user: ${UID:-1000}:${GID:-1000} volumes: - ./joomla_data:/var/www/html networks: - joomla_network
joomladb: image: mysql:${MYSQL_VERSION:-latest} container_name: ${CONTAINER_PREFIX:-joomla}-db restart: always ports: - ${MYSQL_PORT-:3306}:3306 environment: - MYSQL_DATABASE=${DB_NAME:-joomla} - MYSQL_PASSWORD=${DB_PASSWORD:-examplepass} - MYSQL_RANDOM_ROOT_PASSWORD='1' - MYSQL_USER=${DB_USER:-joomla} healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] timeout: 20s retries: 10 user: ${UID:-1000}:${GID:-1000} volumes: - ./db_data:/var/lib/mysql networks: - joomla_network
networks: joomla_network:This Docker Compose file sets up a Joomla website with a MySQL database, both running in containers on the same network. It uses environment variables with default fallback values so you can customize the setup without editing the file directlyβjust pass different values when you start it up.
Updated .envβ
And we'll also update our .env file like this:
CONTAINER_PREFIX=joomlaDB_NAME=joomlaDB_PASSWORD=examplepassDB_USER=joomla// highlight-next-lineJOOMLA_ADMIN_EMAIL=joomla@example.com// highlight-next-lineJOOMLA_ADMIN_PASSWORD=joomla@secured// highlight-next-lineJOOMLA_ADMIN_USER=Joomla Hero// highlight-next-lineJOOMLA_ADMIN_USERNAME=joomla// highlight-next-lineJOOMLA_SITE_NAME=JoomlaJOOMLA_VERSION=5.2.0-php8.3-apacheMYSQL_PORT=3306MYSQL_VERSION=8.4.2PROJECT_NAME=running-joomla-in-dockerWEB_PORT=8080This is a configuration file that sets up environment variables for running a Joomla content management system in Docker. It specifies database credentials, admin account details, service versions, and port mappings needed to launch the application.
Updated makefileβ
And, finally, also update the makefile like this:
-include .env
config: @UID=$$(id -u) GID=$$(id -g) docker compose config
down: stop -@UID=$$(id -u) GID=$$(id -g) docker compose down
log: -@UID=$$(id -u) GID=$$(id -g) docker compose logs
reset: down -@rm -rf db_data joomla_data
start: @clear @printf "\033[1;33m%s\033[0m\n\n" "To start your site, please jump to http://127.0.0.1:${WEB_PORT}" @printf "\033[1;33m%s\033[0m\n\n" "Go to http://127.0.0.1:${WEB_PORT}/administrator to open your backend."
@printf "\033[1;104m%s\033[0m\n\n" "Below a summary of your current installation:"
@printf "\033[1;34m%s\033[0m\n\n" "JOOMLA" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Project name" "${PROJECT_NAME}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Version" "${JOOMLA_VERSION}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Port" "${WEB_PORT}"
# highlight-next-line @printf "\n\033[1;34m%s\033[0m\n\n" " Administration" # highlight-next-line @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Site name" "${JOOMLA_SITE_NAME}" # highlight-next-line @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Admin friendly username" "${JOOMLA_ADMIN_USER}" # highlight-next-line @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Admin username" "${JOOMLA_ADMIN_USERNAME}" # highlight-next-line @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Admin password" "${JOOMLA_ADMIN_PASSWORD}" # highlight-next-line @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n\n" " * Admin email" "${JOOMLA_ADMIN_EMAIL}"
@printf "\033[1;34m%s\033[0m\n\n" "DATABASE" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Host" "joomla-db" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * User name" "${DB_USER}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Password" "${DB_PASSWORD}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Database name" "${DB_NAME}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n" " * Version" "${MYSQL_VERSION}" @printf "\033[1;34m%-30s\033[0m\033[1;104m%s\033[0m\n\n" " * Port" "${MYSQL_PORT}"
stop: -@UID=$$(id -u) GID=$$(id -g) docker compose stop
up: -@mkdir -p db_data joomla_data @UID=$$(id -u) GID=$$(id -g) docker compose up --detach --buildThis is a Makefile that orchestrates a Docker-based Joomla development environment. It provides commands to start, stop, and manage the application, along with a detailed startup message that displays all the configuration details like ports, database credentials, and admin information pulled from environment variables.
As you can see, we've configured some JOOMLA_ADMIN_xxx keys and set JOOMLA_SITE_NAME to Joomla; the name of our website.
Running the website and skip the installation processβ
Once you've updated the three files; just run make reset (to remove our previous site if any) then run make up to create a new one. Finally, run make start to show a list of important variables:
To start your site, please jump to http://127.0.0.1:8080
Go to http://127.0.0.1:8080/administrator to open your backend.
Below a summary of your current installation:
JOOMLA
* Project name running-joomla-in-docker
* Version 5.2.0-php8.3-apache
* Port 8080
Administration
* Site name Joomla
* Admin friendly username Joomla Hero
* Admin username joomla
* Admin password joomla@secured
* Admin email joomla@example.com
DATABASE
* Host joomla-db
* Version 8.4.2
* Name joomla
* User joomla
* Password examplepass
* Port 3306
Now, by going to http://127.0.0.1:8080/administrator, you'll no longer see the installation screens but, immediately, the login screen. The username to use is joomla and its password is joomla@secured (as you can see on the console).
Your Joomla site is already configured; nice no?
Time for a second breakβ
Ok, so right now, we've seen how to create a fresh Joomla website in seconds with just the make up command and how to bypass the installation screens by already providing useful information in our .env file.
Let's try a real-world example: we are a small web agency and we wish to use Docker for our next projects and we already have three projects in our mind. Or, you're an individual having several websites; all with different Joomla versions.
Starting three different projectsβ
Please create a structure like below i.e. cd /tmp/joomla && mkdir project_1 project_2 project_3.
Then go back to the Updated compose.yaml chapter and create the compose.yaml file in both the three projects' folder. Do the same for the .env and the makefile.
The same three files in the three projects folders.
At the end, you should have this structure in your /tmp/joomla folder:
/tmp/joomla
One directory by project and, again, our three files.
Note
The tree command isn't native on Linux. If you wish to install it, just run sudo apt-get update && sudo apt-get install tree.
Project 1 - Joomla 5.2β
Project 1 will be a Joomla 5.2
In a very few words: we'll install Joomla 5.2 and MySQL 8.4.2.
Please configure the project_1/.env file with the following content.
As you can see (highlighted lines), that file is the same that the latest .env we've used earlier but:
- We'll set the
CONTAINER_PREFIXto an unique value; in our examplejoomla_5, - We need to do the same (i.e. define an unique value) for the MySQL port number; we can use the standard port
3306for our first project but, let's use3301(1because it's our first project) - You've understood; we'll do the same for
JOOMLA_SITE_NAMEandPROJECT_NAME; remain humble and opt forJoomla_5andjoomla5and - Finally, we need to define a web port number; we'll use
8081(so our site will be available onhttp://127.0.0.1:8081).
Here is the .env file for our first project:
// highlight-next-lineCONTAINER_PREFIX=joomla_5DB_NAME=joomlaDB_PASSWORD=examplepassDB_USER=joomlaJOOMLA_ADMIN_EMAIL=joomla@example.comJOOMLA_ADMIN_PASSWORD=joomla@securedJOOMLA_ADMIN_USER=Joomla HeroJOOMLA_ADMIN_USERNAME=joomla// highlight-next-lineJOOMLA_SITE_NAME=Joomla_5// highlight-next-lineJOOMLA_VERSION=5.2.0-php8.3-apache// highlight-next-lineMYSQL_PORT=3301// highlight-next-lineMYSQL_VERSION=8.4.2// highlight-next-linePROJECT_NAME=joomla5// highlight-next-lineWEB_PORT=8081This is an environment configuration file that sets up variables for a Joomla 5 website running in Docker containers. It specifies database credentials, admin user details, service versions, and port mappings needed to launch and connect to the application.
Go to your console and run cd project_1 to jump in the first project's folder then make up to create Docker containers for project 1.
By going to http://127.0.0.1:8081/administrator/ we've our first admin page (as you can see, the site is well called Joomla_5 as expected).

Caution
Please really be careful to specify the port number of our project. For project 1, the port number is 8081. As, in fact, we wished by setting the variable WEB_PORT.
So, to access to the first project, our URL is well http://127.0.0.1:8081.
Project 2 - Joomla 4.0β
Project 2 will be a Joomla 4.0
In a very few words: we'll install Joomla 4.0 and MySQL 5.7.37.
Please configure the project_2/.env with the following content. As you can see (highlighted lines), that file is the same as the latest .env we've used earlier but, just, we'll adjust the name of the project and the web port (so our site will be available on http://127.0.0.1:8082).
Do the same changes as for project 1 but just replace 1 by 2:
// highlight-next-lineCONTAINER_PREFIX=joomla_4DB_NAME=joomlaDB_PASSWORD=examplepassDB_USER=joomlaJOOMLA_ADMIN_EMAIL=joomla@example.comJOOMLA_ADMIN_PASSWORD=joomla@securedJOOMLA_ADMIN_USER=Joomla HeroJOOMLA_ADMIN_USERNAME=joomla// highlight-next-lineJOOMLA_SITE_NAME=Joomla_4// highlight-next-lineJOOMLA_VERSION=4.0.2-apache// highlight-next-lineMYSQL_PORT=3302// highlight-next-lineMYSQL_VERSION=5.7.37// highlight-next-linePROJECT_NAME=joomla4// highlight-next-lineWEB_PORT=8082This is an environment configuration file that sets up variables for a Joomla 4 website running in Docker containers with a MySQL database. It defines database credentials, admin user information, software versions, and port mappings that the application will use when it starts up.
Save the file and run make up to start the second website. Go to http://127.0.0.1:8082/administrator and yes, we've our second site running on our machine.

Two Joomla sites having two different PHP and MySQL versions and ... no conflict!
Did you see? We've two websites running on our computer. The first one is a Joomla 5.2 and the second one is Joomla 4.0.
If you're still awake after this long blog post, to get access to our second website, we need to go to http://127.0.0.1:8082.
Project 3 - Joomla 3.5β
Project 3 will be a Joomla 3.5
And now, you need to do some maintenance on an old J3.5 website. Let's create one on our computer.
Please now configure the project_3/.env with the following content.
This time, we'll use 3 as suffixes:
// highlight-next-lineCONTAINER_PREFIX=joomla_3DB_NAME=joomlaDB_PASSWORD=examplepassDB_USER=joomlaJOOMLA_ADMIN_EMAIL=joomla@example.comJOOMLA_ADMIN_PASSWORD=joomla@securedJOOMLA_ADMIN_USER=Joomla HeroJOOMLA_ADMIN_USERNAME=joomla// highlight-next-lineJOOMLA_SITE_NAME=Joomla_3// highlight-next-lineJOOMLA_VERSION=3.5.1-apache// highlight-next-lineMYSQL_PORT=3303// highlight-next-lineMYSQL_VERSION=5.7.31// highlight-next-linePROJECT_NAME=joomla3// highlight-next-lineWEB_PORT=8083This is an environment configuration file that sets up variables for a Joomla 3 installation running in Docker. It defines database credentials, admin user details, service versions, and port mappings that the application needs to start up and run properly.
Save the file and run make up && make start to start the third website. Go to http://127.0.0.1:8083/administrator and yes, we've our third site running on our machine.

Just wow no?
Three different Joomla versions, MySQL and too PHP and no conflict at all!
In fact, nothing surprising, it's normal with Docker: everything is isolated in its own container. π
Start all three projects in just one commandβ
If I'm located in my /tmp/joomla folder; I can start my three projects at once like this:
Here is something you can get:
Other projects? How many sites can I have?β
As we've just seen here, we can launch several Joomla projects at the same time on our machine and access them as easily as possible by varying the web port number (8081, 8082, 8083, ...).
But how many can I have? Well, that just depends on your machine.
For information, here's what I'm seeing right now on my Windows computer (I'm using Docker Desktop and WSL2).

As you can see, I actually have four projects: my current blog (running on Docker too) and the three Joomla projects.
If you look at the CPU (%) column, you can see that the projects are almost asleep. And this is normal: once the web page has been displayed, Joomla and MySQL don't require CPU anymore. The page is displayed so they are sleeping.
For the memory, I've allocated max. 20GB to WSL/Docker and right now, my four projects (including my blog) are eating 3.3 GB combined. I can thus start a lot more projects.
But do I need to be able to work on all three projects at the same time? Probably not. So why not stop, f.i., the first and the third project?
In the console, just run make stop in folder project 1 and 3 by, running ( cd project_1 ; make stop ; cd ../project_3 ; make stop). We'll thus stop (not remove; just freeze and release memory) our first and third project.
By looking back to Docker Desktop, we can indeed see we've earned 1GB RAM.

Note
In our example here, we've just kept the second project so we can still work on http://127.0.0.1:8082/ but the two other projects (http://127.0.0.1:8081/ and http://127.0.0.1:8083/) won't respond anymore. We've stopped them.
Just run make up again in f.i. folder project_1 to make the site back to life. Or, if you prefer the GUI, in Docker Desktop, just click on the Start button:

Under the hood: Docker logsβ
Optional β skip this section if everything is working and you don't need to debug.
Sometimes, if something goes wrong, it's nice to have access to the Docker logs. Simply run make log to achieve this.
Logs will look like this:
joomla-db | 2024-10-13 13:30:25+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.4.2-1.el9 started.
joomla-db | '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
joomla-db | 2024-10-13T13:30:26.058140Z 0 [System] [MY-015015] [Server] MySQL Server - start.
joomla-db | 2024-10-13T13:30:26.238267Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.4.2) starting as process 1
joomla-db | 2024-10-13T13:30:26.239450Z 0 [Warning] [MY-010122] [Server] One can only use the --user switch if running as root
joomla-db | 2024-10-13T13:30:26.246482Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
joomla-db | 2024-10-13T13:30:26.568703Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
joomla-db | 2024-10-13T13:30:26.852192Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
[...]
joomla-db | 2024-10-13T13:30:26.852232Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now
joomla-app | ========================================================================
joomla-app |
joomla-app |
joomla-app | Ensuring Joomla database is present
joomla-app |
joomla-app | MySQL Database Created
joomla-app | This server is now configured to run Joomla!
joomla-app |
joomla-app | NOTE: You will need your database server address, database name,
joomla-app | and database user credentials to install Joomla.
joomla-app |
joomla-app | ========================================================================
joomla-app | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.19.0.3. Set the 'ServerName' directive globally to suppress this message
[...]
joomla-app | [Fri Oct 04 13:31:46.880743 2024] [mpm_prefork:notice] [pid 1:tid 1] AH00163: Apache/2.4.62 (Debian) PHP/8.3.12 configured -- resuming normal operations
joomla-app | [Fri Oct 04 13:31:46.880782 2024] [core:notice] [pid 1:tid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
joomla-app | 172.19.0.1 - - [04/Oct/2024:06:57:36 +0000] "POST /installation/index.php HTTP/1.1" 200 6497 "http://127.0.0.1:8080/installation/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0"
Conclusionβ
Three small files β compose.yaml, .env, makefile β and make up turns into your entire
Joomla deployment story: fresh installs, pre-configured sites that skip the installer wizard, and
as many isolated projects (different Joomla/PHP/MySQL versions) as your machine can carry, each
one started, stopped or torn down with a single command.
At this point, you might be wondering: this is all great, but I already have a Joomla site and I'd like to take a backup of my site and restore it locally using Docker; how can I do this?
If you're indeed wondering, read the next article: Restore a Joomla backup using Docker
This article is part of the Create your joomla website using Docker series:
Loading commentsβ¦

