# PhpStorm with Docker

I have come across developers on social media and at various jobs having trouble setting up their editors when Docker is involved. In this article, I will go over [PhpStorm](https://www.jetbrains.com/phpstorm/) and how to use it properly with Docker. When using Docker, it is usually best to run various scripts and binaries from the Docker container versus running locally. This includes linters, formatters, and even tests.

In this article, I will use a [Laravel](https://laravel.com) application with [Laravel Sail](https://laravel.com/docs/10.x/sail) as an example for configuration PhpStorm.

## Laravel Sail Installation

Use the following command to spin up a new Laravel application with Sail:

```bash
curl -s "https://laravel.build/phpstorm-docker" | bash
```

This can take several minutes to complete. Once it is done, run `sail up` to start the application.

```bash
/vendor/bin/sail up
```

> **Quick Tip:** Add a relative folder to your PATH to enable calling binaries from Composer and Node by using the name of the binary instead of the whole path. In your `.zshrc` or `.bashrc`, add the following:
> 
> ```bash
> export PATH="./vendor/bin:$PATH"
> export PATH="./node_modules/.bin:$PATH"
> ```
> 
> Then, instead of calling `/vendor/bin/sail up`, it is now possible to call `sail up`!

## Set the PhpStorm PHP Interpreter

Open the settings window and go to the PHP section. From there, click the `...` next to the CLI Interpreter box.

![Add new interpreter](https://cdn.hashnode.com/res/hashnode/image/upload/v1696774879746/9806bb79-1d61-4dff-956c-e4163c988ae3.png align="center")

You may have a local PHP interpreter set up. Now you’ll want to add the Docker interpreter. Use the `+` in the top left and select the “From Docker, Vagrant, VM, WSL, Remote…” option.

![Add new interpreter](https://cdn.hashnode.com/res/hashnode/image/upload/v1696775010440/29e7720a-4763-438f-b5fb-663fe291a668.png align="center")

In the next popup, select the “Docker Compose” option. This shows a list of available services included in the `docker-compose.yml` file. Select the `laravel.test` service, which is the PHP container for Sail.

![Select service from Docker Compose file](https://cdn.hashnode.com/res/hashnode/image/upload/v1696775053596/6c9f8137-b85a-4734-8dcf-9c750278ba50.png align="center")

Now, the new PHP interpreter should be set as the default for the project.

![New interpreter set](https://cdn.hashnode.com/res/hashnode/image/upload/v1696775102245/e028817c-e013-4f2d-931f-2dc9c341cf78.png align="center")

With the interpreter setup, let’s look at running [Laravel Pint](https://laravel.com/docs/10.x/pint) to format files.

## Running Linters and Formatters in Docker Container

For this article, I will look at running Laravel Pint. However, this same method can be used for PHP CS Fixer, PHPStan, and other quality tools. Later, I will also go through how to do this with Node and tools like Prettier.

### Laravel Pint

To start:

1. Go to Settings &gt; PHP &gt; Quality Tools.
    
2. Expand the Laravel Pint section and turn on the Pint.
    
3. Set the configuration to the interpreter pointing to the Docker container, in my case, it is `laravel.test`.
    
4. Click the three dots `...` to set up Pint for the interpreter.
    

![Set up Laravel Pint](https://cdn.hashnode.com/res/hashnode/image/upload/v1696776066029/746333f8-d191-4495-85e1-1f86f7b08800.png align="center")

After clicking the three dots `...`, a new window opens to allow you to add a new Pint configuration.

![Create a new Laravel Pint configuration](https://cdn.hashnode.com/res/hashnode/image/upload/v1696776238014/ff68af35-b02d-4108-b685-1f0961330e6f.png align="center")

1. Click the plus icon `+` in the top left.
    
2. Select the interpreter pointing to the Docker container.
    

After selecting the interpreter and hitting "OK", the configuration should be created. The next step is to set the path and validate.

1. In the "Laravel Pint path" field, add `vendor/bin/pint` to point to the Pint binary in the Composer vendor directory.
    
2. Click the "Validate" button.
    
3. If everything is correct, the Pint version should be shown at the bottom.
    

![Set Laravel Pint path](https://cdn.hashnode.com/res/hashnode/image/upload/v1696776365332/35d2624c-20b9-4995-ae90-ce2f5c04d0e4.png align="center")

With this set, Pint needs to be set as the external formatter. Back in Settings &gt; PHP &gt; Quality Tools, scroll to the bottom and click the radio for "Laravel Pint" in the "External formatters" section.

![Set Pint as the external formatter](https://cdn.hashnode.com/res/hashnode/image/upload/v1696776592747/4a4428a4-7cb4-40d1-a140-bcae085d6db6.png align="center")

Now, the code can be reformatted using Laravel Pint from the Docker container.

![Reformat code with Docker Laravel Pint](https://cdn.hashnode.com/res/hashnode/image/upload/v1696777137595/0026f298-f7e7-4784-9031-3172e6cc26b0.gif align="center")

In the example above, the incorrect code is underlined with a squiggly line because it does not follow the formatting set by Laravel Pint. After formatting, the class and method braces are fixed, braces are added to the conditional, and a blank line is added above the return statement.

To make this even easier, enable formatting on save. To accomplish this, go into Settings &gt; Tools &gt; Actions on Save and check the box for "Reformat Code".

![Reformat code on save](https://cdn.hashnode.com/res/hashnode/image/upload/v1696801057836/73d22701-933f-4498-abee-7b4a82c77688.png align="center")

Now, anytime a file is saved, it will automatically be formatted by Laravel Pint, running on the Docker container.

### Prettier

First, install Prettier using the following command:

```bash
sail npm install --save-dev --save-exact prettier
```

Notice the command was prefixed with `sail`, which installs Prettier using the version of Node and npm on the Docker container versus the local version.

Next, similar to PHP, create a Node interpreter that points at the Docker version. Go to Settings &gt; Languages & Frameworks &gt; Node.js. From there, click the three dots `...` next to "Node interpreter".

![Create a new Node interpreter](https://cdn.hashnode.com/res/hashnode/image/upload/v1696801557390/96af3951-75d3-4898-8f9a-e471b6535888.png align="center")

In the new window, click the plus `+` button in the top left. Then select "Add Remote...".

![Add remote Node interpreter](https://cdn.hashnode.com/res/hashnode/image/upload/v1696801687370/72cc36d3-1f82-4942-8f09-560b5f66d356.png align="center")

Just like before with PHP, select the "Docker Compose" option and select the `laravel.test` service.

![Configure the Node.js Remote Interpreter](https://cdn.hashnode.com/res/hashnode/image/upload/v1696801769008/54b70de0-7051-4dc0-b3d4-a2c91e832398.png align="center")

Node is now pointing at the version in the Docker container. To continue with Prettier, go to Settings &gt; Languages & Frameworks &gt; JavaScript &gt; Prettier.

![Set Prettier configuration](https://cdn.hashnode.com/res/hashnode/image/upload/v1696802342441/91ba5efe-9a6d-4e60-812f-4076d2e13a37.png align="center")

In the Prettier settings:

1. Select "Automatic Prettier configuration".
    
2. Check "Run on save" for automatic formatting when saving a file.
    

Now, Prettier is all setup and running right from the Docker container. These same steps can be followed to run ESLint.

## Running Tests from Docker Container

For this article, I will be using PHPUnit. However, the same steps will also apply to Pest and JavaScript test runners like Jest.

Since `laravel.test` is already set as the default interpreter for the project, the tests should automatically run using PHPUnit from the Docker container. This can be seen by running a test:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1696804796986/f1f35826-d0f3-42b7-a548-982c2c2da50e.png align="center")

After running the test, the test output shows the command. You can see it was run using `docker-compose` pointing at the `laravel.test` service of the local `docker-compose.yml` file.

If, for some reason, this is not working, maybe an existing project with other configurations, or an alternate test framework, you can continue with the next steps.

Go into Settings &gt; PHP &gt; Test Frameworks. Then, click the plus `+` button to add a new test framework.

![Create a remote test framework](https://cdn.hashnode.com/res/hashnode/image/upload/v1696803590527/eec22fdf-a032-4600-aea9-a3c93d766d49.png align="center")

Select the `laravel.test` interpreter from the new window:

![PHPUnit remote interpreter](https://cdn.hashnode.com/res/hashnode/image/upload/v1696803641688/0058af7f-f531-44df-9202-7ef6297f1b60.png align="center")

Now, a new PHPUnit Test Framework is available.

![Remote PHPUnit test framework](https://cdn.hashnode.com/res/hashnode/image/upload/v1696803723916/13b5936b-9003-439e-b407-8b98e54ad531.png align="center")

Next, modify the run configurations by going to the Run menu and selecting "Edit Configurations...".

![Edit run configurations](https://cdn.hashnode.com/res/hashnode/image/upload/v1696803951324/957e9597-fe4e-46f6-9d47-4b579ce699a9.png align="center")

From the new window, click the gear icon next to the "Use alternative configuration file" field.

![Set PHPUnit test framework configuration](https://cdn.hashnode.com/res/hashnode/image/upload/v1696804147917/2bbf0a8b-b37a-419f-a4c2-8a5909b14535.png align="center")

This opens a new window to select the new remote PHPUnit configuration.

![Set remote interpreter for tests](https://cdn.hashnode.com/res/hashnode/image/upload/v1696804235573/fe43f1a3-4515-4242-8bc6-b33e91cab544.png align="center")

Finally, make sure the configuration is pointing to the `laravel.test` interpreter or the default interpreter if it is set as `laravel.test`.

![Set remote interpreter for tests](https://cdn.hashnode.com/res/hashnode/image/upload/v1696805186731/558c429e-3012-4c0f-87a3-71a9ddc420fd.png align="center")

That's it! Everything should now be set up to run PHPUnit from the Docker container.

## Package Managers

You can even run your package managers like Composer and npm from the Docker container.

### Composer

Go to Settings &gt; PHP &gt; Composer, then:

1. Select the radio for "Remote Interpreter".
    
2. Select `laravel.test` as the "CLI Interpreter".
    

![Run Composer from Remote Interpreter](https://cdn.hashnode.com/res/hashnode/image/upload/v1696810721973/96ce63fc-5b33-4753-acec-d431cb1d4e35.png align="center")

With Composer set, go to Tools &gt; Composer, and select a command that will be run from the Docker container.

![Composer commands in PhpStorm](https://cdn.hashnode.com/res/hashnode/image/upload/v1696810872956/d01a15ed-8e00-4281-b0ca-1eef50ca135e.png align="center")

### npm

For npm, the remote Node interpreter should have already been set up from the Prettier steps above. Now, open the npm tool window.

![npm Tool window](https://cdn.hashnode.com/res/hashnode/image/upload/v1696811020500/7f0789bc-dacb-4edd-a0b2-59f16091b93f.png align="center")

The npm tool window will show all the scripts configured in the `package.json` file. Right-click on the `dev` script and click "Edit 'dev' Settings...".

![Edit npm configurations](https://cdn.hashnode.com/res/hashnode/image/upload/v1696811146605/664d386c-75f4-4628-ba2e-a266477463a9.png align="center")

With the new window open:

1. Set the "Node interpreter" to the Docker compose `laravel.test` interpreter if it is not already set.
    
2. Add a new environment variable: `WWWUSER=sail`. This prevents PhpStorm from trying to run the npm commands as the `npm` user.
    

![npm run configuration](https://cdn.hashnode.com/res/hashnode/image/upload/v1696811259162/5478493f-0c36-4211-8e58-f7656ebb80f4.png align="center")

Now, the `dev` script can be run from the npm tool window and the output is shown in PhpStorm.

![npm script running in PhpStorm](https://cdn.hashnode.com/res/hashnode/image/upload/v1696811486201/26d25e91-60de-424b-82b6-1890f3cfcc65.png align="center")

## Conclusion

I hope this is helpful for anyone working on a project with a Docker configuration. Though running these scripts and binaries from Docker can be slower than running locally, it does have the benefit of making sure all the developers on the project are running the same versions. This should help prevent the infamous "it runs on my computer" type issues. By using Docker, these various languages, scripts, and binaries also do not need to be installed locally. I can have all of this running without even having Node installed on my local machine.

Thanks for reading! Please let me know if you have any questions in the comments.
