その他

新しいItemの作成

Items

最新コメント

vscodeのdevcontainerでCodexを使うのを今は見送りにした理由

wakairo @wakairo

2026年9月現在では、以下のようにdev containers内でcodexを動かす方法についてドキュメントが存在しています。 ですので、vscodeのdevcontainerでCodexを使うのは、現在では現実的な選択肢のようです。

https://learn.chatgpt.com/docs/agent-approvals-security#run-codex-in-dev-containers

0
Raw
https://www.techtips.page/ja/comments/1273

PmRails v2.0 / DkRails v2.0をリリースしました

wakairo @wakairo

Railsの開発環境をコンテナ内に作るための PmRails v2.0 をリリースしました。

また、PmRailsと同等の開発スタイルをDockerで利用できる DkRails も新しく公開しました。

どちらも、ホスト環境にRubyやRailsをインストールせずにRailsを開発することを目的としたツールです。

PmRails v2.0

PmRails v1では、RailsをPodmanコンテナ内で実行するための比較的小さなツールとしてスタートしました。

v2では機能を大幅に拡張し、Railsアプリの新規作成から日常的な開発まで、より一通りの作業を扱えるようになりました。

主に次の3つの使い方ができます。

  1. rails newだけをコンテナ内で実行する
  2. 単一のRailsコンテナで開発する
  3. Composeを使ってRails、DB、Seleniumなどを組み合わせて開発する

既存のRailsプロジェクトに対しては、pmrails-initで標準的な設定ファイルを生成できます。

Compose環境ではSQLite3に加え、PostgreSQL、MySQL、MariaDB系の構成や、Seleniumを使ったsystem testにも対応しています。

独自のDockerfileやCompose設定も利用できるため、簡単な構成から始めて、必要に応じてプロジェクト固有の環境へ拡張できます。

詳しい変更内容は以下にあります。

PmRails v2.0.0 Release

Docker版のDkRailsも公開

これまでPmRailsはPodmanを前提としていました。

今回、同じ考え方とほぼ同じ操作体系をDockerで利用できる DkRails を公開しました。

たとえば、

pmrails-cmpexe bin/rails test

に対応するDkRailsのコマンドは、

dkrails-cmpexe bin/rails test

です。

そのため、

PodmanならPmRails、DockerならDkRails

という形で、利用するコンテナ環境に応じて選べます。

DkRails v2.0.0 Release

AIを使った開発にも

最近では、Codexなどのcoding agentにコードの編集だけでなく、テストやRailsコマンドの実行まで任せる機会が増えてきました。

このとき、AIにホスト上のコマンド実行を広く許可するのではなく、Railsの実行をPmRails/DkRails経由に寄せるという使い方ができます。

たとえばCodexでは、.codex/rules/default.rulesに次のようなルールを書くことで、よく使うRailsコマンドだけを自動許可できます。

prefix_rule(
    pattern = [
        "pmrails-cmpexe",
        "bin/rails",
        ["test", "test:system", "routes", "zeitwerk:check"],
    ],
    decision = "allow",
    justification = "Allow common Rails development commands through PmRails.",
)

これにより、AIにはテストなどの日常的なRails操作を任せながら、その実行環境をコンテナ側に置くことができます。

一方、runnerconsole、任意のRake taskなど、より広い操作能力を持つコマンドは、この例では自動許可していません。

もちろん、コンテナは完全なセキュリティsandboxではありません。bind mountされたファイルや、コンテナからアクセス可能なDB・ネットワークなどには影響できます。

それでも、

RailsはAIにかなり自由に触らせる。ただし、アプリケーションの実行場所はコンテナに寄せる。

という境界を自然に作れるのは、AIを使った開発でも便利だと感じています。

PmRails/DkRailsはAI専用のツールではありませんが、もともとRailsの実行環境をホストから分離するために作っていたことが、AI coding agentを使う上でも役立つ形になりました。

Links

0
Raw
https://www.techtips.page/ja/comments/1238
💡2
❤️2
🎉1

シェルで複数ファイルに対して一括して文字列置換処理を行うコマンド

wakairo @wakairo

例として、シェルでgitで管理している全ての.cファイル内にあるabcをdefに置換する一行の書き方は以下の通りです。

git ls-files -z -- '*.c' | xargs -0 -r sed -i 's/abc/def/g'
  • -z-0 により、空白や改行を含むファイル名にも対応します。このようなファイル名がない場合には、 -z-0 の両方のオプションを外してOKです。
  • -r は対象ファイルが0件なら sed を実行しません(GNU xargs)。

なお、macOS/BSD系の sed では次のようにするらしいです。

git ls-files -z -- '*.c' | xargs -0 sed -i '' 's/abc/def/g'
0
Raw
https://www.techtips.page/ja/comments/1205

`git diff --check`のHEAD全体への適用方法とempty treeのハッシュ値

wakairo @wakairo

git diff --checkは、(バイナリファイルを除く)diffの内容にtrailing whitespace等が無いかをチェックできるコマンドです。

チェック対象を通常の差分ではなく、HEADのファイル全体にしたい場合は、以下のように実行します。

git diff --check "$(git hash-object -t tree /dev/null)" HEAD

HEADのファイル全体をチェックする仕組みと「empty treeのハッシュ値」

上述のコマンドでは、「何のファイルもないtreeのハッシュ値」とHEADの間でdiffを取ることで、 diffの結果がHEADのファイルの内容全体となり、それがチェックされるようにしています。

では「何のファイルもないtreeのハッシュ値」つまり「empty treeのハッシュ値」をどう求めれば良いかと言いますと、 git hash-object -t tree /dev/nullとなります

$ git hash-object -t tree /dev/null
4b825dc642cb6eb9a060e54bf8d69288fbee4904

ちなみに「empty treeのハッシュ値」は、上記のように定数値ではあるのですが、 gitで用いるハッシュの計算方法(アルゴリズムなど)が変わればこの定数値も変わりますので、 定数として持たずgit hash-objectに計算させた方が安全です。

0
Raw
https://www.techtips.page/ja/comments/1176

Docker Composeのサービス名にappやdevを使うとSeleniumのHTTP接続がSSLエラーになる原因と対策

wakairo @wakairo

要点

Docker Compose の compose.yaml でサービス名を付ける際は、HTTP での接続先となるコンテナのサービス名には appdev といったトップレベルドメイン(TLD)として実在する文字列を使わないほうが安全です。

具体的な対策

HTTP で接続するサービス(コンテナ)には、ハイフン(-)を用いて複数の単語を組み合わせた名前をつけるのが、簡単な解決策です。

  • 避けるべきサービス名の例app, dev
  • 推奨されるサービス名の例rails-app, web-server

なぜエラーになるのか

Docker Compose のネットワーク内では、サービス名で名前解決をして他コンテナへアクセスできます。そのため、Selenium コンテナ内のブラウザから http://app/ のようにアクセスする設定にすることがあります。

しかしブラウザは、その app を Docker 内部の名前としてではなく、通常のホスト名として扱います。 appdev は実在の TLD であり、しかも HSTS(HTTP Strict Transport Security)を強制する対象なので、ブラウザは http://app/https://app/ に書き換えます。 接続先が HTTPS 非対応なら、結果として ERR_SSL_PROTOCOL_ERRORAre you trying to open an SSL connection to a non-SSL Puma? のようなエラーになります。

一方、rails-app のように、TLD と一致しない名前にすれば、HSTS 強制の対象から外れ、HTTPS に書き換えられないため、エラーを防ぐことができます。

背景:何が起きているか

Docker の compose.yamlservices で定義したサービス名は、Docker ネットワーク内で他コンテナへアクセスする際のホスト名として使えます。ここでのホスト名とは、http://example.com/example.com に当たります。

サービス名にドット(.)が含まれていない場合、単一ラベルのホスト名となり、ブラウザはその名前を TLD として扱います。例えば、app というサービス名は、app という TLD のみからなるホスト名として認識されます。

TLD のみのホスト名のうち、appdev は HSTS 強制の対象となっており、HSTS プレロードリストなどの仕組みにより、HTTPS 接続が強制されます。そのため、http://app/ という HTTP での接続になるよう設定しても、ブラウザは強制的に https://app/ という HTTPS での接続へと書き換えて接続しようとします。

