The scenario
You just switched to Fedora Silverblue. The system boots fast, updates atomically, and completely refuses to break from a bad package install. You open a terminal and try to install a C++ compiler, a Python package manager, or a specific Node.js runtime your project requires. The terminal rejects you. The host filesystem is read-only by design. You are staring at a permission denied error, wondering how developers actually build software on an immutable desktop. The answer is not to fight the immutability. The answer is to use a toolbox container.
What toolbox actually does
Silverblue treats the host system like a museum exhibit. You can look at it, run the applications it ships with, and enjoy the stability. You cannot rearrange the furniture. Toolbox solves this by giving you a separate, fully writable Fedora environment that runs alongside your host. It uses Podman under the hood to spin up a container that shares your user account, your home directory, and your network configuration. The container gets its own package database and its own /usr/bin. When you run dnf install inside the container, it only modifies the container filesystem. Your host stays pristine.
Think of it like a dedicated workshop attached to a clean office. The office holds the official documentation and the company laptop. The workshop holds the saws, the drills, and the sawdust. You walk between them through a single door. Your files stay in the same place, but the tools you use depend on which room you are standing in.
The container shares your $HOME directory via a bind mount. This means your source code, your dotfiles, and your project directories are immediately visible inside the container. The container does not copy your files. It sees them directly. This design keeps your workflow simple. You do not need to sync files between environments. You do not need to configure complex volume mappings. You just open your editor and start coding.
Convention aside: config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/. This rule applies equally to the host and the toolbox container. If you modify a system configuration file inside the container, it only affects that container. The host configuration remains untouched.
Run toolbox create before you start a new project. Do not wait until you hit a missing dependency error.
Setting up your development container
The toolbox command is a thin wrapper around Podman. It handles image selection, volume mounting, and environment variables automatically. You do not need to write a Dockerfile. You do not need to map ports manually. Run the creation command from your host terminal.
toolbox create --distro fedora --release 40 my-dev-env
# --distro and --release pin the container to a specific Fedora version.
# This prevents automatic upgrades from breaking your build tools.
# The name my-dev-env becomes the container identifier for all future commands.
The command pulls the base image from the Fedora registry. It mounts your home directory into the container so your source code and configuration files are immediately available. It copies your current shell profile and environment variables into the container image. Once the pull finishes, enter the environment.
toolbox enter my-dev-env
# This drops you into a bash shell inside the container.
# Your prompt changes to reflect the container context.
# All subsequent commands run in the writable filesystem.
Inside the container, you have full root access for package management. Install whatever compilers, runtimes, or CLI tools your project requires.
sudo dnf install gcc make cmake python3-pip
# sudo works inside the container because your user is added to the wheel group automatically.
# The package manager writes to the container rootfs, leaving the host untouched.
# Dependencies resolve against the container's own repository metadata.
Convention aside: always run dnf upgrade --refresh inside the container after a few weeks. The container does not automatically sync with the host update cycle. Keeping the container metadata fresh prevents dependency resolution failures when you add new packages later.
Reboot before you debug. Half the time the symptom is gone.
Verifying the environment
You need to confirm that the container is actually isolated and that your host remains unchanged. Run a quick check from inside the container to see where package binaries land.
which gcc
# Returns /usr/bin/gcc inside the container.
# This path exists only in the container overlay filesystem.
# The host does not have this binary unless you installed it separately.
Exit the container and check the host.
exit
which gcc
# Returns nothing or points to a different version if you installed it on the host.
# The host package database remains completely independent.
# This confirms the isolation boundary is working as intended.
Run toolbox list to see all active containers. The output shows the name, the base image, and the creation date. Keep this list short. Each container consumes disk space for its layer cache and package database. Delete abandoned environments with toolbox rm <name> to reclaim storage.
Verify it worked by checking the container state. Run podman ps on the host to see the underlying process. If the container shows up as running, your development environment is active and ready.
Trust the package manager. Manual file edits drift, snapshots stay.
Common pitfalls and error messages
The most frequent issue is trying to run system services inside the toolbox. Containers lack a full init system. You cannot start systemd services, manage hardware directly, or load kernel modules from inside the container. If you try to run sudo systemctl start postgresql, you will see a failure message.
Failed to connect to bus: No such file or directory
The container does not have access to the host D-Bus socket. Database servers and background daemons must run on the host, or you must use a dedicated service container with proper socket mapping. Keep toolbox strictly for CLI development tools, compilers, and language runtimes.
Another common error occurs when the container image drifts too far from the host kernel. If you pin a container to Fedora 38 and upgrade your host to Fedora 41, the container will still work. The kernel is shared. However, glibc version mismatches can cause subtle linking errors in compiled binaries. Stick to a container release that matches your host release, or at most one version behind.
If toolbox enter hangs or drops you into a broken shell, the container filesystem might be corrupted. Check the logs with podman logs my-dev-env. Look for overlay mount failures. If the overlay driver complains about missing fuse support, enable it in your kernel parameters. Rebuild the container if the logs show filesystem corruption.
Convention aside: journalctl -xe reads better than journalctl alone. The x flag adds explanatory text and the e flag jumps to the end. Most sysadmins type journalctl -xeu <unit> muscle-memory style. Use it when debugging host-level container issues.
Run journalctl first. Read the actual error before guessing.
Choosing your container strategy
Use Toolbox when you need a quick, isolated CLI environment for compiling code or testing scripts without touching the host. Use Podman directly when you need to expose network ports, run background services, or build Docker images for deployment. Use Flatpak when you are installing graphical applications that need sandboxed access to your desktop session. Stay on the host system when you are configuring network interfaces, managing SELinux policies, or installing kernel modules.