[mini-guide] podman devcontainers

I have recently been living with the consequences of my decision to override remove everything docker, which have mostly been nil but configuring devcontainers proved to be a bit of a challenge so I thought I’d write up a mini-guide to how I did it.

see also this previous thread for devpod: Community Guide: Setting up devpod with podman - #21 by phreed

the first thing (after installing the devcontainers extension) is to set podman as the provider, which should not be necessary if you layered podman-docker but this should work in all cases

here I specify a compose path in case you want more complex setups, but this is not required for the simple use case:

{
    "dev.containers.dockerComposePath": "podman-compose",
    "dev.containers.dockerPath": "podman"
}

this likely goes in your vscode user settings JSON, or project, or default, take your pick (or just set it in the UI) :slight_smile:

you then want to enable the podman socket systemd unit so the clients can communicate with it in a manner more similar to docker:

systemctl --user enable podman.socket
systemctl --user start podman.socket

verify this with (outside a container, unless you’re doing dind):

systemctl --user status podman.socket
ls -l $XDG_RUNTIME_DIR/podman/podman.sock

next, you just need one file in the .devcontainer directory (don’t forget to add this to your .gitignore if you’re working on a shared project):

here I’m using a reference golang devcontainer image from microsoft with a few quality of life addons:

.devcontainer/devcontainer.json

{
    "name": "My DevContainer Project",
    "image": "mcr.microsoft.com/devcontainers/go:1.23",
    "customizations": {
        "vscode": {
            "extensions": [
                "golang.go",
                "eamodio.gitlens",
                "streetsidesoftware.code-spell-checker"
            ],
            "settings": {
                "go.useLanguageServer": true,
                "go.toolsEnvVars": {
                    "GOPATH": "/home/vscode/go"
                }
            }
        }
    },
    "features": {
        "ghcr.io/devcontainers/features/go:1": {
            "version": "1.23"
        }
    },
    "forwardPorts": [],
    "postCreateCommand": "go mod download",
    "remoteUser": "vscode",
    "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached,relabel=private",
    "workspaceFolder": "/workspace",
    "containerEnv": {
        "GOPATH": "/home/vscode/go"
    },
    "runArgs": ["--userns=keep-id"],
    "containerUser": "vscode"
}

the things to pay attention to here are:

  • devcontainers feature for the go version, this is not strictly required but gives you more certainty about your toolchain matching what you requested
  • postCreateCommand: this is where you can install extra components if not using a custom Dockerfile, in my case I just make sure my modules are all in place
  • remoteUser, containerUser, runArgs: I have found setting all three like this to be necessary to get the permissions to align
  • workspaceMount: very important, specifically type=bind and relabel=private are absolutely necessary to get the folder mounted with correct SELinux labeling

…and, that’s it! you should be automatically prompted to reopen the project in devcontainer, and after the initial build the startup should be quite fast

if you need more complex SELinux labeling (for example for GPU access) using GitHub - containers/udica: This repository contains a tool for generating SELinux security profiles for containers might be a good next step, but this should work for most projects

7 Likes