roji(路地)は、ローカル開発環境専用のシンプルなリバースプロキシ。Docker Composeのサービスを自動検出し、*.localhost でHTTPSアクセスを可能にする。
"本番は高速道路(Traefik)、開発は路地裏(roji)で"
- CLAUDE.md: 日本語(開発者向け内部ドキュメント)
- その他すべて: 英語(README.md、CONTRIBUTING.md、ソースコード、コメント)
- Traefikより軽量・シンプル: ローカル開発に特化することで複雑な機能を省略
- ネットワークベースの自動検出: 共有ネットワークに接続 = プロキシ対象
- ゼロコンフィグ志向: ラベルなしでも動作、必要に応じてラベルでカスタマイズ
- 言語: Go 1.25+
- 主要ライブラリ:
github.com/docker/docker/client- Docker APInet/http/httputil- ReverseProxy(標準ライブラリ)crypto/x509,crypto/tls- 証明書生成(標準ライブラリ)
- フロントエンド: Petite Vue(~6KB、ビルド不要)
- 配布: Docker イメージ (ghcr.io/kan/roji)
┌─────────────────────────────────────────────────────────────┐
│ roji │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Docker │ │ Route │ │ HTTP/HTTPS │ │
│ │ Watcher │→ │ Manager │→ │ Reverse Proxy │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
│ ↓ ↓ ↑ │
│ Docker Socket SSE Broadcast :80 / :443 │
└─────────────────────────────────────────────────────────────┘
roji/
├── cmd/roji/
│ ├── main.go # エントリーポイント
│ └── cmd/ # Cobraコマンド(root, routes, version, health, server, config, doctor, ca)
├── docker/
│ ├── client.go # Docker API ラッパー
│ ├── compose.go # Docker Compose CLI実行(up/down/restart/logs)
│ └── watcher.go # Events 監視
├── proxy/
│ ├── handler.go # ReverseProxy 実装
│ ├── router.go # ルーティング + SSE Pub/Sub
│ └── templates/ # HTML/CSS/JS(embed.FS)
├── certgen/
│ ├── generator.go # TLS証明書生成
│ ├── installer.go # CAInstaller インターフェース
│ ├── installer_darwin.go # macOS Keychain対応
│ ├── installer_linux.go # Linux (Debian/RHEL) 対応
│ ├── installer_windows.go # Windows certutil対応
│ └── installer_wsl.go # WSL→Windows対応
├── config/
│ ├── labels.go # ラベルパーサー
│ ├── paths.go # XDGパスユーティリティ
│ └── settings.go # 設定ファイル読み込み
├── doctor/
│ ├── check.go # Doctor インターフェース
│ └── checks/ # 各チェック実装
├── test/ # インテグレーション/E2Eテスト
├── Dockerfile # マルチステージビルド
├── docker-compose.yml # 本番用
├── docker-compose.dev.yml # 開発用(Air ホットリロード)
└── install.sh # ワンライナーインストール
| ラベル | 説明 | デフォルト |
|---|---|---|
roji.host |
カスタムホスト名 | {service}.localhost |
roji.port |
ターゲットポート | 最初のEXPOSEポート |
roji.path |
パスプレフィックス | なし |
roji.mock.{METHOD}.{PATH} |
モックレスポンス | なし |
roji.mock.status.{METHOD}.{PATH} |
モックステータスコード | 200 |
roji.auth.basic.user |
BASIC認証ユーザー名 | なし |
roji.auth.basic.pass |
BASIC認証パスワード | なし |
roji.auth.basic.realm |
BASIC認証レルム | Restricted |
roji.self |
予約済み: コンテナをルーティング対象から除外(内部使用) | なし |
| 環境変数 | 説明 | デフォルト (Native Mode) |
|---|---|---|
ROJI_NETWORK |
監視するDockerネットワーク(カンマ区切り) | roji |
ROJI_DOMAIN |
ベースドメイン | dev.localhost |
ROJI_CERTS_DIR |
証明書ディレクトリ | ~/.local/share/roji/certs |
ROJI_DATA_DIR |
データディレクトリ | ~/.local/share/roji |
ROJI_DASHBOARD |
ダッシュボードホスト名 | roji.{domain} |
ROJI_LOG_LEVEL |
ログレベル | info |
ROJI_HTTP_PORT |
HTTPポート | 80 |
ROJI_HTTPS_PORT |
HTTPSポート | 443 |
ROJI_AUTO_CERT |
証明書自動生成 | true |
| エンドポイント | 説明 |
|---|---|
/_api/routes |
ルート一覧(JSON) |
/_api/projects |
プロジェクト一覧 |
/_api/events |
SSEストリーム(ルート更新) |
/_api/logs |
SSEストリーム(リクエストログ) |
/_api/logs/export |
ログエクスポート(JSON/CSV) |
/_api/health |
ヘルスチェック |
/_api/status |
詳細ステータス(証明書期限等) |
/_api/containers/{id}/restart |
コンテナ再起動 |
/_api/projects/{name}/up |
プロジェクト起動(docker compose up -d) |
/_api/projects/{name}/down |
プロジェクト停止(docker compose down) |
/_api/projects/{name}/restart |
プロジェクト再起動(docker compose restart) |
/_api/projects/{name}/logs |
プロジェクトログ(SSEストリーム) |
/_api/projects/{name}/delete |
プロジェクト履歴削除 |
/_api/config/reload |
設定ファイル再読み込み(静的サイト更新) |
- ネットワークベースの自動検出(Docker Events監視)
- ホスト名/パスベースルーティング
- TLS証明書の自動生成(CA + ワイルドカード)
- HTTP → HTTPS リダイレクト
- WebSocketプロキシ(
Upgrade: websocketヘッダー検出、双方向通信) - gRPCプロキシ(HTTP/2、
Content-Type: application/grpcで自動検出) - BASIC認証(Dockerラベル / 設定ファイルで設定)
- リアルタイム更新(SSE + Petite Vue)
- プロジェクト履歴・クイックアクセス
- Docker Compose操作(Start/Stop/Restartボタン)
- リクエストログビューア(フィルタリング対応)
- ログエクスポート(JSON/CSV形式)
- コンテナ再起動ボタン
- ルート一覧からプロジェクト停止ボタン
- 非アクティブプロジェクトのURL直接アクセス時にStartボタン表示
- ダークモード(システム設定連動)
- 設定ミス警告表示
- 認証バッジ表示(🔒 auth)
- リクエストモック(ラベルでレスポンス定義)
- 複数ネットワーク対応
- ブラウザ通知
- 静的ファイルホスティング(httpd機能)
- 設定ファイル対応(
~/.config/roji/config.yaml) - XDG Base Directory準拠のパス管理
roji configコマンド(show/path/init/edit)roji doctorコマンド(環境診断 + 自動修復)roji caコマンド(install/uninstall/export/status)- CA証明書のシステムインストール(macOS/Linux/Windows対応)
- 設定の優先順位: CLI > 環境変数 > 設定ファイル > デフォルト
roji serviceコマンド(install/uninstall/start/stop/restart/status)- サービス登録(Linux systemd / macOS launchd / Windows NSSM)
- ワンライナーインストーラー刷新(Native Mode対応)
- GitHub Releasesからバイナリダウンロード
- 対話式インストール先選択(
~/.local/bin//usr/local/bin) - Docker Mode検出 → 移行フロー
- 自動セットアップ(doctor --fix, ca install, service install)
- 旧Docker版は
install-docker.shとして維持
- 設定ファイルバリデーション(不明キー警告、型チェック)
- Docker Compose操作(ダッシュボード/APIからup/down/restart/logs)
- ワンライナーインストール(Native Mode / アップグレード対応)
- GoReleaser v2(マルチプラットフォーム)
- Distrolessイメージ
- セキュリティスキャン(Trivy, govulncheck)
- インテグレーション/E2Eテスト
-
ドキュメント更新
# README.md: install.sh URLを新バージョンに更新(2箇所) # CHANGELOG.md: 新バージョンの変更内容を追加
-
コミット & タグ
git add README.md CHANGELOG.md git commit -m "Prepare for vX.Y.Z release" git tag -a vX.Y.Z -m "Release vX.Y.Z: [主要機能]" git push origin main git push origin vX.Y.Z
-
確認
- GitHub Actions → GitHub Release → Docker Image
| Version | テーマ | 主要機能 |
|---|---|---|
| v0.7.0 | プロトコル拡張 | WebSocket対応、gRPC対応、ログエクスポート |
| v0.8.0 | Native Mode | 単体バイナリ化、roji doctor、CA自動インストール |
| v0.9.0 | 運用強化 | サービス登録、Docker Compose操作、httpd機能、BASIC認証 |
| v1.0.0 | 安定版 | Docker Mode廃止、Homebrew対応、i18n、ドキュメント整備 |
-
WebSocket対応
- WebSocket接続のプロキシ(
Upgrade: websocket) - フロントエンド開発での必須機能
- 既存のReverseProxyにWebSocketハンドラー追加
- WebSocket接続のプロキシ(
-
gRPC対応
- HTTP/2 + gRPCプロキシ(
Content-Type: application/grpcで自動検出) - HTTPSサーバーでHTTP/2を有効化(gRPCに必須)
- ※ gRPC-Web対応は要望があれば検討
- HTTP/2 + gRPCプロキシ(
-
ログのエクスポート
- リクエストログをJSON/CSVでダウンロード(
/_api/logs/export) - ダッシュボードにエクスポートボタン追加
- ホスト/サービス/メソッド/期間でフィルタリング
- リクエストログをJSON/CSVでダウンロード(
v0.8.0以降はNative Modeを主とする。Docker Modeは1.0.0で廃止予定。
ホスト上で直接動作し、Docker環境を外部から操作する形態に移行。
v0.8.0 Architecture (Native Mode)
┌─────────────────────────────────────────────────────────────────┐
│ roji (Native Mode) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Docker │ │ Route │ │ HTTP/HTTPS │ │
│ │ Watcher │→ │ Manager │→ │ Reverse Proxy │ │
│ └──────────────┘ └──────────────┘ └──────────────────┘ │
│ ↓ ↓ ↑ │
│ Docker Socket SSE Broadcast Host :80/:443 │
│ (/var/run/...) (特権必要) │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Doctor │ │ CA │ │
│ │ Command │ │ Installer │ │
│ └──────────────┘ └──────────────┘ │
│ 環境チェック OS Trust Store │
└─────────────────────────────────────────────────────────────────┘
- 設定は以下の優先順位で適用(後が優先):
- デフォルト値
- 設定ファイル(
~/.config/roji/config.yaml) - 環境変数(
ROJI_*) - コマンドライン引数(
--network等)
- 設定ファイル対応
# ~/.config/roji/config.yaml
network: roji
domain: dev.localhost
certs_dir: ~/.local/share/roji/certs
data_dir: ~/.local/share/roji
dashboard: dev.localhost
log_level: info
http_port: 80
https_port: 443
auto_cert: true- config コマンド
roji config show- 現在の設定を表示roji config path- 設定ファイルパスを表示roji config init- デフォルト設定ファイルを作成roji config edit- エディタで設定を編集
- doctor コマンド
$ roji doctor
✓ Docker daemon is running [pass]
Docker daemon is running
✓ Docker socket is accessible [pass]
/var/run/docker.sock
✗ Docker network [fail]
Network(s) not found: roji
Run 'docker network create roji' or use 'roji doctor --fix'
✓ Port availability [pass]
Ports 80, 443 are available
...
Run 'roji doctor --fix' to auto-fix where possible
チェック項目:
- Docker daemon稼働
- Docker socketアクセス権
- 指定ネットワークの存在(修復可能)
- ポート80/443の利用可能性
- CA証明書の存在(修復可能)
- CA証明書のシステムインストール状態(修復可能、WSLではWindows側も確認)
- サーバー証明書の有効期限(修復可能)
- DNS解決(*.localhost)
フラグ:
--fix- 修復可能な問題を自動修復--json- JSON形式で出力
- ca コマンド
新コマンド:
roji ca status- CA証明書のインストール状態を確認roji ca install- CA証明書をシステムにインストールroji ca uninstall- CA証明書を削除roji ca export [path]- CA証明書をエクスポート(PEM/DER形式)
フラグ:
--user- ユーザーストアにインストール(macOS/Windows、sudo不要)--firefox- Firefoxにもインストール(Linux、nss-tools必要)--windows- WSLからWindows証明書ストアにインストール(常にユーザーストア)--force- 同名の証明書が存在しても強制インストール
プラットフォーム別実装:
| プラットフォーム | 方法 | 実装 |
|---|---|---|
| macOS | Keychain | security add-trusted-cert |
| Linux (Debian系) | update-ca-certificates | /usr/local/share/ca-certificates/ |
| Linux (RHEL系) | update-ca-trust | /etc/pki/ca-trust/source/anchors/ |
| Windows | certutil | certutil -addstore -f "ROOT" |
| WSL → Windows | certutil.exe | ユーザーストア(CurrentUser\ROOT)に登録 |
ログファイル:
- サービスモード時はログをファイルにも出力
- 場所:
- Linux/WSL:
~/.local/share/roji/roji.log - macOS:
~/Library/Logs/roji.log(launchd経由の場合)
- Linux/WSL:
- ログローテーション: 10MB超過時に自動ローテート
新コマンド:
roji log- ログをリアルタイム表示(tail -f相当)roji log -n 100- 最新100行を表示roji log --no-follow- 現在のログを表示して終了
新コマンド:
roji service install- サービス登録roji service uninstall- サービス削除roji service start/stop/restart- サービス制御roji service status- 状態確認
プラットフォーム別:
| プラットフォーム | サービス管理 | 設定場所 | 状態 |
|---|---|---|---|
| Linux | systemd | /etc/systemd/system/roji.service |
✅ 実装済み |
| macOS | launchd | ~/Library/LaunchAgents/com.roji.agent.plist |
✅ 実装済み |
| Windows | NSSM | Windows Service経由 | ✅ 実装済み |
Windows版の注意:
- NSSMのインストールが必要
- 管理者権限で実行する必要あり
- ログは
%USERPROFILE%\.local\share\roji\roji.logに出力
ダッシュボード/APIからdocker-composeプロジェクトを操作:
| API | 説明 |
|---|---|
POST /_api/projects/{name}/up |
docker compose up -d |
POST /_api/projects/{name}/down |
docker compose down |
POST /_api/projects/{name}/restart |
全サービス再起動 |
GET /_api/projects/{name}/logs |
ログ取得(SSE) |
実装:
docker/compose.go:exec.CommandContextでdocker composeコマンドを実行project.Storeに保存済みのworking_dirとconfig_filesを使用- カンマ区切りの
config_filesを-fフラグに展開 - プロジェクト名バリデーション(
[a-zA-Z0-9_.\-]+のみ許可) - CORS対応(非ダッシュボードホストからのAPI呼び出し)
ダッシュボード連携:
- アクティブプロジェクト: Restart / Stop ボタン
- 非アクティブプロジェクト: Start ボタン(+ 既存のCopy start command)
- ルート一覧: プロジェクト所属のルートにStopボタン
- 確認ダイアログ付き(既存のコンテナ再起動と同じUIパターン)
- Not Foundページ: ホスト名から非アクティブプロジェクトを自動検出し、Startボタンを表示
設定ファイルで定義:
# ~/.config/roji/config.yaml
static_sites:
- host: docs # -> docs.{ROJI_DOMAIN} (例: docs.dev.localhost)
root: ~/projects/docs/build
# index: true # デフォルト: ディレクトリ一覧有効
- host: private.example.com # ドットを含む場合はFQDNとして使用
root: /var/www/private
index: false # ディレクトリ一覧を無効化機能:
- ホスト名解決: ドット(
.)なし →{host}.{ROJI_DOMAIN}に展開 - ディレクトリ一覧:
index: true(デフォルト)で有効、Apache/nginx風の一覧表示 - index.html自動配信: ディレクトリアクセス時
- ディレクトリトラバーサル防止:
path.Clean()+ root内チェック - ダークモード対応: システム設定連動
- ダッシュボード連携: 設定再読み込み、index状態表示
ダッシュボード機能:
- 「Reload Config」ボタンで設定ファイルを再読み込み(
/_api/config/reload) - 静的サイトのindex状態を📋(有効)/🔒(無効)で表示
未実装(後続で検討):
roji serveコマンド(一時的なホスティング)
特定ルートにBASIC認証を設定可能。
Docker Composeラベルで設定:
# docker-compose.yml
services:
admin:
labels:
- "roji.auth.basic.user=admin"
- "roji.auth.basic.pass=secret"
- "roji.auth.basic.realm=Admin Area" # 任意設定ファイルで静的サイトに適用:
# ~/.config/roji/config.yaml
static_sites:
- host: docs.dev.localhost
root: ~/projects/docs/build
auth:
basic:
user: admin
pass: secret
realm: Documentation # 任意実装方針:
- 標準ライブラリのみで実装(
net/http) - パスワードは平文(ローカル開発用途のため)
- 401レスポンス時に
WWW-Authenticateヘッダー付与
新 install.sh(Native Mode対応):
curl -fsSL https://raw.githubusercontent.com/kan/roji/v0.9.0/install.sh | bash処理フロー:
- OS/Arch検出(Linux/macOS, x86_64/arm64)
- 既存インストール検出
- Docker Mode → 移行を促す(コンテナ停止、証明書バックアップ)
- Native Mode → バージョン比較してアップグレード
- 対話式インストール先選択
~/.local/bin(デフォルト、sudo不要でインストール)/usr/local/bin(グローバル、sudoでインストール)
- GitHub Releasesからバイナリダウンロード
sudo roji doctor --fixsudo roji ca install(WSLでは--windowsも)sudo roji service install && start
オプション:
--local/--global- インストール先指定--upgrade- アップグレード確認スキップ--migrate- Docker Mode移行確認スキップ--no-service- サービス登録スキップ
旧版:
install-docker.shとして維持(Docker Mode用)
設定読み込み時およびdoctorコマンドで包括的なバリデーションを実行。
チェック内容:
- 不明なキーの検出(タイポ検出)
- 値の型チェック(string/int/bool/array/object)
- 必須フィールドの欠落(static_sitesのhost/root等)
表示:
- 設定読み込み時:
slog.Warnで警告出力 roji doctor: Config file validationチェックとして表示
-
install-docker.shを削除 - README.md から「Docker Mode (Legacy)」セクションを削除
-
docker-compose.ymlのROJI_DOMAINデフォルトをdev.localhostに統一 - Dockerfile、docker-compose.yml、docker-compose.dev.yml は開発・テスト用として維持
- docker-compose.yml のコメントに「開発・テスト用」と明記
- Recent Projects の管理(削除)機能
- 不要になったプロジェクト履歴をダッシュボードから削除
DELETE /_api/projects/{name}/deleteエンドポイント追加- ダッシュボードに削除ボタン追加(確認ダイアログ付き)
project.Storeから該当プロジェクトを削除
-
ROJI_DOMAINのデフォルト値を全環境でdev.localhostに統一- docker-compose.yml が
localhostを使用していた不整合を解消
- docker-compose.yml が
-
roji.selfラベルをドキュメント化(内部使用ラベルとして公式化) - 環境変数・設定パス・APIは現状維持(変更不要と確認済み)
- Homebrew対応(macOS)
- Formulaの作成(GoReleaserの
brewsセクション利用) brew install kan/roji/rojiでインストール可能に
- Formulaの作成(GoReleaserの
- APT/RPMパッケージは検討のみ(v1.x以降)
- ダッシュボード (Web UI)
- メッセージの外部化(JSON / 埋め込みリソース)
- ブラウザの
Accept-Languageヘッダーで言語自動検出 - 日本語リソース追加
- CLIコマンド
- メッセージ・ヘルプテキストの外部化
LANG環境変数で言語自動検出- 日本語リソース追加
- インストーラー (install.sh)
- メッセージの日本語対応
- README.md 全面改訂
- Docker Mode関連の記述を削除・整理
- Native Mode前提の記述に統一
- 機能一覧を最新状態に更新
- Getting Started ガイド(新規作成)
- インストールから初めてのサービス公開まで
- 設定ファイルの使い方
- よくある構成例
- トラブルシューティングガイド(拡充)
- 既存セクションの拡充
- プラットフォーム別の注意事項(WSL、macOS、Linux)
roji doctorとの連携説明
- 破壊的変更の整理 + Docker Mode廃止(影響範囲が広いため最初に)
- ダッシュボード機能強化(Recent Projects削除機能)
- パッケージマネージャー対応(Homebrew Formula)
- 多言語対応 (i18n)
- ドキュメント整備(最後にまとめて更新)
| 機能 | 説明 | 優先度 |
|---|---|---|
| VS Code拡張 | ルート一覧、ブラウザ起動、ログ連携(API安定後) | 高 |
| Docker Desktop ネットワーク対応 | macOS/Windows NativeのDocker Desktopではコンテナ内部IPへの直接アクセス不可(Linux VM経由のため)。ポートフォワーディング自動化やhost.docker.internal経由のルーティングなど、Docker Desktop固有のネットワーク制約への対応。※WSL2+Docker Desktopは既に動作 |
中 |
| 簡易daemon化 | roji startでバックグラウンド起動(サービス登録不要)、PID管理 |
中 |
| ルート別ヘルスチェック | 各バックエンドの死活監視、ダッシュボード表示 | 中 |
| レスポンスタイム統計 | P50/P95/P99レイテンシ、ダッシュボードでグラフ表示 | 中 |
| プラグインシステム | カスタムミドルウェア、認証プロキシ等の拡張 | 低 |
- URL: https://roji-proxy.dev
- 技術: Hugo + Doks テーマ、GitHub Pages
- ソース:
website/ディレクトリ(モノレポ) - 多言語: EN / JA
- デプロイ: GitHub Actions(
mainブランチのwebsite/**変更時に自動デプロイ)
# ユニットテスト
go test -v ./...
# インテグレーションテスト
cd test && go test -v -tags=integration ./...
# E2Eテスト
cd test && go test -v -tags=e2e ./...GoReleaser v2を使用。設定変更時は必ず検証を実行:
# インストール(未導入の場合)
go install github.com/goreleaser/goreleaser/v2@latest
# 設定検証
goreleaser check
# ローカルでスナップショットビルド(リリースなし)
goreleaser release --snapshot --cleanv2の主な特徴:
version: 2ヘッダーが必須dockers_v2: 単一設定でマルチプラットフォームイメージ+マニフェスト生成- Dockerfileで
ARG TARGETPLATFORMを使用し${TARGETPLATFORM}/binaryからコピー
# 開発サーバー起動(ホットリロード)
docker compose -f docker-compose.dev.yml up
# テストサービス起動
cd test && docker compose up -d
# 動作確認
curl -k https://web.dev.localhost- Docker Engine API
- Go httputil.ReverseProxy
- Petite Vue
- VS Code Extension API
- Hugo - Go製静的サイトジェネレーター
- Doks - Hugo用ドキュメントテーマ