Help us improve
Share bugs, ideas, or general feedback.
From skipper
Containerized development using skipper — build, test, lint, and run commands inside Docker/Podman containers with consistent toolchains. Use this skill whenever the user mentions skipper, skipper.yaml, or wants to run make targets, build images, run tests, or execute commands inside a containerized dev environment. Also use when troubleshooting container build failures, skipper configuration, or setting up a reproducible development workflow in a git repository.
npx claudepluginhub redhat-community-ai-tools/claude-plugins --plugin skipperHow this skill is triggered — by the user, by Claude, or both
Slash command
/skipper:skipper-dev-workflowThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
[Skipper](https://github.com/Stratoscale/skipper) is a CLI tool that lets you build and test your project in an isolated container environment. Instead of installing compilers, linters, and test tools on your host, you define them in a Dockerfile and skipper runs everything inside that container. This guarantees every developer on the team uses the exact same toolchain.
Guides Docker usage: debugging container failures, writing Dockerfiles, docker-compose for integration tests, image optimization, volumes, multi-stage builds, and deployments.
Develops secure Docker containers with multi-stage builds, non-root users, minimal Alpine/slim images, Skaffold workflows, and 12-factor principles. For Dockerfiles, container security, and orchestration.
Creates devcontainers with language-specific tooling (Python/Node/Rust/Go) and persistent volumes. Use when adding devcontainer support to a project or setting up isolated development environments.
Share bugs, ideas, or general feedback.
Skipper is a CLI tool that lets you build and test your project in an isolated container environment. Instead of installing compilers, linters, and test tools on your host, you define them in a Dockerfile and skipper runs everything inside that container. This guarantees every developer on the team uses the exact same toolchain.
Skipper works with both Docker and Podman as container runtimes.
Install skipper from PyPI:
pip install strato-skipper
Some IDEs (Cursor, VS Code, etc.) bundle their own Python which can interfere with venv creation. If you hit issues, create the venv with the system Python using a clean environment:
env -i HOME=$HOME PATH=/usr/bin:/usr/sbin:/bin:/sbin /usr/bin/python3 -m venv .venv
source .venv/bin/activate
pip install 'setuptools<81' strato-skipper
The setuptools<81 cap is needed because skipper depends on pkg_resources, which was removed in setuptools 82+.
Enable bash completion:
echo 'source <(skipper completion)' >> ~/.bashrc
Skipper infers images from Dockerfiles in the repo root. For Dockerfile.myservice:
skipper build myservice # Build specific image
skipper build # Build all detected images
skipper build myservice --container-context /path/to/context
All images are automatically tagged with the current commit ID.
Run makefile targets inside the build container — the most common skipper workflow:
skipper make <target>
skipper make test
skipper make lint
skipper make build
Use a non-standard makefile:
skipper make -f Makefile.arm32 tests
skipper run gcc myprog.c -o myprog
skipper run go test ./...
skipper shell
skipper --registry some-registry push myservice
skipper images # List local images
skipper --registry some-registry images -r # Include remote
skipper rmi myservice <tag> # Delete local image
skipper.yamlPlace skipper.yaml at the repo root to avoid repeating CLI flags. Once configured, commands simplify to just skipper make test.
registry: some-registry
build-container-image: development
build-container-tag: latest
# Use git revision as tag — same build container unless Dockerfile changes
# build-container-tag: 'git:revision'
# Build arguments
build-arg:
- VAR1=value1
- VAR2=value2
# Additional build contexts
build-context:
- context1=/path/to/dir
- alpine=docker-image://alpine:3.15
# Custom makefile
make:
makefile: Makefile.custom
# Container definitions (if Dockerfiles aren't at repo root)
containers:
service1: path/to/service1/dockerfile
service2: path/to/service2/dockerfile
# Environment variables
env:
MY_VAR: value
EXTERNAL_PORT: $EXTERNAL_PORT # Shell variable substitution
LITERAL: $$NOT_INTERPOLATED # Double dollar for literal $
# Environment files
env_file:
- /path/to/env_file1.env
- /path/to/env_file2.env
# Volume mounts
volumes:
- /tmp:/tmp:rw
- ${HOME}/.netrc:/root/.netrc
- ${HOME}/.gocache:/tmp/.gocache
# Override working directory (default: project directory)
workdir: /path/to/workdir
Skipper evaluates shell commands in the config using $(command) notation:
env:
VAR: $(expr ${MY_NUMBER:-5} + 5)
volumes:
- $(which myprogram):/myprogram
Pass env vars at runtime with -e:
skipper make -e MY_VAR=value tests
skipper run -e DEBUG=1 ./myapp
Or define them in skipper.yaml under env: or via env_file:.
On Linux, skipper uses host networking by default (no port mapping needed). On macOS/Windows or with custom networks, publish ports with -p:
skipper make -p 8080:8080 serve
skipper run -p 3000:3000 -p 5432:5432 ./myapp
When running skipper on Linux without sudo, skipper creates a dedicated user inside the container with root and docker groups. On Debian-based distros, PATH may get reset. To work around this, install sudo in the build container, disable env_reset in /etc/sudoers, and set:
export SKIPPER_USE_SUDO="true"
Or in skipper.yaml:
env:
SKIPPER_USE_SUDO: "true"
Skipper sets CONTAINER_RUNTIME_COMMAND inside the container (either podman or docker) so scripts can detect the runtime.
skipper: command not foundSkipper isn't installed or the venv isn't activated. Run pip install strato-skipper or source .venv/bin/activate.
pkg_resources / ModuleNotFoundErrorYou have setuptools 82+ installed. Reinstall with the version cap:
pip install 'setuptools<81' strato-skipper
Common causes:
docker system prune or podman system pruneskipper build --no-cache <image>For rootless podman, ensure XDG_RUNTIME_DIR is set and the podman socket is running:
systemctl --user status podman.socket
Check that the container runtime is responsive: docker ps or podman ps. Large builds or test suites can take several minutes — this is normal.
If you see encoding errors, set your locale:
export LC_ALL="en_US.UTF-8"
export LANG="en_US.UTF-8"