Project Zenith is an automated deployment script designed to bring a fully functional, rootless Linux container environment to restricted Linux workstations (specifically tailored for 42 School environments using goinfre storage).
By combining Rootless Podman with Distrobox, Project Zenith allows unprivileged users to create isolated development environments where they possess "root" access, install system packages (via apt, pacman, dnf), and seamlessly integrate with the host's home directory and hardware devices.
When you run Project Zenith, it bypasses the need for system-level package managers (like apt) which require administrator privileges.
- Dynamic Pathing: It detects your actual unprivileged user ID and dynamically maps out your personal
goinfrestorage (a large, temporary storage drive often used in 42 environments). - Binary Fetching: It downloads pre-compiled, static binaries for Podman and its core dependencies directly from their official GitHub releases.
- Configuration Injection: It builds a custom Podman configuration tree in your
~/.config/containersdirectory, instructing Podman to store all heavy container images and runtimes insidegoinfrerather than your limited home directory quota. - Distrobox Wrapping: Finally, it installs Distrobox, a wrapper around Podman that seamlessly mounts your home directory, USB devices, and audio/video sockets into the container, making the container feel like a native application on the host.
Run the script anytime using:
./Project_Zenith.sh- 1) Fresh Install: Downloads and configures Podman, crun, conmon, networking, and Distrobox into
goinfre/bin. - 2) Create Container: Interactive container creator that prompts for container name and base image (Ubuntu, Debian, Arch, Fedora, or custom), ensuring homes and volumes are mapped to
goinfre. - 3) Storage Manager: Visualizes disk usage for
goinfreandcontainers/storage, with options to run safe cache prune, aggressive image cleanup, lock clearing, or deleting individual container homes. - 4) Check for Updates: Checks GitHub for a newer version of Project Zenith and safely updates and restarts the script in-place.
- 5) Repair Setup: Fully resets and wipes container configurations and binaries to reinstall cleanly.
Project Zenith is implemented as a pure Bash script (#!/usr/bin/env bash) strictly utilizing POSIX-compliant tools (curl, tar, find, readlink) to ensure execution on heavily locked-down host machines.
- Podman (Engine): The daemonless container engine.
- crun (Runtime): A fast, lightweight OCI container runtime written in C.
- conmon (Monitor): A utility used to monitor the container runtime, handle logging, and serve as the parent process for the container.
- Netavark & Aardvark-dns (Networking): Rust-based network stack tools for Podman to handle IP allocations, container-to-container networking, and DNS resolution without requiring root firewall rules.
Restricted accounts usually have strict quotas on $HOME. The script explicitly handles this in two ways:
- Engine Storage: Generates a
storage.confto redirect the heavy lifting of container layers:
graphroot = "/goinfre/username/containers/storage"
runroot = "/run/user/<UID>"- Container Home Directory: When you create a container, Project Zenith's setup command explicitly maps your container's internal home directory into
goinfreusing the--homeflag (e.g.,--home /goinfre/username/homes/my-box).- Why this matters: By default, Distrobox tightly mounts your actual host
~into the container. If you were to runnpm install, compile large binaries, or cache large files inside the container, it would immediately eat into your restricted host quota. By mapping the container's home togoinfre/homes/, you get unlimited space for your development tools while keeping your actual host profile clean.
- Why this matters: By default, Distrobox tightly mounts your actual host
The core magic of Project Zenith is giving you root inside the container when you are a standard user on the host. This is achieved through User Namespaces (user_namespaces(7)).
When Podman starts a container, it leverages the Linux kernel's user namespace feature. It creates a mapping between the User IDs (UIDs) inside the container and the UIDs on the host machine.
- Inside the container: You are
root(UID 0). - Outside the container: The kernel translates UID 0 to your unprivileged host UID (e.g., UID 1000 or 50000).
When you run apt install inside the container, the files written to the disk appear to be owned by root from the container's perspective. However, if an administrator checks the host filesystem, those exact same files are owned by your standard user account.
In a standard Docker/Podman setup, the container uses OverlayFS, a filesystem that efficiently layers files. However, OverlayFS historically required root privileges to mount. Because Project Zenith operates in a fully unprivileged environment (often without /etc/subuid or /etc/subgid delegations that Podman usually relies on), the script forces the vfs (Virtual File System) storage driver.
Furthermore, to maintain the "false root" illusion when a package tries to change file ownership (chown) during an installation, the script uses:
ignore_chown_errors = "true"Without this, package managers like apt would crash because the host kernel would deny an unprivileged user the right to assign file ownership to arbitrary other users.
Because Project Zenith relies entirely on unprivileged execution and the vfs driver, it comes with unavoidable technical tradeoffs:
Unlike OverlayFS, which shares identical files between containers using Copy-on-Write (CoW), the vfs driver physically copies the entire filesystem every time a new container or layer is created.
- Impact: If you download a 1GB Ubuntu image and create three Distroboxes from it, it will consume 4GB of disk space (1GB for the base image + 3GB for the identical container clones). This is why routing to
goinfreis mandatory.
Because you are not root on the host, Podman cannot bind to privileged network ports (ports under 1024).
- Impact: You cannot run a web server inside your container on port 80 or 443. You must configure your development servers to run on high ports (e.g.,
8080,3000). - Impact:
ping(ICMP traffic) may fail inside the container depending on how the host kernel'snet.ipv4.ping_group_rangeis configured.
The vfs driver has significantly higher disk I/O overhead compared to native filesystems or OverlayFS. Heavy disk operations (like compiling massive C++ codebases or running npm install for huge projects) will be noticeably slower than running directly on the host.
While Distrobox does an excellent job passing through USB controllers, you cannot easily run systemd inside these rootless containers. Background services (like sshd, nginx, or postgresql daemons) must usually be started manually in the foreground rather than relying on systemctl.