This guide is for AI coding assistants (for example Claude, ChatGPT, Copilot). Use it for context on codebase layout, development patterns, testing, pitfalls, and upstream expectations when helping contributors to containers/podman—people writing patches, tests, and in-tree docs, triaging or fixing issues, and preparing pull requests.
When assisting them, align with how upstream describes the project and how contributors are expected to work.
- Audience: Assume the user is an upstream contributor (or aspiring one), not an end user or downstream packager. Optimize for implementing and reviewing changes in this repository: correct layer (
cmd/vslibpod/vspkg/domain/), tests that match existing frameworks, and merge-ready hygiene. Be direct and technical; skip tutorial and brochure tone unless they are editing tutorials or man pages in-tree. - Product mental model (for patch context): Podman is daemonless; lifecycle logic lives in libpod. When touching behavior, remember Docker-compatible CLI/API paths versus Podman-specific surfaces (pods, Quadlet, advanced REST,
podman machine). Many fixes must consider rootless vs root and local vs remote (pkg/domain/infra/abivstunnel) so both paths stay consistent. - Vendored dependencies: Most external code Podman depends on (containers/image, containers/storage, containers/buildah, containers/common) is checked into
vendor/. Never edit vendored files directly—usego getthenmake vendor. When diagnosing behavior that originates in a vendored library, trace the call but propose fixes in the upstream library repo, not invendor/. - Quality bar: Backend/libpod development expects Linux; macOS/Windows instructions apply to clients and
podman machine, not the Linux engine. Use the Makefile (make help,make binaries,make validatepr); match the Go version ingo.mod. Security issues use the private process linked from CONTRIBUTING, not public GitHub. AI-assisted contributions must follow LLM_POLICY.md. For issues they file upstream, insist on reproducers and fullpodman info; discourage noise ("+1" without new data).
Podman is a daemonless container engine with Docker-compatible CLI, rootless support, native pod management, and systemd integration via Quadlet.
# Build and test
make binaries # Build all binaries
make validatepr # Format, lint, and validate (required for PRs)
make localintegration # Run integration tests
make localsystem # Run system tests
# Development tools
make install.tools # Install linters and dev toolspodman/
├── cmd/podman/ # CLI commands (Cobra framework)
├── cmd/quadlet/ # Quadlet systemd unit generator
├── libpod/ # Core container/pod management (Linux only)
├── pkg/
│ ├── api/ # REST API server
│ ├── bindings/ # HTTP client (stable API)
│ ├── domain/ # Business logic layer
│ │ ├── entities/ # Interfaces and data structures
│ │ ├── infra/abi/ # Local implementation
│ │ └── infra/tunnel/ # Remote implementation
│ └── specgen/ # Container/pod specifications
├── test/e2e/ # Integration tests (Ginkgo)
├── test/system/ # System tests (BATS)
├── docs/source/markdown/ # Man pages
└── vendor/ # Vendored dependencies (DO NOT EDIT)
// cmd/podman/command.go
var commandCmd = &cobra.Command{
Use: "command [options] args",
RunE: commandRun,
}
func commandRun(cmd *cobra.Command, args []string) error {
return registry.ContainerEngine().Command(registry.GetContext(), options)
}// pkg/domain/infra/abi/command.go (local)
func (ic *ContainerEngine) Command(ctx context.Context, options entities.CommandOptions) error {
return ic.Libpod.Command(options) // Direct libpod call
}
// pkg/domain/infra/tunnel/command.go (remote)
func (ic *ContainerEngine) Command(ctx context.Context, options entities.CommandOptions) error {
return bindings.Command(ic.ClientCtx, options) // HTTP API call
}Integration Tests (Ginkgo)
Integration Tests (test/e2e/): Test Podman CLI commands end-to-end, using actual binaries and real containers. Use for testing user-facing functionality and CLI behavior.
It("should work correctly", func() {
session := podmanTest.Podman([]string{"command", "args"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
})System Tests (BATS)
System Tests (test/system/): Test Podman in realistic environments with shell scripts. Use for testing complex scenarios, multi-command workflows, and system integration.
@test "podman command functionality" {
run_podman command --option value
is "$output" "expected output" "description"
}Official Documentation: CONTRIBUTING.md
- Formatter:
gofumpt(viagolangci-lint, configured in.golangci.yml) - Validation: All PRs must pass
make validatepr - Commits: Must be signed (
git commit -s) and follow DCO - Reviews: Two approvals required for merge
- aardvark-dns: Container DNS server
- Cobra: CLI framework used for cmd/podman commands
- containers/buildah: Image building
- containers/container-libs: Shared utilities
- crun: Fast, low-memory container runtime
- Go: Programming language
- gorilla/mux: HTTP router and URL matcher for REST API
- gorilla/schema: Form data to struct conversion
- netavark: Network management
- runc: OCI-compliant container runtime
- Platform awareness - Consider Linux/Windows/macOS differences
- Rootless vs root - Many behaviors differ between modes
- Remote vs local - Different code paths (
abivstunnel) - Test cleanup - Always clean up test artifacts
# Analysis
go list -tags "$BUILDTAGS" -f '{{.Deps}}' ./cmd/podman # Dependencies
grep -r "pattern" --include="*.go" . # Find patterns
# Testing
make localintegration FOCUS_FILE=your_test.go # Single test file
make localintegration FOCUS="test description" # Single test
PODMAN_TEST_SKIP_CLEANUP=1 make localintegration # Debug mode
# Validation
make validatepr # Full validation
make lint # Linting only- CONTRIBUTING.md: Development guidelines
- DISTRO_PACKAGE.md: Packaging guidelines for distributors
- docs/CODE_STRUCTURE.md: Detailed codebase structure
- docs/tutorials/: Step-by-step guides and tutorials
- GOVERNANCE.md: Project organization and contributor roles
- LICENSE: Apache 2.0 license terms
- README.md: Project overview
- RELEASE_PROCESS.md: Release workflow (maintainers only)
- rootless.md: Rootless limitations and troubleshooting
- test/README.md: Testing framework details
For comprehensive information, refer to the official documentation and recent commits in the Podman repository.
