ランチャー実行は「Enter」キーを押してコマンドを実行するのとは異なる

Entering app context and running my command works as expected.

/var/discourse# ./launcher enter app
/var/www/discourse# discourse disable_restore
Restore are now forbidden. Enable them with `enable_restore`

I expected the ./launcher run app "discourse disable_restore" to be the same thing, implicitly changing to the docker context, but it fails with an weird redis connection refused.

/var/discourse# ./launcher run app "discourse disable_restore"
Failed to report error: Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED) 2 Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED) subscribe failed, reconnecting in 1 second. 
Call stack ["/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:344:in `rescue in establish_connection'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:328:in `establish_connection'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:99:in `block in connect'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:291:in `with_reconnect'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:98:in `connect'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:274:in `with_socket_timeout'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis/client.rb:131:in `call_loop'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis/subscribe.rb:43:in `subscription'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis/subscribe.rb:12:in `subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis.rb:2824:in `_subscription'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis.rb:2192:in `block in subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis.rb:45:in `block in synchronize'", "/usr/local/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis.rb:45:in `synchronize'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/redis-4.0.1/lib/redis.rb:2191:in `subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/message_bus-2.1.6/lib/message_bus/backends/redis.rb:337:in `global_subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/message_bus-2.1.6/lib/message_bus.rb:533:in `global_subscribe_thread'", "/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/message_bus-2.1.6/lib/message_bus.rb:481:in `block in new_subscriber_thread'"] 
bundler: failed to load command: script/discourse (script/discourse)
Redis::CannotConnectError: Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)

Is it expected behaviour?

I’m running from master (discourse 42aefc3 and discourse_docker 3377f26).

「いいね!」 2

It worked for me just now.

root@lh:/var/discourse#` ./launcher run web_only "discourse disable_restore"`
Restore are now forbidden. Enable them with `enable_restore`
root@lh:/var/discourse# ./launcher run web_only "discourse enable_restore"
Restore are now permitted. Disable them with `disable_restore`

But maybe there’s something different in a web-only vs single-container solution. You might try

 ./launcher run app  "su discourse discourse disable_restore"

Tried your solution but does not work. :frowning:

/var/discourse# ./launcher run app "su discourse discourse disable_restore" discourse is not in the sudoers file. This incident will be reported.

「いいね!」 1

Hmm. Well, I’ll try on a single container install today if I get a chance.

「いいね!」 1

I solved my issue with another @pfaffman answer: Running commands inside discourse container?

docker exec -w /var/www/discourse -i app discourse enable_restore

Works for me, but I expected ./launcher run app "command" to be the way to do it.

Thanks!

「いいね!」 2

Glad my answer worked! The ./launcher run command is pretty new, but I’d expect it to work too.

「いいね!」 3

みなさん、こんにちは!

私も同じ問題に遭遇しました。./launcher を実行して restore を有効化したいのですが、正しい方法はどのようなものでしょうか?

つまり、以下のコマンドの代わりに

vagrant ssh -c 'cd /vagrant;sudo ./launcher run discourse discourse enable_restore'

上記で述べた通り、以下のコマンドが私の環境では動作します

vagrant ssh -c 'sudo docker exec -w /var/www/discourse -i discourse discourse enable_restore'

しかし、もっと簡単な方法があるはずです。内部の仕組みに踏み込むことなく、標準的なコマンドを使って「安全」に操作したいと考えています。launcher はまさにそのためのものだと考えていたのですが。

そう言ってもらえて嬉しいです。

投稿は 2018 年のものですが、想定されるユーザーを考慮すると、単純なコマンドを正しく実装するのは難しかったのでしょう。

ここ数日、ランチャーのスクリプトを一つずつ分解して分析しており、現在は run コマンドに焦点を当てています。ランチャーのコマンドを作業する際には、使用されている Docker コマンドを使って同じ手順を再現するようにしています。

run については、run を使用する Docker コマンドが 2 つあることは知っていました。

docker container run
docker run

しかし、Docker の専門家ではないため、両者の違いや違いがないのかをラバーダック(説明用の人形)に説明することはできません。

そこで、単純な ls を試してみたところ、結果が返ってくるまでに非常に時間がかかり、お茶休憩をしようかと思いました。ただし、正しい ls の結果は返ってきたので、launcher run が実際に何をしているのかを確認することにしました。

以下のようなコードを見て、信じられませんでした。

  (exec $docker_path run --rm --shm-size=512m $user_args $links "${env[@]}" -e DOCKER_HOST_IP="$docker_ip" -i -a stdin -a stdout -a stderr $volumes $run_image \
    /bin/bash -c "$run_command") || ERR=$?

