{"id":33662792,"url":"https://github.com/martishin/toy-container-runtime","last_synced_at":"2026-03-09T00:32:05.476Z","repository":{"id":321503027,"uuid":"1086094213","full_name":"martishin/toy-container-runtime","owner":"martishin","description":null,"archived":false,"fork":false,"pushed_at":"2025-11-02T01:46:15.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-26T04:48:57.612Z","etag":null,"topics":["cgroups","chroot","devcontainer","docker","golang","linux","namespace"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martishin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-30T00:02:38.000Z","updated_at":"2025-11-02T01:46:18.000Z","dependencies_parsed_at":"2025-10-30T02:23:28.352Z","dependency_job_id":null,"html_url":"https://github.com/martishin/toy-container-runtime","commit_stats":null,"previous_names":["martishin/toy-container-runtime"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/martishin/toy-container-runtime","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martishin%2Ftoy-container-runtime","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martishin%2Ftoy-container-runtime/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martishin%2Ftoy-container-runtime/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martishin%2Ftoy-container-runtime/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martishin","download_url":"https://codeload.github.com/martishin/toy-container-runtime/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martishin%2Ftoy-container-runtime/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30278517,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T20:45:49.896Z","status":"ssl_error","status_checked_at":"2026-03-08T20:45:49.525Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cgroups","chroot","devcontainer","docker","golang","linux","namespace"],"created_at":"2025-12-03T00:00:38.562Z","updated_at":"2026-03-09T00:32:05.461Z","avatar_url":"https://github.com/martishin.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# toy-container-runtime 🚗\n\nA tiny container runtime written in Go that demonstrates **how containers actually work** - no magic, just Linux\nfeatures:\n\n- **Namespaces** (UTS, PID, Mount) → isolate what a process can *see*\n- **chroot + rootfs** → give the process its own filesystem view\n- **cgroups (pids)** → limit what a process can *use*\n- Minimal **mount setup** → `/proc` and a scratch `tmpfs`\n\n\n## Why containers?\n\nContainers are *just Linux processes* with:\n\n- a **restricted view** (namespaces),\n- a **different root filesystem** (chroot/pivot_root with a “rootfs”),\n- and **resource limits** (cgroups).\n\nThis makes them **portable** (ship a filesystem), **isolated** (can’t see host stuff), and **efficient** (no full VM per\napp). Real runtimes (runc/containerd/Docker) add a ton of safety and orchestration around these same primitives.\n\n\n## What this project demonstrates\n\n1) **UTS namespace** → custom hostname (`container`).\n2) **PID namespace** → your process becomes **PID 1** inside the container.\n3) **Mount namespace** → private mount table (no host pollution).\n4) **chroot rootfs** → your command runs in a Docker-built filesystem.\n5) **/proc + tmpfs** → mounts that userspace tools rely on.\n6) **pids cgroup** → best-effort process count limit.\n\nYou’ll literally see: a different hostname, PID 1, your own `/proc`, and a private tmpfs.\n\n\n## How it works\n\n- We build a root filesystem from `Dockerfile` (Alpine + python3 + bash), then `docker export` it to `./rootfs`.\n- `mini_container run ...` re-execs itself as `child` with:\n    - `CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS` (+ `Unshare(CLONE_NEWNS)`)\n    - set hostname → `container`\n    - `chroot(rootfs)` and `chdir(\"/\")`\n    - make `/` a mountpoint, set mount propagation (slave → private)\n    - mount `/proc` and a `tmpfs` at `/mytemp`\n    - (best-effort) put the process in a **pids cgroup** to cap forks\n- Finally, it `exec`s your command (`/usr/bin/python3 /opt/app/hello.py` or `/bin/bash`).\n\n\n## Prerequisites\n\n- Linux (or macOS via Dev Containers / Docker Desktop)\n- Go 1.24.5\n- Docker (to build and export the rootfs)\n- In devcontainers: container needs `--privileged`, `SYS_ADMIN`, and the Docker socket mounted\n\n\n## Running locally\n\n```bash\n# Build the runtime\nmake build\n\n# One-shot: build image -\u003e export rootfs -\u003e run demo app\nmake run\n# Expected: \"Hello from container!\"\n\n# Interactive shell inside the container\nmake bash\n```\n\n\n## Verify you are in a container\n\nInside the container shell:\n\n```bash\nhostname                    # -\u003e container\nmount | head                # shows /proc and /mytemp tmpfs\nps -ef                      # PID namespace view (you're PID 1)\ncat /proc/self/status | sed -n '1,12p'\n```\n\n\n## Project structure\n\n```\n.\n├── Dockerfile                   # rootfs content (Alpine + python3 + bash)\n├── Makefile\n├── app/hello.py                 # demo app\n├── cmd/mini_container/main.go   # Cobra CLI: build/run/run-rootfs/child\n├── internal/\n│   ├── build/dockerfile_driver.go  # docker build/create/export -\u003e ./rootfs\n│   └── container/\n│       ├── namespaces.go           # SysProcAttr (linux)\n│       ├── fs.go                   # mount propagation, /proc, tmpfs\n│       ├── cgroups.go              # pids cgroup (v1/v2 best-effort)\n│       └── runner.go               # Run / RunChild\n├── scripts/build-rootfs.sh\n└── go.mod / go.sum\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartishin%2Ftoy-container-runtime","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartishin%2Ftoy-container-runtime","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartishin%2Ftoy-container-runtime/lists"}