Part 3 – How to run Magento 2 with Elastic search on the docker environment?
This tutorial is a part of the big one Magento & Docker tutorial. You can find the last part here. The complete code of the previous tutorial is on the GitHub.
Review current configuration
In the previous tutorial, we have made a complete configuration for running web applications. We have all needed services for the base run Magento 2
- NGINX
- PHP-FPM
- MySql
The file structure looks like this:
App
- conf
- app
- etc
- nginx
- conf.d
- default.conf
- dockerfile
- phpfpm
- Dockerfile
- sql
- src
- docker-compose.yml
We have made own PHP Docker image, but Magento needs more specific php extensions and libraries. We will add it on this tutorial part. We will try to configure Elasticsearch indexing also.
Let’s start.
Modify PHP-FPM image
Install needed PHP extensions
We can check what php extensions Magento needs in the official documentation
- ext-bcmath
- ext-ctype
- ext-curl
- ext-dom
- ext-gd
- ext-hash
- ext-iconv
- ext-intl
- ext-mbstring
- ext-openssl
- ext-pdo_mysql
- ext-simplexml
- ext-soap
- ext-xsl
- ext-zip
- lib-libxml
Let’s install missed extensions. Open dockerfiles/phpfpm/Dockerfile and add libraries and extensions installation RUN part.
RUN apt-get update && apt-get install -y \
gzip \
libbz2-dev \
libfreetype6-dev \
libicu-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
libsodium-dev \
libssh2-1-dev \
libxslt1-dev \
libzip-dev \
lsof \
default-mysql-client \
zip
RUN docker-php-ext-configure \
gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install \
bcmath \
bz2 \
calendar \
exif \
gd \
gettext \
intl \
mbstring \
mysqli \
opcache \
pcntl \
pdo_mysql \
soap \
sockets \
sodium \
sysvmsg \
sysvsem \
sysvshm \
xsl \
zip
Whole PHP file looks like this:
FROM php:7.3-fpm
RUN apt-get update && apt-get install -y \
gzip \
libbz2-dev \
libfreetype6-dev \
libicu-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
libsodium-dev \
libssh2-1-dev \
libxslt1-dev \
libzip-dev \
lsof \
default-mysql-client \
zip
RUN docker-php-ext-configure \
gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install \
bcmath \
bz2 \
calendar \
exif \
gd \
gettext \
intl \
mbstring \
mysqli \
opcache \
pcntl \
pdo_mysql \
soap \
sockets \
sodium \
sysvmsg \
sysvsem \
sysvshm \
xsl \
zip
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
Application user
The best practice is to create the user for web files. Add the part to creating the user and group after the php.ini selection statement.
RUN groupadd -g 1000 app \
&& useradd -g 1000 -u 1000 -d /var/www -s /bin/bash app
Prepare application directory and set permissions
RUN mkdir -p /var/www/html \
&& chown -R app:app /var/www
Change user, set home directory as volume, and set the workdir to /var/www/html
USER app:app
VOLUME /var/www
WORKDIR /var/www/html
Get composer
For Magento installation, the composer will be useful. We can use the COPY statement from the docker. There is possible to COPY element from directly from another image. Let’s try to copy the composer binary from the composer image. Add this statement after FROM.
COPY --from=composer /usr/bin/composer /usr/bin/composer
After that, the composer will be available for use inside the container.
Complete Dockerfile
FROM php:7.3-fpm
COPY --from=composer /usr/bin/composer /usr/bin/composer
RUN apt-get update && apt-get install -y \
gzip \
libbz2-dev \
libfreetype6-dev \
libicu-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
libsodium-dev \
libssh2-1-dev \
libxslt1-dev \
libzip-dev \
lsof \
default-mysql-client \
zip
RUN docker-php-ext-configure \
gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install \
bcmath \
bz2 \
calendar \
exif \
gd \
gettext \
intl \
mbstring \
mysqli \
opcache \
pcntl \
pdo_mysql \
soap \
sockets \
sodium \
sysvmsg \
sysvsem \
sysvshm \
xsl \
zip
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
RUN groupadd -g 1000 app \
&& useradd -g 1000 -u 1000 -d /var/www -s /bin/bash app
RUN mkdir -p /var/www/html \
&& chown -R app:app /var/www
USER app:app
VOLUME /var/www
WORKDIR /var/www/html
Build image
docker build -t <yournamespace>/php-fpm:7.3-magento2
Push a new image to the hub.
docker push <yournamespace>/php-fpm:7.3-magento2
Modify the docker-compose
Change image in phpfpm service to <yournamespace>/php-fpm:7.3-magento2
Download Magento
You have to configure Magento credentials before installation:
https://devdocs.magento.com/guides/v2.3/install-gde/prereq/connect-auth.html
We have all the needed extensions, so we can try to install the Magento store.
Remove all files from ./src. and following the instructions from https://devdocs.magento.com/guides/v2.3/install-gde/composer.html use the composer
composer create-project --repository-url=https://repo.magento.com/
magento/project-community-edition src/
Magento NGINX configuration
In Magento source files we can find the sample Nginx configuration file. Open ./src/nginx.conf.sample file. Magento developers tell us how to configure our NGINX server. Copy commented “upstream” and “server” part and paste it to /conf/app/etc/nginx/conf.d/default.conf. Set server to phpfpm:9000, $MAGE_ROOT to /var/www/html, server_name to _, and include to /var/www/html/nginx.conf.sample
Whole file:
upstream fastcgi_backend {
server phpfpm:9000;
}
server {
listen 80;
server_name _;
set $MAGE_ROOT /var/www/html;
set $MAGE_DEBUG_SHOW_ARGS 1;
include /var/www/html/nginx.conf.sample;
}
After that go up services
docker-compose up -d
Magento set up
Base configuration
Now, we have to set up the Magento database. Go into the phpfpm container docker-compose exec phpfpm bash, and run commands for set config values, and install base data
$ bin/magento setup:config:set --backend-frontname=admin --db-host=mysql --db-name=mydatabase --db-user=myuser --db-password=test123
$ bin/magento setup:install
After that create admin user:
$ bin/magento admin:user:create --admin-user='admin'
--admin-password='test123' --admin-email='admin@admin.com'
--admin-firstname='Admin' --admin-lastname='Admin'
Now, the sotre should be visible on http://127.0.0.1/.
And you should be able to login to the admin panel on http://127.0.0.1/admin using admin user data from admin:user:create command.
Sample data
You can install Magento sample data for better effect. Use
$ bin/magento sampledata:deploy
The above command needs your Magento marketplace credentials. You can find it on you account settings https://marketplace.magento.com/customer/accessKeys/.
To complete sample data installation you have to run
$ bin/magento setup:upgrade
$ bin/magento cache:flush
Now our store looks much better.
Elasticsearch
Adobe recommends Elasticsearch as the best search engine for the Magento store. Let’s try to configure this in our docker environment.
First, we have to add a new service in docker-compose.yml.
elasticsearch:
image: elasticsearch:7.7.1
ports:
- "9300:9300"
- "9200:9200"
environment:
discovery.type: single-node
Rebuild the environment:
$ docker-compose down
$ docker-compose up -d
Now, the search engine has to be changed in the admin panel. Go to http://127.0.0.1/admin. Select Stores -> Configuration -> Catalog -> Catalog -> Catalog Search. Select Elasticsearch 7+ in Search Engine field. Set Elasticsearch Server Hostname to elasticsearch. Now click “Test connection”. If the Elasticsearch service works, you should see
Now, Elasticsearch index needs to be fill. Go into the phpfpm container and run:
$ bin/magento indexer:reindex catalogsearch_fulltext
$ bin/magento cache:flush
Now, our store uses the elasticsearch indexes for search. You can verify the index data by simple curl request
$ curl -XGET 'localhost:9200/_search?size=1' -H 'Content-Type:
application/json' -d '{ "query": { "match_all": {} } }'
You can find sample product data in the response
{
"took":1,
"timed_out":false,
"_shards":{
"total":1,
"successful":1,
"skipped":0,
"failed":0
},
"hits":{
"total":{
"value":187,
"relation":"eq"
},
"max_score":1.0,
"hits":[
{
"_index":"magento2_product_1_v2",
"_type":"document",
"_id":"1",
"_score":1.0,
"_source":{
"store_id":"1",
"sku":"24-MB01",
"status":"1",
"status_value":"Enabled",
"visibility":"4",
"name":"Joust Duffle Bag",
"url_key":"joust-duffle-bag",
"description":"The sporty Joust Duffle Bag can't be beat - not in the gym, not on the luggage carousel, not anywhere. Big enough to haul a basketball or soccer ball and some sneakers with plenty of room to spare, it's ideal for athletes with places to go. Dual top handles. Adjustable shoulder strap. Full-length zipper. L 29\" x W 13\" x H 11\".",
"category_ids":[
2,
3,
4
],
"position_category_2":"0",
"name_category_2":"Default Category",
"position_category_3":"0",
"name_category_3":"Gear",
"position_category_4":"0",
"name_category_4":"Bags",
"price_0_1":"34.000000",
"price_1_1":"34.000000",
"price_2_1":"34.000000",
"price_3_1":"34.000000"
}
}
]
}
}
So, the Elasticsearch works!
Conclusions
During these tutorials, we set up full Magento 2 store in a docker environment. After reading entire articles you should be able to
- install docker and docker-compose
- create simple PHP, Mysql, NGINX environment in docker-compose
- set up initial MySql data in docker
- build own docker images
- configure php-fpm and NGINX for Magento 2
- run Elasticsearch in docker
- configure Magento to use Elasticsearch
There are still many ways to improve Magento 2 development in docker, but everyone needs their own tutorial but I tried to convey the basics for further works.
You can find many complex solutions using the docker, I recommend to use it instead of reinventing the wheel. Knowledge from these articles will help you a better understand, and adept at another solution.
I think, one of the best Magento 2 and Docker toolbox is: https://github.com/markshust/docker-magento
FIles from this part of the tutorial are there:
https://github.com/pandagrouppl/docker-magento-tutorial/tree/PART-3
If you would like to learn more please check on: