Launcher run works different than enter and run command

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를 실행하여 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 명령이 있다는 것을 알고 있었습니다.

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

믿을 수 없었습니다. 왜 이렇게 되어 있는지 묻지 않았습니다. 때로는 게시글을 잘 살펴보면 답이 나오기 때문이죠. 하지만 답을 찾지 못하더라도 더 많은 정보를 얻게 될 것입니다.

** 수정 **

관련 게시글: launcher를 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
``