When I first started with PHP a long time ago, I really had trouble setting up work environment.
I had no clue about what I was doing.
Don’t ask me how, but I ended up with Apache Tomcat running PHP.
Honestly, I don’t know if I could even set up such a blasphemy today.
EDIT NOTE:
Due the fact that udovicic/echo:apache-php7.1 is updated, you no longer need apache config, so I edited this post and removed apache configuration.
Over the years I went the whole path from xampp, manual LAMP setup, vagrant…
All those had at least 1 dealbreaker, especially when I started working with Magento.
Finally, Docker came and made development much easier.
At this point, it becomes a little bit tricky to explain what Docker is.
It performs operating system level virtualization (containerization) which refers to the operating system feature in which the kernel allows the existence of multiple isolated user-space instances.
If the sentence above doesn’t make any sense to you, then maybe it would be wise to visit http://www.docker.com and at some point come back here, otherwise, continue reading…
What I’m going to share now is not some Docker wisdom. It is more about setup capable of running Magento 2 via Docker, so this article assumes that you are somewhat familiar with Docker.
So, let’s begin…
Let’s run Magento 2 on let’s say http://m2.docker
First thing you should do is add this line somewhere in your /etc/hosts file:
127.0.0.1 m2.docker www.m2.docker
We will need some filesystem structure, so do the following:
tomas ~ $ mkdir m2.docker
tomas ~ $ cd m2.docker/
tomas ~/m2.docker $ mkdir docker
tomas ~/m2.docker $ mkdir html
tomas ~/m2.docker $ mkdir -p docker/db
tomas ~/m2.docker $ touch docker/xdebug.ini
tomas ~/m2.docker $ touch docker/apache.conf
tomas ~/m2.docker $ touch docker-compose.yml
tomas ~/m2.docker $ touch .env
Now, let’s go file by file:
.env
In this file you can write variables that will be used in docker-compose.yml
Mine looks like this:
CONTAINER_PREFIX=m2docker
SERVER_NAME=m2.docker
SERVER_ALIAS=www.m2.docker
DIRECTORY_NAME=m2.docker
WEB_USER=inchoo
WEB_ROOT = /var/www/html
MYSQL_DB_HOST = ${CONTAINER_PREFIX}_db_1
MYSQL_DATABASE=inchoo
MYSQL_ROOT_USERNAME=root
MYSQL_ROOT_PASSWORD=inchoo
MYSQL_USER=inchoo
MYSQL_PASSWORD=inchoo
DOCKER_EXEC=docker exec
DOCKER_EXEC_INTERACTIVE=docker exec -i
DOCKER_EXEC_TTY=${DOCKER_EXEC_INTERACTIVE} -t
For docker-compose.yml you will need code below.
I also added some comments with links to documentation.
Note that I’m using apache-php image created by my colleague Stjepan and I highly recommend it for development.
# https://docs.docker.com/compose/compose-file
version: "3.6"
# https://docs.docker.com/compose/compose-file/#service-configuration-reference
services:
#custom name
apache-php:
# https://docs.docker.com/compose/compose-file/#image
# https://githheizenberg ub.com/udovicic/echo => https://hub.docker.com/r/udovicic/echo/
image: udovicic/echo:apache-php7.1
# https://docs.docker.com/compose/compose-file/#ports
ports:
- "80:80"
# https://docs.docker.com/compose/compose-file/#expose
expose:
- "9000"
# https://docs.docker.com/compose/compose-file/#volumes
volumes:
- ./docker/xdebug.ini:/etc/php/7.1/mods-available/xdebug.ini
- ./html:/var/www/html
# https://docs.docker.com/compose/compose-file/#environment
environment:
- TERM=xterm-256color
- APACHE_RUN_USER=1000
# https://docs.docker.com/compose/compose-file/#network-configuration-reference
networks:
default:
aliases:
- ${SERVER_NAME}
- ${SERVER_ALIAS}
db:
# https://hub.docker.com/_/mysql/
image: mysql:5.7
volumes:
- ./docker/db/data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
redis:
# https://hub.docker.com/_/redis/
image: redis:latest
phpmyadmin:
# https://hub.docker.com/r/phpmyadmin/phpmyadmin/
image: phpmyadmin/phpmyadmin
ports:
- "8080:80"
environment:
MYSQL_USERNAME: ${MYSQL_ROOT_USERNAME}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
…and xdebug.ini
zend_extension=xdebug.so
xdebug.remote_autostart=0
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.remote_connect_back=1
A this point we have working environment, so let’s try to run it:
tomas ~/m2.docker $ docker-compose up -d
Creating network "m2docker_default" with the default driver
Creating m2docker_apache-php_1 ... done
Creating m2docker_redis_1 ... done
Creating m2docker_phpmyadmin_1 ... done
Creating m2docker_db_1 ... done
tomas ~/m2.docker $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e3384b0eff8c mysql:5.7 "docker-entrypoint.s…" 3 seconds ago Up 2 seconds 3306/tcp m2docker_db_1
d283bf018330 phpmyadmin/phpmyadmin "/run.sh phpmyadmin" 3 seconds ago Up 2 seconds 9000/tcp, 0.0.0.0:8080->80/tcp m2docker_phpmyadmin_1
ded8bce1d993 redis:latest "docker-entrypoint.s…" 3 seconds ago Up 2 seconds 6379/tcp m2docker_redis_1
fe8a80763ac6 udovicic/echo:apache-php7.1 "/start.sh" 3 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, 9000/tcp m2docker_apache-php_1
tomas ~/m2.docker $
Now when it works…
Magento should be installed in “html” directory.
Note that you need to use “db” when referring to database address, and so on. Just check docker-compose.yml (service name).
Also, relevant credentials are in .env file.
PhpMyAdmin is available @ http://m2.docker:8080
This is a very basic setup. I usually create git repository which initially ends up with 2 branches like for example m2-docker and master and then I copy .git directory into html and checkout master branch while in the base directory I checkout m2-docker branch.
Thanks for reading.