
2026/02/01 17:02
**Microvm.nix を用いた NixOS 上のコーディングエージェント仮想マシン**
RSS: https://news.ycombinator.com/rss
要約▶
日本語訳:
(以下に示すテキストを日本語へ翻訳してください)
Summary
The article demonstrates how to rapidly spin up isolated, disposable micro‑VMs on NixOS for running coding assistants such as Claude Code without exposing a user’s personal files. It builds upon the
microvm.nix project and NixOS flakes, adding a custom network bridge (microbr, IP range 192.168.83.1/24) that NATs from the host interface eno1. All micro‑VM interfaces are added to this bridge via systemd-networkd.
The flake (
flake.nix) pulls in multiple inputs—nixpkgs, nixpkgs-unstable, stapelbergnix, zkjnastools, microvm, and home-manager—and enables the microvm.nixosModules.host module on the host machine. Two example micro‑VMs are defined in microvm.nix:
- emacsvm – IP 192.168.83.6, tap
, MAC 02:00:00:00:00:05;microvm4 - goprotobufvm – IP 192.168.83.7, tap
, MAC 02:00:00:00:00:06.microvm5
Each VM uses an 8 GB
var.img overlay with 8 vCPUs and 4 GB RAM, runs on cloud‑hypervisor (or QEMU), and includes a systemd shutdown workaround. Shared directories per VM include the workspace (/home/michael/microvm/<name>), host Nix store, SSH keys, and a dedicated state directory (~/claude-microvm). The microvm-home.nix file configures Home‑Manager for each VM, installing Zsh, Emacs, and setting CLAUDE_CONFIG_DIR to the shared credentials folder. For Go development, the goprotobuf.nix module adds a full Go toolchain (go, gopls, delve, protobuf, etc.).
To launch a VM, the host creates the workspace and SSH key, then runs
systemctl start microvm@emacsvm. The user SSHs into the VM (ssh 192.168.83.6) and starts Claude with --dangerously-skip-permissions. A dedicated Claude Skill (create-microvm) automates new VM creation: it sets up directories, generates keys, clones repositories, updates host configuration, and outputs a ready‑to‑deploy configuration that the user can apply via systemctl start microvm@….
The article concludes that NixOS enables fast, secure creation of disposable micro‑VMs for coding agents, requiring minimal maintenance while preserving strong isolation from personal data. Future work could extend this pattern with additional Skills and support other coding assistants or development environments.
This revised summary now fully reflects all major key points, avoids unwarranted inference, maintains clarity, and eliminates vague phrasing.
本文
目次
- microvm.nix の設定
- ステップ 1:ネットワークの準備
- ステップ 2:flake.nix
- ステップ 3:microvm.nix
- ステップ 4:microvm‑base.nix
- ステップ 5:microvm‑home.nix
- ステップ 6:goprotobuf.nix
- VM の起動
- Claude で VM を作成する方法
- Claude Code で設定を再現する
- 結論
コーディングエージェントの価値に気づいた
コーディングエージェントは、プログラムコードを扱うあらゆる場面―アーキテクチャの学習・バグ診断・概念実証の開発―で有用なツールです。彼らが実行したい全てのコマンドを確認し続けると、作業はすぐに退屈になってしまいます。エージェントをレビュー無しで安全に動かすためには、「仮想機械(VM)」という解決策が必要でした。個人ファイルへのアクセスを許さず、VM が侵害されても構わないような環境―単に VM を破棄して再作成できるもの――です。
状態を残す従来の VM を毎回リインストールする代わりに、ephemeral(揮発性) な VM を好みます。これらはホストと共有したファイル以外にはディスク上に何も残しません。microvm.nix プロジェクトが NixOS 上でこの作業を簡単にしてくれ、この記事では私の設定手順をご紹介します。
NixOS を初めて聞いた方は、Wikipedia のページや公式サイト(nixos.org)を確認してください。2025 年に Nix に移行した理由を書き、複数の記事を公開しています。
AI エージェントの脅威モデルを理解するには、Simon Willison の「The lethal trifecta for AI agents: private data, untrusted content, and external communication」(2025年6月)を読んでください。この文書は private‑data 要素を除外したものです。
サンドボックス化全般に興味があるなら、Luis Cardoso の「A field guide to sandboxes for AI」(2026年1月)も参照してください。ここでは解決策の比較はせず、ひとつの可能性を示すだけです。
また、exe.dev(David Crawshaw と Josh Bleecher Snyder による)や Fly.io の Sprites など、商用サービスもこのニーズに応えています。
microvm.nix の設定
さっそく始めましょう! 以下のセクションでは私の構成を段階的に解説します。
ステップ 1:ネットワークの準備
192.168.33.1/24 を使い、
eno1 インターフェース経由で NAT する microbr ブリッジを作成しました。すべての microvm* インターフェースはこのブリッジに追加されます。
systemd.network.netdevs."20-microbr".netdevConfig = { Kind = "bridge"; Name = "microbr"; }; systemd.network.networks."20-microbr" = { matchConfig.Name = "microbr"; addresses = [ { Address = "192.168.83.1/24"; } ]; networkConfig = { ConfigureWithoutCarrier = true; }; }; systemd.network.networks."21-microvm-tap" = { matchConfig.Name = "microvm*"; networkConfig.Bridge = "microbr"; }; networking.nat = { enable = true; internalInterfaces = [ "microbr" ]; externalInterface = "eno1"; };
ステップ 2:flake.nix
microvm モジュールを
flake.nix の新しい入力として追加し、PC(midna)の NixOS 設定で microvm.nixosModules.host を有効にしました。また、すべての VM を宣言する新規ファイル microvm.nix も作成しています。以下は私の flake.nix の内容です。
{ inputs = { nixpkgs = { url = "github:nixos/nixpkgs/nixos-25.11"; }; nixpkgs-unstable = { url = "github:nixos/nixpkgs/nixos-unstable"; }; stapelbergnix = { url = "github:stapelberg/nix"; inputs.nixpkgs.follows = "nixpkgs"; }; zkjnastools = { url = "github:stapelberg/zkj-nas-tools"; inputs.nixpkgs.follows = "nixpkgs"; }; microvm = { url = "github:microvm-nix/microvm.nix"; inputs.nixpkgs.follows = "nixpkgs"; }; home-manager = { url = "github:nix-community/home-manager/release-25.11"; inputs.nixpkgs.follows = "nixpkgs"; }; configfiles = { url = "github:stapelberg/configfiles"; flake = false; }; # repo is not a flake }; outputs = { self, stapelbergnix, zkjnastools, nixpkgs, nixpkgs-unstable, microvm, home-manager, configfiles, }@inputs: let system = "x86_64-linux"; pkgs = import nixpkgs { inherit system; config.allowUnfree = false; }; pkgs-unstable = import nixpkgs-unstable { inherit system; config.allowUnfree = true; }; in { nixosConfigurations = { midna = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; specialArgs = { inherit inputs; }; modules = [ (import ./configuration.nix) stapelbergnix.lib.userSettings stapelbergnix.lib.systemdNetwork stapelbergnix.lib.systemdBoot stapelbergnix.lib.prometheusNode zkjnastools.nixosModules.zkjbackup microvm.nixosModules.host ./microvm.nix ]; }; }; }; }
ステップ 3:microvm.nix
以下の
microvm.nix は、Emacs 用と Go Protobuf 用の 2 つの microVM を宣言します。
{ config, lib, pkgs, inputs, ... }: let inherit (inputs) nixpkgs-unstable stapelbergnix microvm configfiles home-manager; microvmBase = import ./microvm-base.nix; in { microvm.vms.emacsvm = { autostart = false; config = { imports = [ stapelbergnix.lib.userSettings microvm.nixosModules.microvm (microvmBase { hostName = "emacsvm"; ipAddress = "192.168.83.6"; tapId = "microvm4"; mac = "02:00:00:00:00:05"; workspace = "/home/michael/microvm/emacs"; inherit nixpkgs-unstable configfiles home-manager stapelbergnix; }) ./microvms/emacs.nix ]; }; }; microvm.vms.goprotobufvm = { autostart = false; config = { imports = [ stapelbergnix.lib.userSettings microvm.nixosModules.microvm (microvmBase { hostName = "goprotobufvm"; ipAddress = "192.168.83.7"; tapId = "microvm5"; mac = "02:00:00:00:00:06"; workspace = "/home/michael/microvm/goprotobuf"; inherit nixpkgs-unstable configfiles home-manager stapelbergnix; extraZshInit = '' export GOPATH=$HOME/go export PATH=$GOPATH/bin:$PATH ''; }) ./microvms/goprotobuf.nix ]; }; }; }
ステップ 4:microvm‑base.nix
microvm-base.nix は以下のパラメータを受け取り、次の設定を行います。
とsystemd-networkd
を使ったネットワーク構成systemd-resolved- ワークスペース(例:
)~/microvm/emacs - ホスト側 Nix ストア (
) への共有、SSH ホスト鍵 (/nix/store
) の共有、microVM 専用の状態ディレクトリ~/claude-microvm - 8 GB のディスクオーバーレイ (
) をvar.img
に保存/var/lib/microvms/<name> - Cloud‑hypervisor(QEMU も可)で 8 vCPU と 4 GB RAM を割り当て
- シャットダウン時に
がsystemd
をアンマウントしようとする問題への回避策/nix/store
{ hostName, ipAddress, tapId, mac, workspace, nixpkgs-unstable, configfiles, home-manager, stapelbergnix, extraZshInit ? "", }: { config, lib, pkgs, ... }: let system = pkgs.stdenv.hostPlatform.system; pkgsUnstable = import nixpkgs-unstable { inherit system; config.allowUnfree = true; }; in { imports = [ home-manager.nixosModules.home-manager ]; home-manager.useGlobalPkgs = true; home-manager.useUserPackages = true; home-manager.extraSpecialArgs = { inherit configfiles stapelbergnix; }; home-manager.users.michael = { imports = [ ./microvm-home.nix ]; microvm.extraZshInit = extraZshInit; }; environment.systemPackages = [ pkgsUnstable.claude-code ]; networking.hostName = hostName; system.stateVersion = "25.11"; services.openssh.enable = true; users.groups.michael.gid = 1000; users.users.michael.group = "michael"; services.resolved.enable = true; networking.useDHCP = false; networking.useNetworkd = true; networking.tempAddresses = "disabled"; systemd.network.enable = true; systemd.network.networks."10-e" = { matchConfig.Name = "e*"; addresses = [ { Address = "${ipAddress}/24"; } ]; routes = [ { Gateway = "192.168.83.1"; } ]; }; networking.nameservers = [ "8.8.8.8" "1.1.1.1" ]; networking.firewall.enable = false; systemd.settings.Manager.DefaultTimeoutStopSec = "5s"; systemd.mounts = [ { what = "store"; where = "/nix/store"; overrideStrategy = "asDropin"; unitConfig.DefaultDependencies = false; } ]; services.openssh.hostKeys = [ { path = "/etc/ssh/host-keys/ssh_host_ed25519_key"; type = "ed25519"; } ]; microvm = { writableStoreOverlay = "/nix/.rw-store"; volumes = [ { mountPoint = "/var"; image = "var.img"; size = 8192; } ]; shares = [ { proto = "virtiofs"; tag = "ro-store"; source = "/nix/store"; mountPoint = "/nix/.ro-store"; } { proto = "virtiofs"; tag = "ssh-keys"; source = "${workspace}/ssh-host-keys"; mountPoint = "/etc/ssh/host-keys"; } { proto = "virtiofs"; tag = "claude-credentials"; source = "/home/michael/claude-microvm"; mountPoint = "/home/michael/claude-microvm"; } { proto = "virtiofs"; tag = "workspace"; source = workspace; mountPoint = workspace; } ]; interfaces = [ { type = "tap"; id = tapId; mac = mac; } ]; hypervisor = "cloud-hypervisor"; vcpu = 8; mem = 4096; socket = "control.socket"; }; }
ステップ 5:microvm‑home.nix
microvm-home.nix は home-manager を設定し、次のことを行います。
の読み込みで Zsh を構成.zshrc- Emacs を自分の設定で構築
- Claude Code を共有ディレクトリ
へ配置~/claude-microvm
{ config, pkgs, lib, configfiles, stapelbergnix, ... }: { options.microvm.extraZshInit = lib.mkOption { type = lib.types.lines; default = ""; description = "Extra lines to add to zsh initContent"; }; config = { home.username = "michael"; home.homeDirectory = "/home/michael"; programs.zsh.enable = true; programs.zsh.history = { size = 4000; save = 10000000; ignoreDups = true; share = false; append = true; }; programs.zsh.initContent = '' ${builtins.readFile "${configfiles}/zshrc"} export CLAUDE_CONFIG_DIR=/home/michael/claude-microvm ${config.microvm.extraZshInit} ''; programs.emacs.enable = true; programs.emacs.package = stapelbergnix.lib.emacsWithPackages { inherit pkgs; }; home.file.".config/emacs" = { source = "${configfiles}/config/emacs"; }; home.stateVersion = "25.11"; programs.home-manager.enable = true; }; }
ステップ 6:goprotobuf.nix
goprotobuf.nix は Go Protobuf 開発に必要なパッケージを追加します。
{ pkgs, ... }: { environment.systemPackages = with pkgs; [ go gopls delve protobuf gnumake gcc git ripgrep ]; }
VM の起動
ワークスペースと SSH ホスト鍵を作成します。
mkdir -p ~/microvm/emacs/ssh-host-keys ssh-keygen -t ed25519 -N "" \ -f ~/microvm/emacs/ssh-host-keys/ssh_host_ed25519_key
VM を起動します。
sudo systemctl start microvm@emacsvm
数秒で起動し、ping に応答します。SSH で接続し(例:
tmux 内)、許可プロンプト無しで Claude を実行できます。
% ssh 192.168.83.2 emacsvm% cd microvm/emacs emacsvm% claude --dangerously-skip-permissions
Claude で VM を作成する
一度 MicroVM をセットアップすると、プロセスは面倒に感じることがあります。Claude Skills が役立ちます:Markdown ファイルで Claude に特定の手順を指示します。
例(
.claude/skills/create-microvm/SKILL.md):
--- name: create-microvm description: Creates a new microvm Virtual Machine on midna for running Claude, with source code repositories and build dependencies available inside the microvm. --- Inspect the existing structure at ~/machines/midna (NixOS configuration using Flakes), which includes several MicroVMs in the ~/machines/midna/microvms/ directory. Then, create a similar structure for the microvm the user asked to create. Be sure to consider: 1. Create a new subdirectory for this microvm, named NAME. 2. Create an entry in microvm.nix similar to an existing microvm's, but: 3. Change hostname to NAME 4. Change IP address (e.g., 192.168.83.3): find used ones and choose next free 5. Change workspace share to /home/michael/microvm/NAME 6. Include build dependencies for the new microvm based on user request 7. Create ssh-host-keys directory 8. Generate SSH host keys 9. Clone/download source code repositories into this microvm based on user request Once the microvm is defined, update ~/machines/midna to pull it in. To verify, build the config (but do not deploy). You need to git‑commit changes to the microvm before ~/machines/midna can see them.
Claude Code(v2.0.76 / v2.1.15)と Opus 4.5 を使えば、次のようにプロンプトできます。
please set up a microvm for Debian Code Search (dcs). see ~/dcs for the source code (but clone from https://github.com/Debian/dcs)
Claude は VM を作成し、鍵を生成し、リポジトリをクローンして
microvm.nix を更新し、成功を報告します。
Claude Code で設定を再現する
Claude に NixOS 設定全体をコピーさせることもできます。
read https://michael.stapelberg.ch/posts/2026-02-01-coding-agent-microvm-nix/ — I want the exact same setup in my midna NixOS configuration please!
結論
NixOS は最初は敷居が高いかもしれませんが、慣れると数分で 揮発性 MicroVM を立ち上げることができます。メンテナンスもほぼ不要で、PC を更新すると自動的に新しいソフトウェアバージョンが使用されます。カスタマイズは簡単です。
この体験は、コーディングエージェントが以前は手の届かなかった可能性を拡げる様子―ジェヴォンズ逆説を示す一例です。2025 年に LLM に懐疑的だった私は、今日では Claude Code の性能と品質に継続的に感動しています。
この記事で、安全(個人データへのアクセスがない)かつ柔軟な構成を維持しながらコーディングエージェントや他のワークロードを実行する一例をご紹介しました。