ホストBashからrailsコマンドを実行する

みなさん、こんにちは。

ホスト側の Bash から自動化されたユーザー削除タスクを実行したいと考えています。手動では以下のように実行しています。

/var/discourse/launcher enter app
rails c
UserDestroyer.new(Discourse.system_user).destroy(User.find_by_username_or_email("user@example.com"), delete_posts: false) 

削除対象のユーザー名リストがテキストファイルに長々とあるので、手動で一つずつ実行するのは現実的ではありません。削除コマンドを Bash スクリプトでラックしようと試みました。しかし、launcher app サブコマンドで rails c を実行すると、Redis 接続に失敗します。

/var/discourse/launcher run app "echo \"User.find_by_username_or_email('user@example.com')\" | rails c"
Failed to report error: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL) 2 Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL) subscribe failed, reconnecting in 1 second.

一方、launcher enter applauncher run app の環境変数を export で比較すると、ほぼ同じように見えます。何が足りないのでしょうか?launcher run/ から開始されるのに対し、launcher enter は直接 /var/www/discourse に進入します。実行前に cd を使っても解決しませんでした。

何かヒントはありませんか?ありがとうございます!

docker run は新しいコンテナを起動すると思います。

そのような場合は、不要な処理を多数実行する launcher ではなく、docker exec を使用します。

「いいね!」 1

返信ありがとうございます。docker exec による Rails の挙動も非常に奇妙だと感じています。手動では問題なく動作します:

docker exec -it de7f5f6f649c '/bin/bash'
root@discourse-app:/# rails c
[1] pry(main)> User.find_by_username_or_email('myname')

しかし、コンテナの外から rails c を実行しようとすると、以下の問題が発生します:

docker exec -it de7f5f6f649c "/usr/local/bin/rails console"
OCI runtime exec failed: exec failed: container_linux.go:367: starting container process caused: exec: "/usr/local/bin/rails console": stat /usr/local/bin/rails console: no such file or directory: unknown

さらに興味深いことに:

docker exec -it de7f5f6f649c '/bin/bash -c "/usr/local/bin/rails"'
OCI runtime exec failed: exec failed: container_linux.go:367: starting container process caused: exec: "/bin/bash -c \"/usr/local/bin/rails\"": stat /bin/bash -c "/usr/local/bin/rails": no such file or directory: unknown

なぜこのような違いが生じるのでしょうか?

これは想定される動作です。Docker にコンテナ内で /usr/local/bin/rails console というバイナリを実行するよう指示しています。つまり、埋め込まれたスペースを含む単一のファイルです。このファイルは存在しません。

以下を考慮してください:

○ → docker run -i debian /bin/echo hello
hello

○ → docker run -i debian '/bin/echo hello'
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "/bin/echo hello": stat /bin/echo hello: no such file or directory: unknown.
ERRO[0000] error waiting for container: context canceled 

コンテナ内から実行する場合と同じように、コマンドを引用符で囲んでください:

○ → docker exec -i app rails runner 'puts "hello"'
hello

OP の例を使用すると、以下のように動作するはずです:

docker exec -i app rails runner 'UserDestroyer.new(Discourse.system_user).destroy(User.find_by_username_or_email("user@example.com"), delete_posts: false)'
「いいね!」 2

はい、私にとっては予想外でした。RTFM(マニュアルを読め)をしなかったからです。迅速なご支援をありがとうございます。

「いいね!」 1