なぜこのような実装になっているのかを尋ねていませんが、時には答えが投稿の中に隠れていることもあります。もし答えが見つからなくても、自分自身で深く理解できるはずです。

** 編集 **

関連投稿: Trying to understand launcher as a series of Docker commands

関連投稿で指摘された通り、launcher run app ls を実行した結果は以下の通りです。

groot@galaxy:/var/discourse$ sudo bash -x launcher run app ls 2> ~/traces/ls_01
eric@swi-prolog:/var/discourse$ grep /usr/bin/docker ~/traces/ls_01

出力:

+ docker_path=/usr/bin/docker
+ '[' -z /usr/bin/docker ']'
++ /usr/bin/docker info
+ /usr/bin/docker info
++ /usr/bin/docker --version
++ /usr/bin/docker images
++ /usr/bin/docker run -i --rm -a stdout -a stderr discourse/base:2.0.20200512-1735 echo working
++ /usr/bin/docker info --format '{{.DockerRootDir}}'
+ '[' -z /usr/bin/docker ']'
++ /usr/bin/docker --version
+++ /usr/bin/docker run --rm -i -a stdin -a stdout discourse/base:2.0.20200512-1735 ruby -e 'require '\''yaml'\''; puts YAML.load(STDIN.readlines.join)['\''templates'\'']'
++++ /usr/bin/docker run --rm -i -a stdin -a stdout discourse/base:2.0.20200512-1735 ruby -e 'require '\''yaml'\''; puts YAML.load(STDIN.readlines.join)['\''templates'\'']'
++ /usr/bin/docker run --rm -i -a stdin -a stdout discourse/base:2.0.20200512-1735 ruby -e 'require '\''yaml'\''
++ /usr/bin/docker run --rm -i -a stdin -a stdout discourse/base:2.0.20200512-1735 ruby -e 'require '\''yaml'\''
++ /usr/bin/docker run --rm -i -a stdin -a stdout discourse/base:2.0.20200512-1735 ruby -e 'require '\''yaml'\''
++ /usr/bin/docker run --rm -i -a stdout -a stdin discourse/base:2.0.20200512-1735 ruby -e 'require '\''yaml'\''; puts YAML.load(STDIN.readlines.join)['\''docker_args'\'']'
++ /usr/bin/docker run --rm -i -a stdout -a stdin discourse/base:2.0.20200512-1735 ruby -e 'require '\''yaml'\''; puts YAML.load(STDIN.readlines.join)['\''volumes'\''].map{|v| '\''-v '\'' << v['\''volume'\'']['\''host'\''] << '\'':'\'' << v['\''volume'\'']['\''guest'\''] << '\'' '\''}.join'
++ /usr/bin/docker run --rm -i -a stdout -a stdin discourse/base:2.0.20200512-1735 ruby -e 'require '\''yaml'\''; puts YAML.load(STDIN.readlines.join)['\''links'\''].map{|l| '\''--link '\'' << l['\''link'\'']['\''name'\''] << '\'':'\'' << l['\''link'\'']['\''alias'\''] << '\'' '\''}.join'
++ /usr/bin/docker run --rm -i -a stdin -a stdout discourse/base:2.0.20200512-1735 ruby -e 'require '\''yaml'\''; puts YAML.load(STDIN.readlines.join)['\''run_image'\'']'
+ exec /usr/bin/docker run --rm --shm-size=512m -e LANG=en_US.UTF-8 -e RAILS_ENV=production -e UNICORN_WORKERS=4 -e UNICORN_SIDEKIQS=1 -e RUBY_GLOBAL_METHOD_CACHE_SIZE=131072 -e RUBY_GC_HEAP_GROWTH_MAX_SLOTS=40000 -e RUBY_GC_HEAP_INIT_SLOTS=400000 -e RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.5 -e DISCOURSE_DB_SOCKET=/var/run/postgresql -e DISCOURSE_DB_HOST= -e DISCOURSE_DB_PORT= -e LETSENCRYPT_DIR=/shared/letsencrypt -e DISCOURSE_HOSTNAME=discourse.galaxy.org -e DISCOURSE_DEVELOPER_EMAILS=groot@galaxy.org -e DISCOURSE_SMTP_ADDRESS=smtp.mailgun.org -e DISCOURSE_SMTP_PORT=587 -e DISCOURSE_SMTP_USER_NAME=groot@mg.galaxy.org -e DISCOURSE_SMTP_PASSWORD= I_am_Groot -e LETSENCRYPT_ACCOUNT_EMAIL=groot@galaxy.org -e DOCKER_HOST_IP=NNN.MMM.OOO.PPP -i -a stdin -a stdout -a stderr -v /var/discourse/shared/standalone:/shared -v /var/discourse/shared/standalone/log/var-log:/var/log local_discourse/app /bin/bash -c ls