You cloned the repository but the build fails immediately
You pulled the containers/podman repository, ran the first make command, and the terminal immediately complained about missing Go modules or a broken linter. You expected a straightforward go build like any other project. Instead, you are staring at a wall of dependency resolution errors and a build system that refuses to compile until you run a specific initialization step. This is normal. The container ecosystem does not follow standard Go project conventions. The build pipeline expects a specific toolchain layout, and Fedora's packaging rules enforce strict validation before any binary ships. Run the initialization target before you touch the source code.
What is actually happening
The Podman project uses a hybrid build system. It relies on make to orchestrate Go compilation, but it also manages a separate set of development tools for linting, formatting, and cross-compilation. When you clone the repository, you get the source code. You do not get the toolchain. The make install.tools target downloads and compiles a pinned set of utilities into a local bin/ directory. This isolates your development environment from your system packages. It prevents version drift between your host Go installation and the project's expected toolchain.
Fedora maintains this separation to ensure that every contributor builds against the exact same linter versions and code generators. The make binaries step then compiles the actual podman and podman-remote executables. Finally, make validatepr runs the continuous integration checks locally. It catches formatting violations and test failures before you push to GitHub. The title references Docker because many developers arrive from that ecosystem, but Fedora ships Podman as the default container engine. The upstream repository is containers/podman, and the development workflow targets that codebase exclusively. Trust the package manager for runtime usage. Build from source only when you intend to modify the engine.
The setup procedure
Here is how to prepare a working development environment on Fedora. Open your terminal and navigate to your preferred workspace directory.
# Clone the upstream repository. The containers organization hosts the official source.
git clone https://github.com/containers/podman.git
cd podman
# Fetch the exact Go dependencies declared in go.mod. This prevents version mismatches.
go mod download
# Download and compile the project's internal toolchain into ./bin/.
# This isolates linters and code generators from your system packages.
make install.tools
# Compile the podman and podman-remote binaries into the local bin/ directory.
# The build system uses CGO for certain platform-specific features.
make binaries
# Run the pre-commit validation suite locally.
# This checks formatting, linting, and basic test coverage before you open a PR.
make validatepr
The make install.tools command takes the longest. It compiles several Go packages from scratch. You will see output scrolling through your terminal as it builds golangci-lint, go-bindata, and other utilities. Do not interrupt it. The build system caches compiled tools in bin/, so subsequent runs finish in seconds. Fedora developers often work inside a containerized development environment to avoid polluting the host system. You can run the same commands inside a fedora:latest container with podman run -it --rm -v $(pwd):/src -w /src fedora:latest bash. This keeps your host filesystem clean and matches the CI environment exactly. Run dnf upgrade --refresh weekly to keep your host toolchain current. It prevents stale metadata from breaking dependency resolution.
Verify the build
Run the newly compiled binary to confirm it links correctly and reports the expected version string.
# Execute the locally built binary instead of the system package.
# The ./bin/ path takes precedence in this shell session.
./bin/podman --version
# Run a quick smoke test to verify the runtime can talk to the socket.
# This confirms the binary can initialize the container engine.
./bin/podman info
If ./bin/podman --version prints a version string matching the repository tag, the compilation succeeded. The podman info command checks your runtime configuration, storage driver, and security settings. A clean output means the binary is ready for development. Always check systemctl status --user podman before restarting services. It shows recent log lines and current state in one view. Reboot before you debug. Half the time the symptom is gone.
Common pitfalls and what the error looks like
The most frequent failure happens during make install.tools. The build system expects Go 1.21 or newer. If your host runs an older version, the compiler aborts with go: downloading golang.org/x/tools@v0.20.0: module requires go >= 1.21. Fedora Workstation ships with a recent Go version in the go package. Install it with sudo dnf install go before cloning the repository.
Another common issue involves missing C libraries. The build system uses CGO for platform-specific features like cgroup management and network namespaces. If you see # cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in $PATH, your development tools are incomplete. Run sudo dnf groupinstall "Development Tools" to install gcc, make, and pkg-config. The container build pipeline requires these standard C utilities to compile Go packages that interface with the Linux kernel.
SELinux denials occasionally block the local runtime during testing. If podman info returns Error: cannot connect to Podman: request canceled while waiting for connection, check your journal for security context mismatches. Run journalctl -xeu podman to inspect the actual failure. Fedora enforces strict MAC policies by default. The development workflow expects you to run podman commands as your regular user. Rootless containers are the standard. Do not run sudo podman during development unless you are specifically debugging root-level storage drivers. Config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/. Trust the package manager. Manual file edits drift, snapshots stay.
When to use this workflow
Use this local build workflow when you are contributing patches to the upstream Podman project. Use make validatepr when you need to verify that your changes pass the CI checks before opening a pull request. Use make binaries when you want to test a specific commit without rebuilding the entire toolchain. Use podman build when you are creating container images for your own applications. Use buildah when you need to construct OCI images without a running daemon. Stay on the packaged podman version from dnf when you only need to run containers and do not intend to modify the engine source code.