Docker containers solved the “it works on my machine” problem, but they introduced a new one: “it works on my machine with Docker installed.” Containers require the Docker daemon, containerd, or at minimum a container runtime. For distributing command-line tools, desktop applications, or deployment artifacts, this dependency is a burden. Dockerc takes a radically different approach – it compiles entire Docker images into standalone binary executables.
Written in Zig and available at github.com/NilsIrl/dockerc, Dockerc reads a Docker image’s layers and produces a single, self-contained binary that embeds the filesystem, entry point, and runtime configuration. When executed, the binary unpacks itself into an in-memory filesystem (via tmpfs), sets up the process namespace, and runs the application. No Docker, no containerd, no root privileges required.
This approach is particularly compelling for distributing CLI tools, automation scripts, and utility applications to environments where Docker is unavailable – CI runners, locked-down servers, air-gapped systems, or end-user machines. The resulting binary is portable across Linux systems with the same kernel architecture.
What is Dockerc?
Dockerc is a tool that compiles Docker container images into standalone, portable binary executables. It is written in Zig and produces statically linked binaries that embed the full container filesystem. The generated binary runs on any Linux system of the same architecture without requiring Docker, containerd, or any other container runtime.
How do you use Dockerc?
Usage follows a straightforward compile-and-run pattern:
# Compile a Docker image into a binary
dockerc --image alpine:latest --output myapp.bin
# Run the resulting binary (no Docker needed)
./myapp.bin
# Compile with arguments
dockerc --image nginx:alpine --output webserver.bin --entrypoint nginx
The compilation process extracts image layers, creates a squashfs filesystem, and embeds it in a minimal launcher binary written in Zig.
What architectures are supported?
Dockerc’s architecture support depends on both the tool’s compilation target and the source image’s platform.
| Host Architecture | Target Architecture | Status |
|---|---|---|
| x86_64 Linux | x86_64 containers | Full support |
| x86_64 Linux | ARM64 containers | Experimental (QEMU user mode) |
| ARM64 Linux | ARM64 containers | Full support |
| ARM64 Linux | x86_64 containers | Experimental |
| macOS | Linux containers | Cross-compilation only |
| Windows | Linux containers | Not supported |
The core limitation is Linux kernel syscall compatibility. The generated binary runs natively without emulation, so the binary’s architecture must match the host kernel.
What are Dockerc’s limitations?
While powerful, Dockerc has important constraints to understand.
| Aspect | Limitation | Mitigation |
|---|---|---|
| File size | Binary includes full container filesystem | Use slim/alpine base images |
| Startup time | Extracts filesystem to tmpfs on first run | Minimal with small images |
| Mount support | No volume mounting | Copy files in/out manually |
| Network | Inherits host network stack | Works with host firewall rules |
| GPU access | No direct GPU passthrough | Use host libraries |
| Persistent storage | In-memory only (tmpfs) | Explicit save/load mechanisms |
| Signal handling | Basic | Supported for main process |
For CLI tools, batch jobs, and stateless workloads, these limitations rarely matter. For stateful services or GPU applications, a traditional container setup is more appropriate.
Can you build Dockerc from source?
Yes. Dockerc is written in Zig, and building from source requires the Zig compiler:
# Clone the repository
git clone https://github.com/NilsIrl/dockerc.git
cd dockerc
# Build with Zig
zig build
# The binary is at ./zig-out/bin/dockerc
./zig-out/bin/dockerc --version
Pre-built binaries are also available from the GitHub Releases page for users who do not want to install the Zig toolchain.
Frequently Asked Questions
What is Dockerc?
Dockerc is a tool written in Zig that compiles Docker images into standalone, portable binary executables. These binaries run on any Linux system without Docker or any container runtime installed.
How do I use Dockerc?
Use dockerc --image <name> --output <file> to compile an image into a binary. The resulting binary is executed directly with ./<file>. The entrypoint and default command from the Docker image are preserved.
What architectures are supported?
x86_64 and ARM64 Linux hosts can compile and run binaries for their native architecture. Cross-architecture support (e.g., running ARM64 containers on x86_64) is experimental via QEMU user mode. macOS and Windows are not supported as runtime targets.
What are Dockerc’s limitations?
The generated binary includes the full container filesystem (larger file size), runs in-memory (no persistent storage by default), and does not support volume mounts or GPU passthrough. Best suited for CLI tools and stateless workloads.
Can I build Dockerc from source?
Yes. Clone the repository and run zig build. You need the Zig compiler installed. Pre-built binaries are also available from GitHub Releases.
Further Reading
- Dockerc GitHub Repository
- Zig Programming Language
- Docker Image Specification
- squashfs Filesystem Overview
- Portable Linux Binaries: A Practical Guide
flowchart LR
A[Docker Image] --> B[Extract Layers]
B --> C[Create squashfs]
C --> D[Embed in Launcher]
D --> E[Standalone Binary]
E --> F{Deploy To}
F --> G[No Docker Host]
F --> H[CI Runner]
F --> I[Air-gapped System]
F --> J[End User Machine]
G --> K[Execute Binary]
H --> K
I --> K
J --> K
K --> L[tmpfs Extraction]
L --> M[Run Application]graph TD
subgraph Binary Structure
A[Launcher Header] --> B[Zig Runtime]
A --> C[Embedded squashfs]
A --> D[Entry Point Config]
end
subgraph Execution Flow
B --> E[Create tmpfs]
E --> F[Extract squashfs]
F --> G[Setup Namespaces]
G --> H[Execute Entrypoint]
end
subgraph Benefits
H --> I[No Docker Daemon]
H --> J[No Root Required]
H --> K[Single File Distribution]
end
無程式碼也能輕鬆打造專業LINE官方帳號!一鍵導入模板,讓AI助你行銷加分!