-
Notifications
You must be signed in to change notification settings - Fork 0
Documentation #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
82902fb
a21ecc8
378a583
02164c3
e759999
b2dc201
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,9 @@ | ||
| # Summary | ||
|
|
||
| - [Git: Step Zero](./chapter_1.md) | ||
| - [Devcontainers](./chapter_2.md) | ||
| - [Nix](./nix/README.md) | ||
| - [Home Manager](./nix/home-manager.md) | ||
| - [Flakes]() | ||
| - [Tools](./tools/README.md) | ||
| - [Just](./tools/just.md) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| # Devcontainers | ||
|
|
||
| Devcontainers often get a bad reputation—and sometimes deservedly so. Running Docker for a simple webpage feels like swatting a fly with a sledgehammer, especially when the container is bloated and slow. | ||
|
|
||
| But the *idea* behind devcontainers is sound: **a reproducible, isolated development environment**. | ||
|
|
||
| ## The Real Problem | ||
|
|
||
| It's not about Docker. It's about maintaining focus and productivity by keeping your working environment clean: | ||
|
|
||
| - VS Code extensions that conflict or clutter | ||
| - System binaries that drift between machines | ||
| - "Works on my machine" debugging sessions | ||
| - Configuration that accumulates like sediment | ||
|
|
||
| A devcontainer solves this by declaring exactly what your environment should contain—nothing more, nothing less. | ||
|
|
||
| > **macOS Users:** If you're developing locally, use [OrbStack](https://orbstack.dev/) instead of Docker Desktop. It's significantly faster, lighter on resources, and makes devcontainer iteration actually pleasant. The trial is generous enough to evaluate whether the speed gains justify the cost. | ||
|
|
||
| ## Starting Minimal | ||
|
|
||
| This template's initial devcontainer ([cc11da7](https://github.com/alycda/dev/commit/cc11da7273691c76e44d6317dc5547561d078024)) was intentionally sparse: | ||
|
|
||
| ```json | ||
| { | ||
| "image": "debian:bookworm-slim", | ||
| "features": { | ||
| "ghcr.io/devcontainers/features/nix:1": { | ||
| "packages": ["direnv"] | ||
alycda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
Comment on lines
+27
to
+30
|
||
| }, | ||
| "customizations": { | ||
| "vscode": { | ||
| "extensions": ["jnoortheen.nix-ide"], | ||
| "settings": { | ||
| "editor.wordWrap": "on", | ||
| "git.autofetch": true | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| That's it: | ||
| - **Debian slim** - A minimal base, not Ubuntu with kitchen sink | ||
| - **Nix + direnv** - The foundation for reproducible tooling (more on this later) | ||
| - **One extension** - Nix language support | ||
| - **Sensible defaults** - Word wrap, auto-fetch | ||
|
|
||
| ## Why This Matters | ||
|
|
||
| The devcontainer is the *second* commit in this repository's history (after `.gitignore`). This ordering is intentional: | ||
|
|
||
| 1. **Step 0**: Ignore the right files | ||
| 2. **Step 1**: Define the environment | ||
|
|
||
| Everything else—the actual code, the tools, the configuration—builds on this foundation. When you open this repository in VS Code or GitHub Codespaces, you get exactly the environment the project expects. | ||
|
|
||
| ## The Nix Connection | ||
|
|
||
| Notice that we install Nix immediately. The devcontainer itself stays minimal because Nix (via `shell.nix` and `direnv`) handles the actual development tools. This separation means: | ||
|
|
||
| - The container is fast to build | ||
| - Tools are managed declaratively in Nix | ||
| - You can use the same Nix configuration outside Docker | ||
|
|
||
| We'll cover Nix in detail in the next [chapter](./nix/README.md). | ||
|
|
||
| ## When to Use Devcontainers | ||
|
|
||
| Use them when: | ||
| - **Onboarding matters** - New contributors should be productive in minutes | ||
| - **Environment consistency is critical** - CI/CD should match local dev | ||
| - **You're using Codespaces** - It's the native way to define the environment | ||
|
|
||
| Skip them when: | ||
| - The project is simple enough that a README suffices | ||
| - Docker overhead genuinely hurts your workflow | ||
| - You're the only developer and prefer native tooling | ||
|
|
||
| The goal isn't Docker for Docker's sake—it's having a single source of truth for "what does this project need to run?" | ||
|
|
||
| --- | ||
|
|
||
| - https://learnxinyminutes.com/docker/ | ||
| - https://containers.dev/ | ||
alycda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - https://code.visualstudio.com/docs/devcontainers/containers | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,90 @@ | ||||||
| # Nix | ||||||
|
|
||||||
| Nix is a package manager that guarantees reproducibility. Same inputs, same outputs—every time, on every machine. | ||||||
|
|
||||||
| If you've ever dealt with "it works on my machine" or spent hours debugging environment differences, Nix solves that problem at the root. | ||||||
|
|
||||||
| ## The Core Idea | ||||||
|
|
||||||
| Traditional package managers install software globally and hope for the best. Nix takes a different approach: | ||||||
|
|
||||||
| - **Immutable packages** - Each package is stored in isolation with a unique hash | ||||||
| - **Declarative configuration** - You describe *what* you want, not *how* to install it | ||||||
| - **Reproducible builds** - The same `shell.nix` produces the same environment everywhere | ||||||
|
|
||||||
| ## The Initial Setup | ||||||
|
|
||||||
| This template's first Nix integration ([8b951a5](https://github.com/alycda/dev/commit/8b951a56c38efb96b6f7533d6b10a946b7d3c233)) added three files: | ||||||
|
|
||||||
| ### shell.nix | ||||||
|
|
||||||
| ```nix | ||||||
| { pkgs ? import <nixpkgs> {} }: | ||||||
|
|
||||||
| pkgs.mkShell { | ||||||
| buildInputs = with pkgs; [ just ]; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| This declares a shell environment with one tool: `just` (a command runner). Want more tools? Add them to the list: | ||||||
|
|
||||||
| ```nix | ||||||
| buildInputs = with pkgs; [ just nodejs python3 rustc ]; | ||||||
| ``` | ||||||
|
|
||||||
| ### .envrc | ||||||
|
|
||||||
| ```bash | ||||||
| use nix | ||||||
| ``` | ||||||
|
|
||||||
| This one-liner tells `direnv` to activate the Nix shell automatically when you enter the directory. | ||||||
|
|
||||||
| ### The Hook | ||||||
|
|
||||||
| The devcontainer's `postCreateCommand` wires it together: | ||||||
|
|
||||||
| ```bash | ||||||
| echo 'eval "$(direnv hook bash)"' >> ~/.bashrc && direnv allow | ||||||
| ``` | ||||||
|
|
||||||
| ## How It Works | ||||||
|
|
||||||
| 1. You `cd` into the project directory | ||||||
| 2. `direnv` detects `.envrc` | ||||||
| 3. `.envrc` says `use nix` | ||||||
| 4. Nix builds/fetches the packages in `shell.nix` | ||||||
| 5. Your shell now has those tools available | ||||||
|
|
||||||
| Leave the directory, tools disappear. Enter again, they're back. No global pollution. | ||||||
|
|
||||||
| ## Why This Matters | ||||||
|
|
||||||
| The devcontainer installs Nix, but Nix manages the actual tools. This separation is powerful: | ||||||
|
|
||||||
| - **Lightweight container** - Just Debian + Nix, nothing else | ||||||
| - **Declarative tools** - `shell.nix` is version-controlled documentation of your dependencies | ||||||
| - **Works anywhere** - Same `shell.nix` works on macOS, Linux, or in Codespaces | ||||||
| - **Easy iteration** - Add a tool to `shell.nix`, run `direnv reload`, done | ||||||
|
|
||||||
| ## Current State | ||||||
|
|
||||||
| The template's `shell.nix` has grown to include several tools: | ||||||
|
|
||||||
| ```nix | ||||||
| buildInputs = with pkgs; [ just cheat asciinema_3 presenterm tmux mdbook ]; | ||||||
| ``` | ||||||
|
|
||||||
| Each of these gets its own chapter later. The point is: adding tools is trivial. One line in `shell.nix`, and everyone who clones this repo gets the same environment. | ||||||
|
||||||
| Each of these gets its own chapter later. The point is: adding tools is trivial. One line in `shell.nix`, and everyone who clones this repo gets the same environment. | |
| Whether it's just one tool or many, adding them is trivial. One line in `shell.nix`, and everyone who clones this repo gets the same environment. |
alycda marked this conversation as resolved.
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,118 @@ | ||||||
| # Nix: Home Manager | ||||||
|
|
||||||
| The previous chapter covered `shell.nix` for project-specific tools. But what about tools you want *everywhere*—your editor, your shell configuration, your personal utilities? | ||||||
|
|
||||||
| That's what [Home Manager](https://github.com/nix-community/home-manager) solves. | ||||||
|
|
||||||
| ## shell.nix vs home.nix | ||||||
|
|
||||||
| Think of it this way: | ||||||
|
|
||||||
| | | shell.nix | home.nix | | ||||||
| |---|---|---| | ||||||
| | **Scope** | Per-project | Per-user | | ||||||
| | **Activates** | When you `cd` into directory | Always available | | ||||||
| | **Use for** | Project dependencies | Personal tools and config | | ||||||
|
|
||||||
| `shell.nix` gives you `just` and `mdbook` when working on this template. `home.nix` gives you `helix` and `ripgrep` no matter what directory you're in. | ||||||
|
|
||||||
| ## The Initial Setup | ||||||
|
|
||||||
| Home Manager was introduced in commit [c8ec56a](https://github.com/alycda/dev/commit/c8ec56a009f579f012a17566f5862dd2bd42cd81): | ||||||
|
|
||||||
| ```nix | ||||||
| { pkgs, ... }: | ||||||
| { | ||||||
| programs.home-manager.enable = true; | ||||||
|
|
||||||
| home.packages = with pkgs; [ | ||||||
| helix | ||||||
| ripgrep | ||||||
| ]; | ||||||
|
|
||||||
| programs.direnv = { | ||||||
| enable = true; | ||||||
| nix-direnv.enable = true; | ||||||
| }; | ||||||
|
|
||||||
| home.stateVersion = "24.05"; | ||||||
| home.username = "root"; | ||||||
| home.homeDirectory = "/root"; | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| This declares: | ||||||
| - **Core packages** - `helix` (editor) and `ripgrep` (search) available globally | ||||||
| - **direnv integration** - With `nix-direnv` for faster Nix shell loading | ||||||
| - **Self-management** - Home Manager can update itself | ||||||
|
|
||||||
| ## Beyond Packages | ||||||
|
|
||||||
| Home Manager doesn't just install tools—it *configures* them. The current `home.nix` includes: | ||||||
|
|
||||||
| ```nix | ||||||
| home.sessionVariables = { | ||||||
| EDITOR = "hx"; | ||||||
| VISUAL = "code"; | ||||||
| }; | ||||||
|
|
||||||
| programs.bash = { | ||||||
| enable = true; | ||||||
| initExtra = '' | ||||||
| # Custom shell initialization | ||||||
| ''; | ||||||
| }; | ||||||
alycda marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| ``` | ||||||
|
|
||||||
| Your editor preferences, shell configuration, environment variables—all declarative, all version-controlled. | ||||||
|
|
||||||
| ## The Rebuild Command | ||||||
|
|
||||||
| When you modify `home.nix`, apply changes with: | ||||||
|
|
||||||
| ```bash | ||||||
| just rebuild | ||||||
| ``` | ||||||
|
|
||||||
| Which runs: | ||||||
|
|
||||||
| ```bash | ||||||
| home-manager switch -b backup -f .devcontainer/home.nix | ||||||
| ``` | ||||||
|
|
||||||
| The `-b backup` flag preserves any existing dotfiles that would be overwritten. | ||||||
|
|
||||||
| ## Current State | ||||||
|
|
||||||
| The template's `home.nix` has grown to include: | ||||||
|
|
||||||
| ```nix | ||||||
| home.packages = with pkgs; [ | ||||||
| helix # Terminal editor | ||||||
| ripgrep # Fast search | ||||||
| jujutsu # Git-compatible VCS | ||||||
| gh # GitHub CLI | ||||||
| claude-code # AI assistant | ||||||
|
||||||
| claude-code # AI assistant | |
| fd # Fast file finder |
Copilot
AI
Dec 30, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The relative path in this link is incorrect. Since this file is located at book/src/nix/home-manager.md, the path "./tools/just.md" tries to find tools/ inside the nix/ directory. The correct relative path should be "../tools/just.md" to navigate up to the src directory, then into the tools directory.
| You've seen `just rebuild` above. The [next chapter](./tools/just.md) covers Just—a command runner that ties these tools together with simple, memorable commands. | |
| You've seen `just rebuild` above. The [next chapter](../tools/just.md) covers Just—a command runner that ties these tools together with simple, memorable commands. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Tools | ||
|
|
||
| This section covers the tools included in this template's `shell.nix`. They're available automatically when you enter the project directory thanks to direnv. | ||
|
|
||
| These aren't arbitrary choices—each solves a specific friction point in development workflows: | ||
|
|
||
| - **Just** - Command runner for memorable aliases | ||
| - **cheat** - Quick reference for commands you forget | ||
| - **Jujutsu** - Git-compatible VCS with better UX | ||
| - **Presenterm** - Terminal-based presentations | ||
| - **Asciinema** - Record terminal sessions | ||
| - **mdbook** - Generate documentation sites | ||
|
|
||
| All are installed via Nix, so they're reproducible across machines and don't pollute your global system. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Flakes entry has an empty link target, which will result in a broken link in the generated documentation. Either provide the actual path to the Flakes documentation file, or remove this entry until the documentation is ready.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
placeholder to denote flakes are not forgotten but not implemented/documented yet