启动器运行方式与输入并运行命令不同

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).

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.

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

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

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!

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

大家好!

我遇到了同样的问题。我想运行 ./launcher 来启用恢复功能。正确的做法是什么?

所以,与其使用

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,我知道有两个 Docker 命令使用了 run:

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=$?

我简直不敢相信。我还没有问为什么是这样,因为有时候答案就藏在帖子中,只要你仔细寻找;而且即使我找不到答案,我也会因此获得更充分的信息。

** 编辑 **

相关帖子:试图将启动器理解为一系列 Docker 命令

在相关帖子中提到的运行 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