A simple yet powerful container runtime written in Go, demonstrating Linux namespaces and container isolation.
Gocker is a lightweight container runtime that shows how Docker-like containers work under the hood. It uses Linux namespaces, chroot, and filesystem isolation to run processes in isolated environments.
- ๐๏ธ Image-based architecture - Pull and manage base images (Alpine Linux)
- ๐ Process isolation - PID namespace (every container sees itself as PID 1)
- ๐ Hostname isolation - UTS namespace (custom hostname per container)
- ๐ Filesystem isolation - Mount namespace + chroot
- ๐ Unique container IDs - Docker-style container identification
- ๐ Simple CLI - Easy-to-use Docker-inspired commands
- ๐ฆ Portable - All data stored in
~/.gocker(no hardcoded paths) - ๐ฏ OverlayFS support - Efficient layered filesystem (automatic detection)
- ๐ Network isolation - Network namespace for container networking
~/.gocker/
โโโ images/
โ โโโ alpine/
โ โโโ rootfs/ # Base Alpine Linux filesystem (shared)
โโโ containers/
โ โโโ <container-id-1>/
โ โ โโโ rootfs/ # Container 1's isolated filesystem
โ โโโ <container-id-2>/
โ โ โโโ ...
โ โโโ ...
โโโ metadata/
OverlayFS Mode (Recommended):
- Base image is mounted as read-only lower layer
- Container changes are written to the upper layer
- Fast container creation (no copying needed)
- Space-efficient (changes only stored once)
Fallback Mode:
- Full filesystem copy for each container
- Works on any Linux system
- More disk space usage but simpler
go build -o gocker# Download Alpine base image and set up directory structure
./gocker initThis will:
- Create
~/.gockerdirectory structure - Download Alpine Linux minirootfs (~3MB)
- Extract it to
~/.gocker/images/alpine/rootfs
# Run a shell
./gocker run alpine /bin/sh
# Run a command
./gocker run alpine /bin/ls -la /
# Check container hostname
./gocker run alpine /bin/hostname
# View processes (PID isolation)
./gocker run alpine /bin/ps aux
# Check OS version
./gocker run alpine /bin/cat /etc/os-releaseInitialize gocker environment by creating directory structure and downloading the Alpine base image.
./gocker initRun a command in a new container.
./gocker run alpine /bin/sh
./gocker run alpine /bin/ls -la /
./gocker run alpine /bin/ps aux
# Disable OverlayFS (use filesystem copy instead)
./gocker run --no-overlay alpine /bin/sh
# Disable network namespace isolation
./gocker run --no-network alpine /bin/shArguments:
image- Image name (currently onlyalpineis supported)command- Command to execute inside the containerargs...- Arguments for the command
Flags:
--no-overlay- Disable OverlayFS and use full filesystem copy--no-network- Disable network namespace isolation
- Creates
~/.gockerdirectory structure - Downloads Alpine Linux minirootfs from official CDN
- Extracts it to
~/.gocker/images/alpine/rootfs
- Verify image exists - Check if the base image is available
- Generate container ID - Create a unique 12-character identifier
- Setup filesystem:
- OverlayFS mode (default) - Mount overlay with base image as lower layer
- Fallback mode - Copy base image to container-specific directory
- Create namespaces - Fork process with isolated namespaces:
- PID namespace - Process isolation (container sees itself as PID 1)
- UTS namespace - Hostname isolation
- Mount namespace - Filesystem mount isolation
- User namespace - User/UID mapping (allows unprivileged containers)
- Network namespace - Network isolation (if enabled)
- Setup UID/GID mapping - Map container root (UID 0) to host user
- Setup environment:
chrootinto container filesystem- Mount
/procfilesystem - Set custom hostname
- Execute command - Run the requested command
- Cleanup - Unmount
/procand exit
| Namespace | Purpose | Example |
|---|---|---|
| PID | Process ID isolation | Container sees only its own processes (PID 1) |
| UTS | Hostname isolation | Container has its own hostname (gocker-container) |
| Mount | Filesystem mount isolation | Container has its own mount table |
| User | User/UID isolation | Maps container root (UID 0) to host user (unprivileged) |
| Network | Network isolation | Container has its own network stack (optional) |
// Paths in ~/.gocker/
type Paths struct {
Root string // ~/.gocker
Images string // ~/.gocker/images
Containers string // ~/.gocker/containers
Metadata string // ~/.gocker/metadata
}User runs: gocker run alpine /bin/sh
โ
1. Check if gocker initialized
โ
2. Verify alpine image exists
โ
3. Generate container ID (e.g., a8317726)
โ
4. Copy image rootfs โ container rootfs
(~/.gocker/images/alpine/rootfs โ ~/.gocker/containers/a8317726/rootfs)
โ
5. Create parent process with namespaces (PID, UTS, Mount, User)
โ
6. Setup UID/GID mapping (container UID 0 โ host UID)
โ
7. Fork child process (PID 1 in new namespace)
โ
8. Child: chroot + mount /proc + set hostname + exec /bin/sh
โ
9. User interacts with container
โ
10. Exit โ cleanup /proc โ done
syscall.Sethostname()- Set container hostnamesyscall.Chroot()- Change root directorysyscall.Chdir()- Change working directorysyscall.Mount()- Mount /proc filesystemsyscall.Unmount()- Unmount /proc on exitsyscall.CLONE_NEWUSER- Create new user namespace (enables unprivileged containers)syscall.CLONE_NEWPID- Create new PID namespacesyscall.CLONE_NEWUTS- Create new UTS namespacesyscall.CLONE_NEWNS- Create new mount namespace
gocker/
โโโ cmd/
โ โโโ root.go # Root cobra command
โ โโโ init.go # Initialize gocker
โ โโโ run.go # Run containers
โ โโโ child.go # Internal child process handler
โโโ internal/
โ โโโ paths/
โ โ โโโ paths.go # Path management
โ โโโ image/
โ โ โโโ image.go # Image download & management
โ โโโ containerops/
โ โ โโโ container.go # Container creation & execution
โ โโโ container/
โ โโโ container.go # Legacy container operations
โโโ main.go # Entry point
โโโ go.mod # Dependencies
โโโ README.md # This file
For educational purposes and simplicity:
- โ Easy to understand - Direct filesystem copy is conceptually simple
- โ No kernel dependencies - Works on any Linux system
- โ Complete isolation - Each container has its own filesystem
โ ๏ธ Trade-off - Uses more disk space and slower to create
Future improvement: Implement OverlayFS for Docker-like layered filesystem.
- โ Portable - No hardcoded paths
- โ User-specific - Each user has their own containers
- โ No root filesystem pollution - Clean separation
- โ
Easy cleanup - Just remove
~/.gocker
$ ./gocker run alpine /bin/sh
Container bf116791 created successfully
๐ณ Container ID: bf116791
Running command in container: [/bin/sh]
Starting container (PID: 1)
/ # hostname
gocker-container
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 /proc/self/exe child --rootfs ...
8 root 0:00 /bin/sh
14 root 0:00 ps aux
/ # exit
โ
Container bf116791 finished$ ./gocker run alpine /bin/ls -la /
Container d8ac5809 created successfully
๐ณ Container ID: d8ac5809
Running command in container: [/bin/ls -la /]
Starting container (PID: 1)
total 72
drwxr-xr-x 19 1000 1000 4096 Jan 2 15:22 .
drwxr-xr-x 19 1000 1000 4096 Jan 2 15:22 ..
drwxr-xr-x 2 1000 1000 4096 Jan 2 15:22 bin
drwxr-xr-x 2 1000 1000 4096 Jan 2 15:22 dev
...
โ
Container d8ac5809 finished$ ./gocker run alpine /bin/cat /etc/os-release
Container 94e0358a created successfully
๐ณ Container ID: 94e0358a
Running command in container: [/bin/cat /etc/os-release]
Starting container (PID: 1)
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.19.0
PRETTY_NAME="Alpine Linux v3.19"
โ
Container 94e0358a finished- OS: Linux (kernel 3.8+)
- Go: 1.21 or higher
- Only Alpine Linux is supported as base image
- No network namespace isolation (yet)
- No cgroups resource limiting (yet)
- No container persistence/restart
- No overlay filesystem (uses full copy)
- OverlayFS support for efficient storage
- Network namespace isolation
- Cgroups for resource limiting (CPU, memory)
- Container lifecycle management (start/stop/rm)
- Support for custom images
- Volume mounting
- Environment variable passing
This project demonstrates:
- Linux namespaces (PID, UTS, Mount, User, Network)
- User/UID mapping for unprivileged containers
- Process isolation techniques
- chroot jails
- OverlayFS and layered filesystems
- Network namespace isolation
- Copy-on-Write filesystems
- Filesystem management
- Go system programming
- CLI design with Cobra and flags
This is an educational project. Feel free to:
- Add new features
- Improve documentation
- Fix bugs
- Add tests
MIT License - See LICENSE file for details
- Inspired by Docker and container runtimes
- Uses Alpine Linux minirootfs
- Built with Cobra CLI framework
Made with โค๏ธ for learning how containers work