{"id":49716963,"url":"https://github.com/eth-library/nix-aerie","last_synced_at":"2026-05-08T20:35:03.312Z","repository":{"id":339553090,"uuid":"1161271902","full_name":"eth-library/nix-aerie","owner":"eth-library","description":" Nix flakes pre-baked into one OCI image — reproducible environments for devcontainers.","archived":false,"fork":false,"pushed_at":"2026-04-07T11:12:51.000Z","size":123,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-07T11:26:01.000Z","etag":null,"topics":["ci-cd","codespaces","devcontainers","devops","devshell","direnv","dx","flakes","nix","oci","reproducibility"],"latest_commit_sha":null,"homepage":"","language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eth-library.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2026-02-18T23:23:26.000Z","updated_at":"2026-04-07T10:50:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/eth-library/nix-aerie","commit_stats":null,"previous_names":["eth-library/nix-aerie"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/eth-library/nix-aerie","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eth-library%2Fnix-aerie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eth-library%2Fnix-aerie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eth-library%2Fnix-aerie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eth-library%2Fnix-aerie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eth-library","download_url":"https://codeload.github.com/eth-library/nix-aerie/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eth-library%2Fnix-aerie/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32796102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"ssl_error","status_checked_at":"2026-05-08T08:22:45.650Z","response_time":54,"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":["ci-cd","codespaces","devcontainers","devops","devshell","direnv","dx","flakes","nix","oci","reproducibility"],"created_at":"2026-05-08T20:35:02.698Z","updated_at":"2026-05-08T20:35:03.297Z","avatar_url":"https://github.com/eth-library.png","language":"Nix","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nix-aerie\n\nPre-baked devcontainer image for [GitHub Codespaces](https://github.com/features/codespaces) and [local devcontainers](https://containers.dev/). Ships [Nix](https://nixos.org/), [direnv](https://direnv.net/), and pre-cached development shells on an [Ubuntu 24.04](https://ubuntu.com/) base.\n\n## Why\n\nSetting up Nix in a fresh container (installing the binary, evaluating a project flake, downloading packages) can take up to 3 minutes and is error-prone. Installing Nix on top of a stock image via features or scripts doesn't help: it repeats the same setup on every container start.\n\n**nix-aerie** ships language toolchains pre-built inside the image, so `nix develop` works instantly instead of downloading packages on every start:\n- **One-click onboarding** — set the image in your `devcontainer.json` and every team member gets the same Nix + direnv environment with all dev dependencies. No install steps, no entrypoint scripts.\n- **Beginner-friendly** — new developers get the benefits of Nix shells without having to set up Nix themselves. Open the Codespace, start coding.\n- **Instant locally** — if the image is already pulled, local devcontainers start in seconds with no download at all. On Codespaces, you can enable [prebuilds](https://docs.github.com/en/codespaces/prebuilding-your-codespaces) for the same effect.\n\n\u003e If you already develop locally with Nix flakes, this image isn't meant to replace that workflow. It's for Codespaces and shared devcontainers where cold start time and consistent onboarding matter.\n\n## Usage\n\nSimply add a `.devcontainer/devcontainer.json` to your project. Pick the variant that matches your stack (`:base`, `:python`, or the full image with all shells) and point `remoteUser` to `dev`. If your project uses direnv, `onCreateCommand` takes care of trusting the `.envrc` on first start.\n\nHere's a real-world example for a Python project:\n\n`.devcontainer/devcontainer.json`:\n\n```jsonc\n{\n  \"name\": \"Pre-baked devcontainer including Nix flakes, Python, uv, and direnv\",\n  \"image\": \"ghcr.io/eth-library/nix-aerie-python:latest\",\n  \"remoteUser\": \"dev\",\n  \"onCreateCommand\": \"direnv allow .\",\n  \"customizations\": {\n    \"vscode\": {\n      \"extensions\": [\n        \"jnoortheen.nix-ide\",\n        \"ms-python.python\"\n      ],\n      \"settings\": {\n        \"python.defaultInterpreterPath\": \"${workspaceFolder}/.venv/bin/python\",\n        \"python.terminal.activateEnvironment\": false\n      }\n    }\n  }\n}\n```\n\n### Aligning your nixpkgs pin\n\nTo get the most out of the pre-cached shells, have your project's `flake.nix` follow the same nixpkgs pin as **nix-aerie**. This way `nix develop` finds everything in the Nix store and resolves instantly:\n\n`flake.nix`:\n\n```nix\n{\n  inputs = {\n    nix-aerie.url = \"github:eth-library/nix-aerie\";\n    nixpkgs.follows = \"nix-aerie/nixpkgs\";\n  };\n\n  outputs = { self, nixpkgs, ... }:\n    let\n      systems = [ \"x86_64-linux\" \"aarch64-linux\" \"x86_64-darwin\" \"aarch64-darwin\" ];\n      forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});\n    in\n    {\n      devShells = forAllSystems (pkgs: {\n        default = pkgs.mkShell {\n          packages = [\n            pkgs.python312\n            pkgs.uv\n          ];\n        };\n      });\n    };\n}\n```\n\nThe key line is `nixpkgs.follows = \"nix-aerie/nixpkgs\"`. This ensures your project uses the exact same nixpkgs revision that the image was built with, so all store paths match. Without it, `nix develop` still works but downloads packages from cache.nixos.org instead of using the pre-cached ones.\n\n## How It Works\n\n### Ubuntu base\n\nThe image builds on Ubuntu 24.04 for the conventional FHS layout, glibc, and `apt-get`, the things devcontainer features and standard Linux tooling expect. A familiar starting point for developers new to Nix: no need to learn NixOS to benefit from reproducible toolchains.\n\n### Nix-managed toolchain\n\nAll developer tools (bash, git, direnv, curl, jq, and language shells) are managed by Nix through a single `flake.nix` with one `flake.lock`. Reproducible, pinned, and pre-cached in the image.\n\nThe image also ships with [direnv](https://direnv.net/) and [nix-direnv](https://github.com/nix-community/nix-direnv) pre-configured. When your project has an `.envrc` with `use flake`, opening a terminal automatically activates the Nix shell. No manual `nix develop` needed.\n\n### Variants and layer architecture\n\nEach Nix shell closure (Python, Go, Java, K8s) is mapped to its own content-addressed OCI layer via [nix2container](https://github.com/nlewo/nix2container). The shared base packages are built as a separate layer and excluded from shell layers to avoid duplication. Variants compose only the layers they need:\n\n```mermaid\nblock-beta\n  columns 1\n\n  variant[\"Variant layers\\nPython · Go · Java · K8s · …\"]\n  shared[\"Shared base\\nNix · bash · git · direnv · curl · jq\"]\n  ubuntu[\"Ubuntu 24.04\\nFHS · glibc · apt-get\"]\n\n  style variant fill:#d4dce8,color:#2d3748,stroke:#7b8fa3\n  style shared fill:#b8c6d6,color:#2d3748,stroke:#5d7089\n  style ubuntu fill:#9cb0c4,color:#2d3748,stroke:#4a6478\n```\n\n| Variant | Image | Packages | Shell definition |\n|---------|-------|----------|-----------------|\n| Base | `nix-aerie-base` | Nix, bash, git, direnv, curl, jq | [`flake.nix` (`userPackages`)](flake.nix#L62) |\n| Python | `nix-aerie-python` | Python 3.12, uv | [`shells/python.nix`](shells/python.nix) |\n| Go | `nix-aerie-go` | Go, gopls, golangci-lint | [`shells/go.nix`](shells/go.nix) |\n| Java | `nix-aerie-java` | JDK 25 (headless), Maven | [`shells/java.nix`](shells/java.nix) |\n| K8s | `nix-aerie-k8s` | kubectl, Helm | [`shells/k8s.nix`](shells/k8s.nix) |\n| Full | `nix-aerie` | All of the above | all shells combined |\n\nBecause layers are content-addressed, pulling one variant after another only downloads the delta. Security updates push only the store paths that actually changed, not the full image.\n\nThe nixpkgs source tree (~32 MB compressed) is also included in the Nix store, so flake evaluation doesn't need to download nixpkgs first. This saves time on every `nix develop` call regardless of whether your pins match the image.\n\n## Details\n\n- **nix2container** builds the image without Docker. Content-addressed layers mean updates push only the store paths that changed, not the full image.\n- **Single-user Nix**, the container standard; no daemon or systemd required.\n- **`USER=dev`** in the image, ready for devcontainers and `docker run` out of the box.\n- **One `flake.lock`** pins all shells to the same nixpkgs revision, guaranteeing store-path deduplication across variants.\n- **Architecture**: Multi-arch (`linux/amd64` + `linux/arm64`) published as OCI manifests — `docker pull` selects the native image automatically, including on Apple Silicon.\n\n## License\n\n[Apache-2.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feth-library%2Fnix-aerie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feth-library%2Fnix-aerie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feth-library%2Fnix-aerie/lists"}