Skip to content

Stop depending on ghcr.io/loft-sh images - #33

Merged
renatoathaydes merged 60 commits into
mainfrom
claude/drop-loft-sh-images
Oct 23, 2026
Merged

renatoathaydes merged 60 commits into
mainfrom
claude/drop-loft-sh-images

Conversation

@renatoathaydes

@renatoathaydes renatoathaydes commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

DevPod no longer pulls anything from ghcr.io/loft-sh at runtime or in its tests. (The dev container's image is replaced in #32.)

dockerless

Kubernetes workspaces build their dev container with dockerless: the pod starts from its image, and kaniko builds the Dockerfile straight into the pod's file system. It was ghcr.io/loft-sh/dockerless:0.2.0, built on loft-sh's patched copy of Google's kaniko 1.9.2, which is archived.

  • dockerless/ is imported from loft-sh/dockerless v0.2.0 with git subtree, keeping its history and authors (53 commits), with vendor/ filtered out of that history. It's MPL-2.0, like DevPod.
  • It's now built on the maintained osscontainertools/kaniko v1.28.6. loft-sh's only kaniko patch added Unpack, which always unpacks the final stage into the container; the fork has that upstream as Materialize.
  • It's a separate Go module (github.com/loft-sh/devpod/dockerless), so kaniko's dependencies stay out of the CLI and the agent, and isn't vendored. Its Dockerfile builds it from source with pinned base images. loft-sh's goreleaser, Justfile, workflows and dev container are dropped.
  • .github/workflows/dockerless.yaml builds, vets, lints (golangci-lint v2) and license-checks it, and builds the image for amd64 and arm64, on PRs that touch it; on a dockerless-v<version> tag it publishes ghcr.io/curityio/dockerless:<version>.
  • DevPod's default is ghcr.io/curityio/dockerless:0.3.0 (DOCKERLESS_IMAGE still overrides it). The e2e workflow builds the image from the checkout under that name and loads it into kind, so the kubernetes tests use the code under test.

Fixes from a review of dockerless

A review of dockerless/, limited to how DevPod uses it, found no regression from the kaniko change, and these problems, all inherited from loft-sh's v0.2.0 except the compression level:

  • USER forms: start --user only accepted a name or a uid with a passwd entry, so a Dockerfile ending in USER 1000:1000, or a base image whose user is an unknown uid, stopped the pod after the build. It now accepts every form docker does (unit tests in cmd/start_test.go).
  • Root from a workspace user: /.dockerless was world-writable and on PATH before busybox, and DevPod runs sh -c and su in the pod as root, so any user could plant an sh that root then ran. It is now 755 and off PATH; DevPod always calls dockerless by its full path.
  • TLS: --insecure defaulted to true, so every base-image pull and registry-cache request accepted any certificate (and plain HTTP), with the user's registry credentials. It now defaults to false; the kubernetes provider's new DOCKERLESS_INSECURE option passes --insecure for an in-cluster cache that needs it.
  • Disk: kaniko's copy of every changed file stayed in /.dockerless/layers, doubling the pod's ephemeral storage; the build now removes it (config.CleanupBuild).
  • image.json: written by renaming a complete file, and start --wait retries one it can't parse, instead of the pod dying on a half-written file.
  • Env: the started processes (feature entrypoints, DevPod's container daemon) now get the pod's variables, such as containerEnv, minus dockerless's own, as with docker.
  • Docker Hub lookups: without a registry cache, kaniko looked for cached layers in index.docker.io/library/local/cache; layer caching is now only on with a registry cache.
  • Compression level: the new kaniko ignores CompressionLevel without CompressionLevelSet (only affects cache pushes).

vcluster feature

The e2e compose features test and examples/simple used ghcr.io/loft-sh/devcontainer-features/vcluster. The test now installs gh 2.62.0 with the devcontainers github-cli feature and checks its version; the example drops it.

Before the next release

  • Push the dockerless-v0.3.0 tag after merging, so the image exists.
  • Make the dockerless package public in the curityio package settings; GHCR creates it private.

Both are in TODO.md.

Testing

  • go build, go vet and golangci-lint v2.15.0 (0 issues) for dockerless (GOOS=linux), go-licenses v2 check passes.
  • In the image: a Dockerfile with a RUN builds and unpacks (base files, the RUN output, the image config's env); a FROM-only Dockerfile still unpacks the base image (the case loft-sh's patch was for); dockerless start runs the entrypoint with the image's env.
  • After the review fixes, running the image as DevPod does (start --wait --user 1000:1000 as PID 1, then build through exec): the process ran as uid/gid 1000 with HOME=/, the pod's MY_VAR and the image's env and PATH; /.dockerless is 755, PATH has no /.dockerless, /.dockerless/layers was removed after a 50 MB RUN, and the build log has no Docker Hub cache lookup. --insecure still works.
  • With a CLI built from this branch on Docker Desktop's Kubernetes, before and after the fixes, the build kubernetes dockerless e2e testdata came up with the locally built ghcr.io/curityio/dockerless:0.3.0 and ssh returned test456; with DOCKERLESS_INSECURE=true the agent passed --insecure.
  • Root module: go build ./... and go test ./pkg/devcontainer/.... The e2e suites themselves (kind, compose features) run in CI.

🤖 Generated with Claude Code

FabianKramm and others added 30 commits August 29, 2023 10:36
Signed-off-by: Thomas Kosiewski <thomas.kosiewski@loft.sh>
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.3 to 1.7.5.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](containerd/containerd@v1.7.3...v1.7.5)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Thomas Kosiewski <thomas.kosiewski@loft.sh>
Signed-off-by: Thomas Kosiewski <thomas.kosiewski@loft.sh>
Signed-off-by: Thomas Kosiewski <thomas.kosiewski@loft.sh>
Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](docker/login-action@v2...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](docker/setup-qemu-action@v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.5 to 1.7.6.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](containerd/containerd@v1.7.5...v1.7.6)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
…etup-buildx-action-3

