Configuring local development using Docker Compose
Links: Code in GitLab
Journey map:
- Part 1 — Automate development workspace configuration ← You are here
- Part 2 — Install a testing suite
- Part 3 — Write automated tests
Prestashop module development has been difficult for a lot of time.
Your module needs to support an increasing number of PrestaShop versions, testing cannot be made without a running prestashop, and documentation is very limited, if you compare it to other open source frameworks/platforms.
The first time I had to send for approval my module to PrestaShop Addons it took me an entire week, no kidding.
But can automation really help?
Someone told me yes, so let’s try it.
The goal
The goal is to make a module ready to be approved on the PrestaShop Addons, automating everything possible from development to validation.
The “working” module will be generated by the prestashop module generator. Nothing fancy here.
Development setup
For development, we will use four PrestaShop websites, that are the mayor versions that should be supported at this time: 1.7.3
, 1.7.2
, 1.7.1
and 1.6.1
.
Normally, this is where you go to download and install on your machine a LAMP setup, I am on macOS, so I have used MAMP for this.
But this operation is time consuming and causes problems if you have multiple environment.
For example if you have two computer where you develop, and you want to switch between them. Or if you work in a team, your collegues may have a different setup (or a different OS), which leads to bugs like: “It works on my computer”.
Wouldn’t it be great if instead we can use a single command to start your prestashop websites, having the certain that everyone have the exact same configuration?
Let the docker composition begin
Docker compose is a tool that help you run multiple applications in your machine, without actually install it on your machine.
Instead, applications are build as images, which are executed in running container started on your system. This is similar to use a virtual machine, but faster.
I’m not going to explain how docker compose works underground. There are plenty of articles for that. Instead I will focus on what matter to us:
Automated and replicable development configuration
To do so, I will create a file called docker-compose.yml
in the root of our module:
version: "3"
services:
mysql:
image: mysql/mysql-server:5.7
restart: always
environment:
- MYSQL_RANDOM_ROOT_PASSWORD=1
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWD}
- MYSQL_DATABASE=${DB_NAME}
prestashop_1.6.1:
image: prestashop/prestashop:1.6
depends_on:
- mysql
ports:
- 8080:80
volumes:
- .:/var/www/html/modules/${PS_MODULE_NAME}
environment:
- DB_SERVER=mysql
- DB_PREFIX=ps161_
- PS_DEV_MODE=${PS_DEV_MODE}
- PS_INSTALL_AUTO=1
- DB_USER=${DB_USER}
- DB_PASSWD=${DB_PASSWD}
- DB_NAME=${DB_NAME}
- PS_FOLDER_ADMIN=${PS_FOLDER_ADMIN}
- PS_DOMAIN=${PS_DOMAIN}:8080
- PS_LANGUAGE=${PS_LANGUAGE}
- PS_COUNTRY=${PS_COUNTRY}
- PS_FOLDER_INSTALL=installed
prestashop_1.7.1:
image: prestashop/prestashop:1.7.1.0
depends_on:
- mysql
ports:
- 8081:80
volumes:
- .:/var/www/html/modules/${PS_MODULE_NAME}
environment:
- DB_SERVER=mysql
- DB_PREFIX=ps171_
- PS_DEV_MODE=${PS_DEV_MODE}
- PS_INSTALL_AUTO=1
- DB_USER=${DB_USER}
- DB_PASSWD=${DB_PASSWD}
- DB_NAME=${DB_NAME}
- PS_FOLDER_ADMIN=${PS_FOLDER_ADMIN}
- PS_DOMAIN=${PS_DOMAIN}:8081
- PS_LANGUAGE=${PS_LANGUAGE}
- PS_COUNTRY=${PS_COUNTRY}
- PS_FOLDER_INSTALL=installed
prestashop_1.7.2:
image: prestashop/prestashop:1.7.2.4
depends_on:
- mysql
ports:
- 8082:80
volumes:
- .:/var/www/html/modules/${PS_MODULE_NAME}
environment:
- DB_SERVER=mysql
- DB_PREFIX=ps172_
- PS_DEV_MODE=${PS_DEV_MODE}
- PS_INSTALL_AUTO=1
- DB_USER=${DB_USER}
- DB_PASSWD=${DB_PASSWD}
- DB_NAME=${DB_NAME}
- PS_FOLDER_ADMIN=${PS_FOLDER_ADMIN}
- PS_DOMAIN=${PS_DOMAIN}:8082
- PS_LANGUAGE=${PS_LANGUAGE}
- PS_COUNTRY=${PS_COUNTRY}
- PS_FOLDER_INSTALL=installed
prestashop_1.7.3:
image: prestashop/prestashop:1.7.3
depends_on:
- mysql
ports:
- 8083:80
volumes:
- .:/var/www/html/modules/${PS_MODULE_NAME}
environment:
- DB_SERVER=mysql
- DB_PREFIX=ps173_
- PS_DEV_MODE=${PS_DEV_MODE}
- PS_INSTALL_AUTO=1
- DB_USER=${DB_USER}
- DB_PASSWD=${DB_PASSWD}
- DB_NAME=${DB_NAME}
- PS_FOLDER_ADMIN=${PS_FOLDER_ADMIN}
- PS_DOMAIN=${PS_DOMAIN}:8083
- PS_LANGUAGE=${PS_LANGUAGE}
- PS_COUNTRY=${PS_COUNTRY}
- PS_FOLDER_INSTALL=installed
Wow, this configuration is huge.
Let’s break it down.
services
The yaml file will tell to docker-compose which services (aka applications) we want to run. There are five in our setup:
- mysql
- prestashop_1.6.1
- prestashop_1.7.1
- prestashop_1.7.2
- prestashop_1.7.3
image
This is the docker image to download from hub.docker.com.
depends_on
All prestashop_*
services depends on the mysql
service, because all needs a mysql database to run, this ensure that if something happen to the mysql
service, the other services will respond accordingly.
For our development, we don’t really need to keep things separate, so we will use the database prefix to fit our four PrestaShop websites in one database.
ports
This parameter map the internal prestashop 80
to our machine port, like 8080
. Since we are running all these websites at once the configuration points to ports from range 8080 — 8083
volumes
Volumes are a way to map a directory of our machine to the remote host. In our case, we will link the current directory (the one containg the module files) to the modules folder of all prestashop services.
environment
Each docker image have a number of environment variables, which can be configurable to fit our needs. All variables ${}
values are stored in a special file called .env
, that should be placed in the root of our project. If you are working in a team, this let everyone change the configuration to fit their needs (and should not be kept under version control).
An example of this file could be:
# Database
DB_USER=username
DB_PASSWD=password
DB_NAME=prestashop
# Prestashop
PS_DOMAIN=localhost
PS_DEV_MODE=1
PS_FOLDER_ADMIN=adminPS
PS_MODULE_NAME=testmodule
PS_LANGUAGE=en
PS_COUNTRY=GB
NOTE: PS_MODULE_NAME
should always be set equal the module name, because it will be used to link the current project folder to the modules/
folder inside prestashop containers.
Start up everything
Now that our configuration is done, we just need to execute this command in the terminal to start up all containers (be sure to be on the project root first):
docker-compose up
If you haven’t take it yet, now it’s time for a coffee ☕️☕️
The first time docker will download all images, start the containers, load the database, install prestashop and start the webserver for each website.
This will take some time…
But don’t worry, it’s only for the first run.
From the second startup it will take just some seconds.
When finished, you should be able to see your prestashop 1.6.1 website opening the pagelocalhost:8080
The Backoffice
If you have used my .env
example file, your admin folder should be renamed in adminPS
for all your websites.
This means you can go to localhost:8080/adminPS
and login.
We can now enter into the admin using the default prestashop credentials:
Email: demo@prestashop.com
Password: prestashop_demo
If you want, you can even customize the default account using some additional environment variable in your docker-compose.yml
file. For more information check out the prestashop docker hub page.
NOTE: I referenced only the prestashop 1.6.1 website. If you didn’t skip the ports explanation, you should already know that you can open localhost:8081/adminPS
for 1.7.1
, localhost:8082/adminPS
for 1.7.2
and localhost:8083/adminPS
for 1.7.3
What about module development?
You are right. Configuration is cool, but we need to work easily.
But since we have already configured a volume between our project and all prestashop websites, you can just go to the modules page in the prestashop backoffice and find your module, like you fresh install it.
Also, every change that you make to your project files will be automatically found in all prestashop websites.
Does it look like an improvement in your PrestaShop development workflow?
Let me know with a comment below
This ends Part 1. Thanks for sticking around!
In part 2 we will install a testing suite using composer.
Stay tuned!