A PrestaShop module development automation journey — Part 1

NeoKree
5 min readJun 29, 2018

Configuring local development using Docker Compose

Links: Code in GitLab

Journey map:

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!

--

--