build(deps): bump docker/setup-buildx-action from 2 to 3
…ogin-action-3

build(deps): bump docker/login-action from 2 to 3
…etup-qemu-action-3

build(deps): bump docker/setup-qemu-action from 2 to 3
…checkout-4

build(deps): bump actions/checkout from 3 to 4
…ontainerd/containerd-1.7.6

build(deps): bump github.com/containerd/containerd from 1.7.5 to 1.7.6
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.14.0 to 0.17.0.
- [Commits](golang/net@v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.57.0 to 1.57.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](grpc/grpc-go@v1.57.0...v1.57.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…/net-0.17.0

build(deps): bump golang.org/x/net from 0.14.0 to 0.17.0
…g.org/grpc-1.57.1

build(deps): bump google.golang.org/grpc from 1.57.0 to 1.57.1
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.6 to 1.7.8.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](containerd/containerd@v1.7.6...v1.7.8)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
…ontainerd/containerd-1.7.8

build(deps): bump github.com/containerd/containerd from 1.7.6 to 1.7.8
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](spf13/cobra@v1.7.0...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Thomas Kosiewski and others added 28 commits December 7, 2023 11:25
…spf13/cobra-1.8.0

build(deps): bump github.com/spf13/cobra from 1.7.0 to 1.8.0
…containerd/containerd-1.7.10

build(deps): bump github.com/containerd/containerd from 1.7.8 to 1.7.10
…/sbom-action-0.15.0

build(deps): bump anchore/sbom-action from 0.14.3 to 0.15.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0.
- [Commits](golang/crypto@v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.10 to 1.7.11.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](containerd/containerd@v1.7.10...v1.7.11)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 23.0.5+incompatible to 23.0.8+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](moby/moby@v23.0.5...v23.0.8)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.15.0 to 0.15.1.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](anchore/sbom-action@v0.15.0...v0.15.1)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](actions/setup-go@v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Thomas Kosiewski <thomas.kosiewski@loft.sh>
The compose features test only needs some feature with a version to check,
so it installs gh 2.62.0 from the devcontainers github-cli feature.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The source of the image DevPod uses to build dev containers on Kubernetes
without a docker daemon, from https://github.com/loft-sh/dockerless at
v0.2.0 (2d0c0b5), with its history and with vendor/ removed from it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

git-subtree-dir: dockerless
git-subtree-mainline: 1eb513f
git-subtree-split: b104a11
Google's kaniko is archived, and dockerless used loft-sh's copy of its
1.9.2 with one patch, an Unpack option that always unpacks the final
stage's file system into the container. osscontainertools/kaniko is
maintained and has the same option upstream, Materialize.

dockerless becomes the github.com/loft-sh/devpod/dockerless module, without
vendor/, and its Dockerfile builds it from source with pinned base images.
loft-sh's release tooling (goreleaser, Justfile, its workflows and dev
container) is dropped; lint uses golangci-lint v2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DevPod's default dockerless image is now ghcr.io/curityio/dockerless:0.3.0,
published by a new workflow when a dockerless-v<version> tag is pushed; it
also checks dockerless on pull requests. The e2e tests build the image from
the checkout under that name and load it into kind, so the kubernetes tests
use the code under test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
All of these came with loft-sh's dockerless v0.2.0 except the ignored
compression level, which the new kaniko only applies with
CompressionLevelSet.

- start accepts every USER form docker does (uid without a passwd entry,
  user:group, uid:gid); it failed and stopped the pod.
- /.dockerless is no longer writable by everyone nor on PATH, where
  DevPod's root commands looked up sh and su.
- --insecure defaults to false, so registries' certificates are checked.
- The build removes kaniko's copy of the changed files, only caches
  layers when there is a registry cache (it looked them up on Docker
  Hub), and writes image.json by renaming a complete file; start retries
  a file it can't parse.
- start passes the variables the container was started with to its
  processes, minus dockerless's own, as docker does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dockerless now checks registries' certificates. The option passes
--insecure to it, for registry caches in the cluster that use plain HTTP
or a certificate that isn't trusted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The org.opencontainers.image.source label links the package to
curityio/devpod when it is first published, so it gets the repository's
access permissions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@renatoathaydes
renatoathaydes merged commit a46aedc into main Oct 23, 2026
19 checks passed
@renatoathaydes
renatoathaydes deleted the claude/drop-loft-sh-images branch October 23, 2026 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants