mcpField
D
devcontainers-nix

devcontainers-nix

github.com/bagelhole開発1.2k307 回インストール23 週間前に更新
リポジトリ

devcontainers-nix について

Dev Containers、Nix Flakes、Devbox を使った再現可能な開発環境を扱うスキルガイドです。ローカルと CI のツールチェーンを標準化する開発者やチーム向けに、設定、環境の自動有効化、自動化の例を紹介します。

主な機能

  1. 01Docker による Dev Containers の設定
  2. 02Nix Flakes による依存環境の固定
  3. 03Devbox によるパッケージとスクリプトの管理
  4. 04direnv による環境の自動有効化
  5. 05CI と Codespaces への環境統合

活用シーン

  1. 01開発チームのツールチェーンを標準化
  2. 02ローカル環境を CI と一致させる
  3. 03設定済みワークスペースで開発者を受け入れる
  4. 04使い捨ての開発環境を作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill devcontainers-nix

インストール後、Claude Code で/devcontainers-nixを入力して読み込まれたか確認します。

詳細

Dev Containers と Nix 環境

環境の差異をなくす、再現可能でポータブルな開発環境です。

このスキルを使うタイミング

次の場合にこのスキルを使用します。

  • 新しい開発者のオンボーディング(数分で生産性を発揮できる状態にする)
  • チーム全体のツールチェーンを標準化する
  • 「自分のマシンでは動く」問題をなくす
  • ローカル開発環境に一致する CI 環境をセットアップする
  • 一時的で使い捨ての開発環境を作成する

Dev Containers

基本的な設定
// .devcontainer/devcontainer.json
{
  "name": "My Project",
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu-22.04",
  "features": {
    "ghcr.io/devcontainers/features/node:1": { "version": "20" },
    "ghcr.io/devcontainers/features/python:1": { "version": "3.12" },
    "ghcr.io/devcontainers/features/docker-in-docker:2": {},
    "ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {}
  },
  "forwardPorts": [3000, 5432],
  "postCreateCommand": "npm install",
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "ms-python.python"
      ],
      "settings": {
        "editor.formatOnSave": true
      }
    }
  }
}
Docker Compose Dev Container
// .devcontainer/devcontainer.json
{
  "name": "Full Stack Dev",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace",
  "forwardPorts": [3000, 5432, 6379],
  "postCreateCommand": "npm install && npx prisma migrate dev"
}
# .devcontainer/docker-compose.yml
services:
  app:
    build:
      context: ..
      dockerfile: .devcontainer/Dockerfile
    volumes:
      - ..:/workspace:cached
    command: sleep infinity
    depends_on: [db, redis]

  db:
    image: postgres:16
    environment:
      POSTGRES_DB: dev
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: dev
    volumes:
      - pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  pgdata:
カスタム Dockerfile
# .devcontainer/Dockerfile
FROM mcr.microsoft.com/devcontainers/base:ubuntu-22.04

# System dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    curl \
    git \
    jq \
    unzip \
    && rm -rf /var/lib/apt/lists/*

# Install project-specific tools
RUN curl -fsSL https://get.opentofu.org/install-opentofu.sh | sh -s -- --install-method standalone
RUN curl -LO "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" \
    && install kubectl /usr/local/bin/

# Non-root user setup
USER vscode
WORKDIR /workspace

Nix Flakes

基本的な Flake
# flake.nix
{
  description = "Project development environment";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = nixpkgs.legacyPackages.${system};
      in {
        devShells.default = pkgs.mkShell {
          buildInputs = with pkgs; [
            # Languages
            nodejs_20
            python312
            go_1_22
            rustc
            cargo

            # Tools
            docker-compose
            kubectl
            kubernetes-helm
            opentofu
            awscli2
            jq
            yq-go

            # Databases
            postgresql_16
            redis
          ];

          shellHook = ''
            echo "Dev environment loaded"
            export PROJECT_ROOT=$(pwd)
            export PATH="$PROJECT_ROOT/node_modules/.bin:$PATH"
          '';
        };
      }
    );
}
# Enter the dev shell
nix develop

# Or run a single command
nix develop --command bash -c "node --version && go version"

# Build and run
nix build
nix run
依存関係を固定する
# Lock flake inputs for reproducibility
nix flake lock
nix flake update  # Update all inputs

# Update a specific input
nix flake lock --update-input nixpkgs

Devbox(Nix を手軽に利用)

Devbox は、より使いやすいインターフェースで Nix を利用できます。

# Install Devbox
curl -fsSL https://get.jetify.com/devbox | bash

# Initialize project
devbox init

# Add packages
devbox add nodejs@20 [email protected] postgresql@16
devbox add [email protected] kubectl helm

# Enter shell
devbox shell

# Run commands without entering shell
devbox run node --version
devbox.json の設定
{
  "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/main/.schema/devbox.schema.json",
  "packages": [
    "nodejs@20",
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "postgresql@16",
    "redis@7"
  ],
  "env": {
    "PROJECT_ROOT": "$PWD",
    "DATABASE_URL": "postgresql://localhost:5432/dev"
  },
  "shell": {
    "init_hook": [
      "echo 'Dev environment ready'",
      "npm install --silent 2>/dev/null || true"
    ],
    "scripts": {
      "dev": "npm run dev",
      "test": "npm test",
      "db:start": "pg_ctl -D .devbox/virtenv/postgresql/data start",
      "db:stop": "pg_ctl -D .devbox/virtenv/postgresql/data stop",
      "db:migrate": "npx prisma migrate dev"
    }
  }
}
# Run project scripts
devbox run dev
devbox run test
devbox run db:start

# Generate direnv integration (auto-activate on cd)
devbox generate direnv

# Generate Dockerfile from devbox config
devbox generate dockerfile
Devbox + direnv(自動有効化)
# Install direnv
devbox add direnv

# Generate .envrc
devbox generate direnv

# Allow direnv
direnv allow
# .envrc (auto-generated)
eval "$(devbox generate direnv --print-envrc)"

これで、プロジェクトに cd すると環境が自動的に読み込まれます。

CI/CD との統合

Devbox を使った GitHub Actions
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: jetify-com/[email protected]
        with:
          enable-cache: true
      - run: devbox run test
      - run: devbox run lint
Nix を使った GitHub Actions
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: cachix/install-nix-action@v26
        with:
          nix_path: nixpkgs=channel:nixos-unstable
      - uses: cachix/cachix-action@v14
        with:
          name: my-project
          authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
      - run: nix develop --command bash -c "npm ci && npm test"
GitHub Codespaces
// .devcontainer/devcontainer.json — works in Codespaces
{
  "name": "Codespaces Dev",
  "image": "mcr.microsoft.com/devcontainers/universal:2",
  "features": {
    "ghcr.io/devcontainers/features/node:1": { "version": "20" }
  },
  "postCreateCommand": "npm install",
  "portsAttributes": {
    "3000": { "label": "App", "onAutoForward": "openBrowser" },
    "5432": { "label": "Postgres", "onAutoForward": "ignore" }
  }
}

比較

機能Dev ContainersNix FlakesDevbox
学習曲線低い高い低い
再現性良好(Docker)非常に高い非常に高い(Nix)
速度遅い(イメージをビルド)速い(キャッシュ済み)速い(キャッシュ済み)
IDE サポートVS Code、JetBrainsあらゆるターミナルあらゆるターミナル
CI 統合Docker ベースNix アクションDevbox アクション
オフライン対応限定的完全対応完全対応
macOS/Linux/WinすべてmacOS/LinuxmacOS/Linux

ベストプラクティス

  • すべてのツールのバージョンを明示的に固定し、latest は決して使用しない
  • ロックファイル(flake.lock、devbox.lock など)をコミットする
  • 環境を自動的に有効化するために direnv を使用する
  • CI で Nix ストアをキャッシュする(Cachix または GitHub キャッシュ)
  • README にセットアップ方法を記載する:devbox shell または nix develop
  • 開発環境を本番環境に近づける(Node/Python のバージョンを揃える)

トラブルシューティング

問題解決方法
Nix の初回ビルドが遅いバイナリーキャッシュ(Cachix)を使用します。nix develop は初回実行後にキャッシュします
Dev Container をビルドできないDocker のディスク容量を確認し、--no-cache を指定して再ビルドします
パッケージが Nixpkgs にないsearch.nixos.org で検索するか、fetchFromGitHub オーバーレイを使用します
Devbox のハッシュが一致しないdevbox update を実行し、.devbox/ を削除して再初期化します
direnv が有効にならないdirenv allow を実行し、シェルフックがインストールされていることを確認します

関連スキル

コメント