Making Podman, DevPod, and PHPStorm play nice
DevContainers are cool, but permissions and SELinux are not
The new girl on the block are DevContainers, and I was keen to use them all this time because I was already accustomed to open Docker and use a container with remote interpreters (like PHP, Node, and others) through the locally installed IDE. As I changed Linux distributions, I finally decided to give them a chance.
DevContainers presents themselves the best from containers (isolation, reproduction), but most importantly, easier to build, run and configure. I mean, they’re just a JSON file that tells how to run a Dockerfile or even another DevContainer image. DevContainers simplify a lot and they “just work”.
After surfing the Internet for a good way to manage DevContainers, I ended up with three weapons of choice:
- DevPod to manage my different DevContainers.
- Podman to handle rootless DevContainers.
- PHPStorm and VSCode to code on them.
Personally, I consider VSCode a very patchy way to work with PHP, but that was years ago, and I haven’t looked back to see how is the state of VSCode regarding developing for the pixie violet elephant. I’ll stick to PHPStorm until I cannot longer pay the yearly subscription, because it’s very good at making me fast at work.
Back to the point, luckily for me, when I switched from Ubuntu to Fedora Workstation, I noted that the guys at Universal Blue created their own Fedora spin tailored for developers called Bluefin (for GNOME) and Aurora (for KDE). Both spins include Podman and DevPod out of the box, and even JetBrains Toolbox with a single ujust install-jetbrains-toolbox
command.
Now, the thing I had to do was to test how PHPStorm would work on DevContainers.
Preface: DevContainers in JetBrains are kind of beta
I noted immediately that JetBrains had built-in compatibility with DevContainers, so my first instinct was to give it a spin.
Not only the container took like three times more to build compared to DevPod, but also commands were painfully slow to work with: Terminal, PHP itself, anything.
I also tried to configure Podman, and even use the podman
CLI instead of docker
to no avail, as I would get this error when building the image:
Can't retrieve image ID from build stream
Until these problems are fixed, I would need to use DevPod (or VSCode directly) to build a DevContainer, and then use the SSH data to connect to it.
Hello DevPod, hello Podman
DevPod is basically an open-source answer from Loft to GitHub Codespaces, which are cloud exclusive. In other words, you can create DevPods anywhere you want: locally, on another network computer, or in the cloud too.
The first thing I tried on DevPod was to use vanilla Docker to do the same. After that, I created a DevContainer from the project I was working on, and JetBrains Gateway didn’t connect to the container.
The DevContainer created by DevPod is registered in the SSH configuration of the current user profile. This allows SSH to connect to the container using a friendly name, like “my-app.dev” instead of juggling your way to the DevContainer.
I figured out that for some reason the SSH configuration wasn’t retrieved correctly, as any attempt to connect was a failure. I had to set the configuration parse to “Legacy”, which forces the IDE to read the config file of the current user instead of the command output (and failing because it’s not OpenSSH).
I tried again, but commands were still unresponsive in the IDE, so I switched providers in Devpod for Podman just to see if it was Docker all along (spoilers alert: it was).
To use DevPod with Podman, all I had to do was to point out the Podman socket and the podman
binary in the provider configuration.
While building and connection was a success, file permissions were not. Even if the user ID was the same between the host and the container, which is normally 1000:1000
, the container couldn’t see the project files. After some surfing around the Internet, I found the culprit (SELinux) and the fix (ignoring SELinux).
I needed to add some arguments to the DevContainer JSON to disable SELinux checking on the correct labels on the project folder inside container. Just for bonus, I also added a flag (only readable by Podman, as it will throw an error if run with Docker) to use the same User ID for the container namespace.
"runArgs": [
"--userns=keep-id", "--security-opt", "label=disable"
],
And finally, after so much going around, permissions were fixed, and commands were responsive as expected.
DevPod offers two ways to work with the IDE. The first is obvious, you only get the SSH connection details, and your IDE will have to prepare the container to connect, which PHPStorm does automatically when you issue the SSH connection details on a freshly created container.
The other alternative is let DevPod download the IDE for you and then let the IDE in your host connect to it. Both approaches are practically the same, except that DevPod requires JetBrains Gateway for this to work.
In my case, I don’t like to open JetBrains Gateway, so I manage the SSH connection on PHPStorm exclusively and hope for the best, which is currently working fine. The rest is up to you, especially when dealing with ports forwarding (which seems very hit and miss).