From d022e705a40146fae4e4459e5922c769b0f308c5 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Thu, 14 May 2026 07:15:56 -0500 Subject: [PATCH 1/5] docs: add Podman provider tutorial and promote to first-party --- .../pages/managing-providers/add-provider.mdx | 2 +- .../pages/tutorials/podman-provider-setup.mdx | 179 ++++++++++++++++++ docs/sidebars.js | 4 + 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 docs/pages/tutorials/podman-provider-setup.mdx diff --git a/docs/pages/managing-providers/add-provider.mdx b/docs/pages/managing-providers/add-provider.mdx index 9824643a2..0242f5927 100644 --- a/docs/pages/managing-providers/add-provider.mdx +++ b/docs/pages/managing-providers/add-provider.mdx @@ -6,6 +6,7 @@ sidebar_label: Add a Provider The Devsy team maintains providers for popular services such as: - [Docker (docker)](https://github.com/devsy-org/devsy/tree/main/providers/docker) +- [Podman (podman)](https://github.com/devsy-org/devsy/tree/main/providers/podman) - [Kubernetes (kubernetes)](https://github.com/devsy-org/devsy-provider-kubernetes) - [SSH (ssh)](https://github.com/devsy-org/devsy-provider-ssh) - [AWS (aws)](https://github.com/devsy-org/devsy-provider-aws) @@ -235,7 +236,6 @@ The community maintains providers for additional services. - [Open Telekom Cloud (akyriako/devsy-provider-opentelekomcloud)](https://github.com/akyriako/devsy-provider-opentelekomcloud) - [Vultr (navaneeth-dev/devsy-provider-vultr)](https://github.com/navaneeth-dev/devsy-provider-vultr) - [STACKIT (stackitcloud/devsy-provider-stackit)](https://github.com/stackitcloud/devsy-provider-stackit) -- [Podman (kuju63/devsy-provider-podman)](https://github.com/kuju63/devsy-provider-podman) These providers can be installed with the Devsy CLI in the following form: ``` diff --git a/docs/pages/tutorials/podman-provider-setup.mdx b/docs/pages/tutorials/podman-provider-setup.mdx new file mode 100644 index 000000000..e0b1f24ea --- /dev/null +++ b/docs/pages/tutorials/podman-provider-setup.mdx @@ -0,0 +1,179 @@ +--- +title: Podman Provider Setup +sidebar_label: Podman Provider Setup +--- + +## Introduction + +Podman is a first-class provider in Devsy. It runs containers without a background daemon — each container is a direct child of the calling process — which eliminates the single-point-of-failure that a persistent Docker daemon introduces. Podman is OCI-compatible, so existing `devcontainer.json` configurations work without changes. + +This tutorial walks through installing Podman on your platform, registering it as a Devsy provider, and starting a workspace. + +## Prerequisites + +Install Podman for your platform before registering it as a Devsy provider. + +### Linux + +Install `podman` from your distribution's package manager: + +```bash +# Debian / Ubuntu +sudo apt-get install -y podman + +# Fedora / RHEL / CentOS +sudo dnf install -y podman + +# Arch Linux +sudo pacman -S podman +``` + +### macOS + +Install via Homebrew or download [Podman Desktop](https://podman-desktop.io): + +```bash +brew install podman +podman machine init +podman machine start +``` + +### Windows + +Podman on Windows runs inside WSL2. Install WSL2 first, then install Podman inside your WSL distro. + +**Step 1 — Enable WSL2.** Run the following in **PowerShell (as Administrator)** and restart when prompted: + +```powershell +wsl --install +``` + +**Step 2 — Install Podman inside WSL.** Open your WSL terminal and run: + +```bash +sudo apt-get update && sudo apt-get install -y podman +``` + +**Step 3 — Verify the socket is reachable from Windows.** Note the socket path — you will need it for the `PODMAN_HOST` option: + +```bash +echo $XDG_RUNTIME_DIR/podman/podman.sock +``` + +## Adding the Podman Provider + +Register the built-in Podman provider with Devsy: + +```bash +devsy provider add podman +``` + +Devsy downloads the provider manifest and registers `podman` as an available provider. Confirm it appears in your provider list: + +```bash +devsy provider list +``` + +## Configuration Options + +The Podman provider exposes three options: + +| Option | Default | Description | +|--------|---------|-------------| +| `PODMAN_PATH` | `podman` | Path to the `podman` binary. Override when `podman` is not on `PATH` — for example, `/usr/local/bin/podman`. | +| `PODMAN_HOST` | *(unset)* | Podman host socket or TCP address (sets `DOCKER_HOST` internally). Required on Windows to point Devsy at the WSL socket, e.g. `unix:///run/user/1000/podman/podman.sock`. | +| `INACTIVITY_TIMEOUT` | *(unset)* | Stops the container after the specified idle period. Accepts duration strings such as `10m` or `1h`. | + +Set options interactively after adding the provider: + +```bash +devsy provider set-options podman +``` + +Or pass them inline at add time: + +```bash +devsy provider add podman -o PODMAN_PATH=/usr/local/bin/podman -o INACTIVITY_TIMEOUT=1h +``` + +## Rootless vs Rootful Setup + +Podman can run in two modes: + +| Mode | How it works | When to use | +|------|-------------|-------------| +| **Rootless** (default) | Containers run as your user. User namespaces isolate processes from the host. | Recommended for most development workflows. Reduces the blast radius of a compromised container. | +| **Rootful** | Containers run as root inside a Podman machine. | Required when a container needs to bind-mount paths owned by root, or when certain network configurations (e.g. macvlan) are needed. | + +**macOS / Windows — switching machine mode:** + +```bash +# Initialize a new rootful machine (replaces the default rootless one) +podman machine init --rootful + +# Or upgrade an existing machine in-place +podman machine set --rootful +podman machine stop && podman machine start +``` + +**Linux — rootless is the system default.** To run rootful containers, prefix commands with `sudo` or add your user to the `wheel` / `sudo` group and run `podman system service` as root. + +:::info +After switching to rootful mode on macOS or Windows, update the `PODMAN_HOST` option in Devsy to point to the rootful socket. The rootful socket path is typically `/run/podman/podman.sock` (inside the VM). +::: + +## Creating a Workspace with Podman + +Start a workspace using the Podman provider by passing `--provider podman` to `devsy up`: + +```bash +devsy up --provider podman --id my-workspace https://github.com/my-org/my-repo +``` + +Devsy builds the workspace image with Buildah (Podman's built-in build tool) and starts the container. When the workspace is ready, connect to it: + +```bash +devsy ssh my-workspace +``` + +Verify the container runtime inside the workspace: + +```bash +echo $DEVSY_PROVIDER +# podman +``` + +## Troubleshooting Common Issues + +### Socket not found or permission denied + +Devsy cannot reach the Podman socket. Check that the Podman machine is running: + +```bash +podman machine list +podman machine start # if the machine is stopped +``` + +On Linux, confirm the user socket exists: + +```bash +ls -la $XDG_RUNTIME_DIR/podman/podman.sock +``` + +If the socket path differs from the default, set `PODMAN_HOST` to the correct path: + +```bash +devsy provider set-options podman --option PODMAN_HOST=unix:///run/user/1000/podman/podman.sock +``` + +### Dockerfile features not supported during image build + +Podman uses Buildah for image builds, not Docker BuildKit. Most Dockerfiles are compatible, but a small number of BuildKit-specific syntax extensions (e.g. `RUN --mount=type=cache` with the `buildkit` frontend) may fail or behave differently. If your workspace image uses BuildKit-only syntax, remove the `# syntax=docker/dockerfile:1` pragma or restructure the affected `RUN` steps. + +### `podman compose` vs `docker-compose` + +Podman v4+ ships `podman compose` as a built-in subcommand backed by the `podman-compose` Python library. It is compatible with `docker-compose` v2 syntax for most workloads. If your `devcontainer.json` or workspace scripts call `docker-compose` directly, replace those calls with `podman compose` or create a shell alias: + +```bash +alias docker-compose='podman compose' +``` diff --git a/docs/sidebars.js b/docs/sidebars.js index caa732d6e..6300c5499 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -187,6 +187,10 @@ module.exports = { type: "doc", id: "tutorials/docker-provider-via-wsl", }, + { + type: "doc", + id: "tutorials/podman-provider-setup", + }, ], }, { From d95837b6ab63bf292b17415d45abfeeee348031d Mon Sep 17 00:00:00 2001 From: Samuel K Date: Thu, 14 May 2026 07:27:24 -0500 Subject: [PATCH 2/5] docs: fix review findings in Podman tutorial --- .../pages/tutorials/podman-provider-setup.mdx | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/pages/tutorials/podman-provider-setup.mdx b/docs/pages/tutorials/podman-provider-setup.mdx index e0b1f24ea..42c2c341f 100644 --- a/docs/pages/tutorials/podman-provider-setup.mdx +++ b/docs/pages/tutorials/podman-provider-setup.mdx @@ -3,7 +3,7 @@ title: Podman Provider Setup sidebar_label: Podman Provider Setup --- -## Introduction +## Purpose Podman is a first-class provider in Devsy. It runs containers without a background daemon — each container is a direct child of the calling process — which eliminates the single-point-of-failure that a persistent Docker daemon introduces. Podman is OCI-compatible, so existing `devcontainer.json` configurations work without changes. @@ -84,13 +84,19 @@ The Podman provider exposes three options: | `PODMAN_HOST` | *(unset)* | Podman host socket or TCP address (sets `DOCKER_HOST` internally). Required on Windows to point Devsy at the WSL socket, e.g. `unix:///run/user/1000/podman/podman.sock`. | | `INACTIVITY_TIMEOUT` | *(unset)* | Stops the container after the specified idle period. Accepts duration strings such as `10m` or `1h`. | -Set options interactively after adding the provider: +Set options after adding the provider using `--option` flags: ```bash -devsy provider set-options podman +devsy provider set-options podman --option PODMAN_PATH=/usr/local/bin/podman ``` -Or pass them inline at add time: +To see available options before setting them: + +```bash +devsy provider options podman +``` + +Or pass options inline at add time: ```bash devsy provider add podman -o PODMAN_PATH=/usr/local/bin/podman -o INACTIVITY_TIMEOUT=1h @@ -136,11 +142,10 @@ Devsy builds the workspace image with Buildah (Podman's built-in build tool) and devsy ssh my-workspace ``` -Verify the container runtime inside the workspace: +A successful `devsy ssh` connection confirms the workspace is running under Podman. To verify the Podman binary inside the workspace: ```bash -echo $DEVSY_PROVIDER -# podman +podman --version ``` ## Troubleshooting Common Issues From b90845f847f4cf83e1a405995743c48ae335e1a0 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Thu, 14 May 2026 07:32:58 -0500 Subject: [PATCH 3/5] docs: polish Podman tutorial per review feedback - Replace Buildah build attribution with accurate `podman build` phrasing - Add UID hint for PODMAN_HOST socket path examples - Use `id -u` in troubleshooting socket example - Simplify provider registration description --- docs/pages/tutorials/podman-provider-setup.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/pages/tutorials/podman-provider-setup.mdx b/docs/pages/tutorials/podman-provider-setup.mdx index 42c2c341f..cad3728fa 100644 --- a/docs/pages/tutorials/podman-provider-setup.mdx +++ b/docs/pages/tutorials/podman-provider-setup.mdx @@ -68,7 +68,7 @@ Register the built-in Podman provider with Devsy: devsy provider add podman ``` -Devsy downloads the provider manifest and registers `podman` as an available provider. Confirm it appears in your provider list: +Devsy registers `podman` as an available provider. Confirm it appears in your provider list: ```bash devsy provider list @@ -81,7 +81,7 @@ The Podman provider exposes three options: | Option | Default | Description | |--------|---------|-------------| | `PODMAN_PATH` | `podman` | Path to the `podman` binary. Override when `podman` is not on `PATH` — for example, `/usr/local/bin/podman`. | -| `PODMAN_HOST` | *(unset)* | Podman host socket or TCP address (sets `DOCKER_HOST` internally). Required on Windows to point Devsy at the WSL socket, e.g. `unix:///run/user/1000/podman/podman.sock`. | +| `PODMAN_HOST` | *(unset)* | Podman host socket or TCP address (sets `DOCKER_HOST` internally). Required on Windows to point Devsy at the WSL socket, e.g. `unix:///run/user//podman/podman.sock` (replace `` with `id -u`). | | `INACTIVITY_TIMEOUT` | *(unset)* | Stops the container after the specified idle period. Accepts duration strings such as `10m` or `1h`. | Set options after adding the provider using `--option` flags: @@ -136,7 +136,7 @@ Start a workspace using the Podman provider by passing `--provider podman` to `d devsy up --provider podman --id my-workspace https://github.com/my-org/my-repo ``` -Devsy builds the workspace image with Buildah (Podman's built-in build tool) and starts the container. When the workspace is ready, connect to it: +Devsy builds the workspace image using `podman build` and starts the container. When the workspace is ready, connect to it: ```bash devsy ssh my-workspace @@ -168,7 +168,7 @@ ls -la $XDG_RUNTIME_DIR/podman/podman.sock If the socket path differs from the default, set `PODMAN_HOST` to the correct path: ```bash -devsy provider set-options podman --option PODMAN_HOST=unix:///run/user/1000/podman/podman.sock +devsy provider set-options podman --option PODMAN_HOST=unix:///run/user/$(id -u)/podman/podman.sock ``` ### Dockerfile features not supported during image build From 910686fa24c313bbdd39430467973cad66db688b Mon Sep 17 00:00:00 2001 From: Samuel K Date: Thu, 14 May 2026 07:34:42 -0500 Subject: [PATCH 4/5] docs: add Podman troubleshooting section to Linux guide --- .../troubleshooting/linux-troubleshooting.mdx | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/docs/pages/troubleshooting/linux-troubleshooting.mdx b/docs/pages/troubleshooting/linux-troubleshooting.mdx index ee56215b5..eb575e455 100644 --- a/docs/pages/troubleshooting/linux-troubleshooting.mdx +++ b/docs/pages/troubleshooting/linux-troubleshooting.mdx @@ -64,3 +64,51 @@ append `:Z` to your volume definitions, like so There is a [known issue](https://github.com/devsy-org/devsy/issues/1045) where some linux distros use a large PATH to find SSH and causes the connection string to be too long. The workaround is to specify the SSH binary explicitly in vscode. + +## Podman + +### Rootless socket path + +Rootless Podman places its socket at `$XDG_RUNTIME_DIR/podman/podman.sock`. If Devsy cannot connect, `PODMAN_HOST` is likely unset. Set it explicitly: + +```bash +devsy provider set-options podman --option PODMAN_HOST=unix:///run/user/$(id -u)/podman/podman.sock +``` + +On macOS and Windows, also verify the Podman machine is running: + +```bash +podman machine start +``` + +### `podman compose` vs `docker-compose` + +Podman v4+ ships `podman compose` as a built-in subcommand. If your `devcontainer.json` or workspace scripts call `docker-compose` directly, they will fail. Update references to `podman compose`, or add a shell alias as a stopgap: + +```bash +alias docker-compose='podman compose' +``` + +`devsy up` handles this automatically — Devsy's compose helper detects Podman via the `ContainerRuntime` interface. The alias is only needed for scripts that run inside the workspace itself. + +### BuildKit not available + +Podman uses buildah internally for `podman build`. Dockerfiles with the `# syntax=docker/dockerfile:1` pragma or BuildKit-specific `RUN --mount` syntax will fail. Remove the syntax pragma and restructure affected `RUN` steps to avoid BuildKit mounts. Most standard Dockerfiles build without changes. + +### Volume mount permissions in rootless mode + +Rootless Podman maps UIDs through user namespaces. Files created inside the container appear owned by `nobody` on the host. + +**With SELinux**: append `:Z` to volume mounts (see [Using SELinux](#using-selinux) above). + +**Without SELinux**: fix ownership with `podman unshare`: + +```bash +podman unshare chown -R $(id -u):$(id -g) /path/to/volume +``` + +If rootless UID mapping is too restrictive, reinitialize with a rootful machine: + +```bash +podman machine init --rootful +``` From b69d104f68cd4fbe8b40c39409468166532d8075 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Thu, 14 May 2026 07:38:46 -0500 Subject: [PATCH 5/5] docs: fix review findings in Podman troubleshooting section - Replace podman machine init --rootful with sudo podman (Linux page) - Demote heading levels to match existing ### hierarchy - Remove macOS/Windows guidance from Linux troubleshooting page --- .../troubleshooting/linux-troubleshooting.mdx | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/docs/pages/troubleshooting/linux-troubleshooting.mdx b/docs/pages/troubleshooting/linux-troubleshooting.mdx index eb575e455..826b29c24 100644 --- a/docs/pages/troubleshooting/linux-troubleshooting.mdx +++ b/docs/pages/troubleshooting/linux-troubleshooting.mdx @@ -65,9 +65,9 @@ append `:Z` to your volume definitions, like so There is a [known issue](https://github.com/devsy-org/devsy/issues/1045) where some linux distros use a large PATH to find SSH and causes the connection string to be too long. The workaround is to specify the SSH binary explicitly in vscode. -## Podman +### Podman -### Rootless socket path +#### Rootless socket path Rootless Podman places its socket at `$XDG_RUNTIME_DIR/podman/podman.sock`. If Devsy cannot connect, `PODMAN_HOST` is likely unset. Set it explicitly: @@ -75,13 +75,7 @@ Rootless Podman places its socket at `$XDG_RUNTIME_DIR/podman/podman.sock`. If D devsy provider set-options podman --option PODMAN_HOST=unix:///run/user/$(id -u)/podman/podman.sock ``` -On macOS and Windows, also verify the Podman machine is running: - -```bash -podman machine start -``` - -### `podman compose` vs `docker-compose` +#### `podman compose` vs `docker-compose` Podman v4+ ships `podman compose` as a built-in subcommand. If your `devcontainer.json` or workspace scripts call `docker-compose` directly, they will fail. Update references to `podman compose`, or add a shell alias as a stopgap: @@ -91,11 +85,11 @@ alias docker-compose='podman compose' `devsy up` handles this automatically — Devsy's compose helper detects Podman via the `ContainerRuntime` interface. The alias is only needed for scripts that run inside the workspace itself. -### BuildKit not available +#### BuildKit not available Podman uses buildah internally for `podman build`. Dockerfiles with the `# syntax=docker/dockerfile:1` pragma or BuildKit-specific `RUN --mount` syntax will fail. Remove the syntax pragma and restructure affected `RUN` steps to avoid BuildKit mounts. Most standard Dockerfiles build without changes. -### Volume mount permissions in rootless mode +#### Volume mount permissions in rootless mode Rootless Podman maps UIDs through user namespaces. Files created inside the container appear owned by `nobody` on the host. @@ -107,8 +101,4 @@ Rootless Podman maps UIDs through user namespaces. Files created inside the cont podman unshare chown -R $(id -u):$(id -g) /path/to/volume ``` -If rootless UID mapping is too restrictive, reinitialize with a rootful machine: - -```bash -podman machine init --rootful -``` +If rootless UID mapping is too restrictive for your workflow, run the container as root using `sudo podman` instead.