PhpStorm is my preferred IDE for PHP (and some other projects too). Using it has definitely accelerated my development process, but recently I lost a few hours when trying to run a working phpUnit test framework inside PHPStorm. To be honest, it was me, who did not look carefully, or misunderstood the brand new docker compose feature in the IDE.

The situation

The project I am working on comes in two docker containers, one contains the application,
the other one the mysql database – nothing fancy. There is a docker integration in PhpStorm since version 2013.2, which works well for single containers, but did not run as good with a network of containers. PhpStorm 2017.2 closes this gap:

PhpStorm 2017.2 introduces native support for Docker Compose to make using Docker and PhpStorm even easier […]

Gary Hockin – New Docker-Compose Support in PhpStorm

In case you’re not using Docker Compose: Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. This makes managing the web of containers needed to develop and (ultimately deliver your project using Docker Stack) much easier than having several individual docker files that need to be brought up in the right order.

Anyway, after installing PHPUnit via composer inside the application container I wrote a first test case, just to make sure everything works fine. This integration test required a database connection, and this is where the trouble started.

The problem

From inside the docker container the test framework was running – a database connection was established. Doing the very same inside PhpStorm I got an error. I configured the PHPUnit as described in this guide from PHPStorm. Here is what I got:

#using localhost
SQLSTATE[HY000] [2002] No such file or directory

SQLSTATE[HY000] [2002] Connection refused

#using "mysql" 
# as configured inside the link section in docker-compose.yml
SQLSTATE[HY000] [2002] php_network_getaddresses: 
  getaddrinfo failed: Name or service not known

#same using the docker container name
SQLSTATE[HY000] [2002] php_network_getaddresses: 
  getaddrinfo failed: Name or service not known

Slightly frustrated, I called an ex colleague, asking for an idea. We re-tested the options, re-checked the YAML file. Per settings the mysql container was exposed to the outside world by mapping the container’s MySQL port to the host machine port. Everything should work as aspected.

Short notice on the IP vs. localhost thing vs. localhost is a classic on mac OSx. uses TCP/IP and localhost uses sockets. The default php.ini file points to the wrong place for the mysql.sock so you have to do is change it or you create a symlink between the entries:

sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock

But enough of this, the use of TCP/IP / sockets was not the problem. My colleague asked me to list all docker containers (docker ps -a), and hello, PhpStorm created own container, named phpstorm_helpers[…].

This might explain the connection trouble. There was simply no linking between the PhpStorm- and the project mysql container. We tested again, this time using the mysql container ip-address as the db-host, and yes, we had a connection.

To find the ip-address of a container, do the following:

#to find the id of a container, type..
docker ps 
#copy the id and
docker inspect -f '{{ .NetworkSettings.IPAddress }}' #container-id#

But isn’t this what I expect, when using the docker compose YAML? That the IDE uses the information to setup everything correctly? I re-checked the preference settings one more time. I had just updated to version 2017.2, maybe I had overlooked something? And yes, it was all my fault.

The solution

Let PHPStorm, Docker and PHPUnit work together like charm:

  1. Prerequisites: You need Docker for sure. Please refer to the Docker documentation to get more information about the installation process. For setting up docker in PhpStorm – go to preferences > Build, Execution, Deployment > Docker
    In case you use Docker for Mac simply choose this option. If not, follow these instructions to integrate docker support.

  2. Choosing the interpreter: Go to preferences > Languages & Frameworks > PHP
    Add a new interpreter (Use the Option from Docker, Vagrant…), then choose Docker compose, and select your composer YAML file, and the service, for this PhpStorm provides a list of services (containers) to pick from (You can select any container that provides command-line PHP).

    Once you’ve configured your docker-compose interpreter you’ll see that PhpStorm will infer the path mappings automatically from the volumes section of your configuration file

  3. Now for Testing: Go to preferences > Languages & Frameworks > PHP > Test Frameworks
    Select the interpreter you just created, and fill in the PHPUnit library information. In my case: using composer autoloader. Be aware that the path is the path of the container, not the physical path from the host.

That’s it. Now everything worked, but what went wrong in the first place?

As mentioned above, the possibility of using docker-compose comes with the version 2017.2. I changed the version after installing the project. In the moment I had updated the system and opened the project, a message came up, that I could use the corresponding YAML file for the docker container(s). I clicked on “ok” and thought how nice, everything works automatically. Unfortunately it was just an info-popup, not a call-to-action. The project preferences stayed unchanged, using “docker” instead of the new “docker compose”.

So thanks again, Marian, for your support – and sorry for my blindness. And for all who work with docker-compose and PhpStorm, switch to the new option, to get the most out of it.