結果、appdev のような HSTS が強制される名前を持つサービス(コンテナ)に対して、Selenium コンテナ内のブラウザは、HTTP で接続するよう設定されていても、HTTPS で接続してしまいます。 さらに、接続される側のコンテナが HTTPS に対応していない場合、接続がエラーとなります。

このように、E2E テストやシステムテストでは「ブラウザがどう解釈するか」は無視できない事項です。 コンテナ間疎通の都合だけで名前を決めるのではなく、ブラウザが特殊な扱いをする名前ではないか、という観点も持っておくとトラブルを減らせます。

注意点

  • TLD、及び、HSTS が強制されるホスト名は追加が続いています。そのため、将来のトラブルを防ぐ観点では、現状でトラブルになる名前だけでなく、今後トラブルになりそうな名前全般を避けたほうが無難だと考えられます。
  • HSTS はホスト名ベースで効き、ポート番号では回避できません。つまり http://app:3000/ のような URL でもエラーになり得ます。
  • ホスト名にドットを含めることは、本件の SSL エラーの確実な回避策とはなりません。なぜなら、HSTS 強制の対象となっているホスト名としては、TLD のみのホスト名だけではなく、facebook.comwww.amazon.com といったドットを含むホスト名も多数存在するためです。

接続エラーに遭遇した状況

compose.yaml において、selenium/standalone-chromium イメージの Selenium コンテナからサービス名が app のコンテナへ HTTP で接続する設定をしたところ、以下のエラーが発生しました。

2026-03-25 05:37:53 +0000 HTTP parse error, malformed request: #<Puma::HttpParserError: Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?>
[Screenshot Image]: /x/tmp/screenshots/failures_test_should_destroy_Article.png
E

Error:
ArticlesTest#test_should_destroy_Article:
Selenium::WebDriver::Error::UnknownError: unknown error: net::ERR_SSL_PROTOCOL_ERROR
  (Session info: chrome=145.0.7632.109)
    test/system/articles_test.rb:38:in 'block in <class:ArticlesTest>'

なお、サービス名を app から rails-app に変更したところ、無事意図したとおりに動くようになりました。 HSTS 強制の対象となる TLD(app)との一致を回避した結果、ブラウザが HTTPS へ強制的に書き換えなくなったためと考えられます。

参考資料

0
Raw
https://www.techtips.page/ja/comments/1139
❤️1

PmRails v1.1.0 をリリースしました。

wakairo @wakairo

リリースの概要

  • 新コマンド pmrails-new-plus : アプリの作成・gem のインストール・.gitignore の更新を1ステップで自動化します。
  • プロジェクトローカルなruntimeディレクトリ .pmrails/var/ : gem・キャッシュ・設定ファイルなどをプロジェクトごとに隔離して管理するようになりました。
  • SELinux / Fedora Immutable サポート : 全コマンドに Podmanの --userns=keep-id オプションを追加しました。

アップデート時の注意:ランタイムディレクトリ変更のため、pmbundle installの再実行が必要です。

リリースノートと変更履歴はGitHubで確認できます: https://github.com/wakairo/pmrails/releases/tag/v1.1.0

0
Raw
https://www.techtips.page/ja/comments/1123
🎉1
❤️1

vscodeのdevcontainerでCodexを使うのを今は見送りにした理由

wakairo @wakairo

Codex(OpenAIのコーディング・エージェント)をdevcontainer(開発用コンテナ)の中に閉じ込めて動かすのは、 セキュリティの確保もできて、なかなか良いアイデアなのではと思いました。 ところが、vscodeで実際に試してみたところ、Codexのセキュリティの仕組みと絡んで、不都合な挙動があったので、 このやり方は公式にサポートされるまでは様子見が良いかなと今は思っています。

確認したこと

まずvscodeでdevcontainerを起動しました。 設定ファイル.devcontainer/devcontainer.jsonの中身は以下の通りです。

{
        "name": "Ruby",
        "image": "mcr.microsoft.com/devcontainers/ruby:3-3.4"
}

次に、Codex拡張をインストールしました。 その次に、Codexにソースファイルの一部を変更する指示を出したところ、 apply_patchが上手くいかないのでsedなどを代わりに使うという返答で、 変更前後のdiffが見づらい形になりました。

なお、devcontainerの設定で指定するimageは以下の2つも試しましたが、 同じ現象に遭遇しましたので、特定のイメージでのみ発生する現象ではありません。

  • ruby:3.4(Rubyの公式イメージ)
  • ghcr.io/openai/codex-universal:latest(OpenAIが公開している参考Dockerイメージ)

apply_patchが失敗する背景

Codexが言うには、apply_patchはbwrapという一種のコンテナの中で動かす仕組みらしく、 devcontainerというコンテナの中でbwrapというコンテナを動かす、 つまり、コンテナの中でコンテナを動かすのに失敗しているらしいです。 具体的には、devcontainerの中でbwrapのコンテナのために新しいnamespaceを作ろうとして、 permissionの問題に遭遇しているとのこと。

Codexがbwrapを使うのはセキュリティを高めるためだと思いますので、 安易な設定変更などでapply_patchを出来るようにするのは、 セキュリティ上のリスクがあると見ています。

0
Raw
https://www.techtips.page/ja/comments/1121

シェルスクリプトで壊さずに全ての引数を別コマンドに引き渡す書き方

wakairo @wakairo
最終更新

基本はダブルクォーテーション付きの"$@"

シェルスクリプトに渡された全ての引数を、そのシェルスクリプト内で別のコマンドに引き渡す場合は"$@"を使います。 例えば、以下のように記述します。

grep -n cat "$@" | sed "s/cat/__CAT__/g" | tee -a ~/foo.log

"$*"$@(ダブルクォーテーションなし)を使うと、'foo bar'のようなスペースを含む引数がスペースで分割されて壊れてしまいます。

shコマンドに渡すときはsh -c '..."$@"...' -- "$@"

1つの実行コマンドしか受け付けないsudosshdocker runなどで、 複数コマンドの実行などの複雑な処理を行いたいときに活躍するのがsh -c '...'です。

シェルスクリプト内でsh -c '...'にすべての引数を渡したいときは、sh -c '..."$@"...' -- "$@"と記述します。 例えば、以下のように記述します。

sudo sh -c 'grep -n cat "$@" | sed "s/cat/__CAT__/g" | tee -a /var/log/foo.log' -- "$@"

先頭のいくつかの引数を取り出して残りを渡す場合(おまけ)

検索ワードのような「固定の引数」と、複数のファイルのような「可変長の引数」が混在しているケースです。 これらをまとめてsudosshdocker runなどに投げたい場合は、 -cオプションの文字列内でshiftを使います。

以下は、第一引数が検索文字列、第二引数がその検索文字列を置き換える先の文字列、 第三引数以降はこの検索と置換の対象となるファイル(複数個指定可)となっている例です。

sudo sh -c 'pattern="$1"; replace="$2"; shift 2;
            grep -n "$pattern" "$@" |
            sed "s/$pattern/$replace/g" |
            tee -a /var/log/foo.log' -- "$@"
0
Raw
https://www.techtips.page/ja/comments/1083
❤️2
😄1
🔧1
💯1

setup-rubyにおける.ruby-versionを用いたバージョン指定

wakairo @wakairo

ruby-version:が無いときのデフォルト動作では、まず.ruby-versionを読みに行くのですね。知りませんでした。

ちなみに少し調べてみたら、2020年のv1.3.0のときから既にそういう仕様のようですね。

それから、railsの新規アプリのGitHub Actionsの設定も現在はruby-version:を省略するようになっていますね。

0
Raw
https://www.techtips.page/ja/comments/1076

setup-rubyにおける.ruby-versionを用いたバージョン指定

takuma_tech Takuma @takuma_tech

setup-rubyのREADMEに以下の記述がありますので、 ruby-version:を設定ファイルにあえて書かないことで、.ruby-versionに設定することも可能です。

If the ruby-version input is not specified, .ruby-version is tried first, followed by .tool-versions, followed by mise.toml

設定ファイルをできるだけ簡潔にしたいなら書かない選択もありですし、逆に分かりやすさを重視するなら明示的に書くのも一案です。どちらを取るかは悩ましいところですね。

0
Raw
https://www.techtips.page/ja/comments/1075
😄2
🔧1
💯1