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

**URL:** https://meta.discourse.org/t/launcher-run-works-different-than-enter-and-run-command/100197
**Category:** Self-hosting
**Created:** [2018年十月22日 22:17 UTC](https://meta.discourse.org/t/launcher-run-works-different-than-enter-and-run-command/100197 "2018-10-22T22:17:51Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![iurisilvio](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/iurisilvio/32/118978_2.png) [@iurisilvio](https://meta.discourse.org/u/iurisilvio)
#### Post date: [2018年十月22日 22:17 UTC](https://meta.discourse.org/t/launcher-run-works-different-than-enter-and-run-command/100197/1 "2018-10-22T22:17:51Z")

</div>

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

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2018年十月22日 22:46 UTC](https://meta.discourse.org/t/launcher-run-works-different-than-enter-and-run-command/100197/2 "2018-10-22T22:46:19Z")

</div>

It worked for me just now.

```plaintext
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"

```

---

<div class="post-metadata">

### Author: ![iurisilvio](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/iurisilvio/32/118978_2.png) [@iurisilvio](https://meta.discourse.org/u/iurisilvio)
#### Post date: [2018年十月24日 12:03 UTC](https://meta.discourse.org/t/launcher-run-works-different-than-enter-and-run-command/100197/3 "2018-10-24T12:03:04Z")

</div>

Tried your solution but does not work. ☹

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

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2018年十月24日 12:19 UTC](https://meta.discourse.org/t/launcher-run-works-different-than-enter-and-run-command/100197/4 "2018-10-24T12:19:19Z")

</div>

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

---

<div class="post-metadata">

### Author: ![iurisilvio](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/iurisilvio/32/118978_2.png) [@iurisilvio](https://meta.discourse.org/u/iurisilvio)
#### Post date: [2018年十一月6日 15:27 UTC](https://meta.discourse.org/t/launcher-run-works-different-than-enter-and-run-command/100197/5 "2018-11-06T15:27:10Z")

</div>

I solved my issue with another @pfaffman answer: [Running commands inside discourse container? - #5 by pfaffman](https://meta.discourse.org/t/running-commands-inside-discourse-container/92811/5)

```
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!

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2018年十一月6日 15:32 UTC](https://meta.discourse.org/t/launcher-run-works-different-than-enter-and-run-command/100197/6 "2018-11-06T15:32:42Z")

</div>

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

---

<div class="post-metadata">

### Author: ![pihentagy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pihentagy/32/131067_2.png) [@pihentagy](https://meta.discourse.org/u/pihentagy)
#### Post date: [2020年五月12日 21:17 UTC](https://meta.discourse.org/t/launcher-run-works-different-than-enter-and-run-command/100197/7 "2020-05-12T21:17:33Z")

</div>

大家好！

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

所以，与其使用

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

```

对我而言（如上所述）有效的是：

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

```

但我希望有更直接的方法。我根本不想深入底层，而是希望通过标准命令保持“安全”。我原本以为 launcher 就是为此设计的。

---

<div class="post-metadata">

### Author: ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://meta.discourse.org/u/EricGT)
#### Post date: [2020年六月3日 23:41 UTC](https://meta.discourse.org/t/launcher-run-works-different-than-enter-and-run-command/100197/8 "2020-06-03T23:41:40Z")

</div>

> [@pfaffman](#):
>
> `./launcher run` 命令相对较新，但我预计它也能正常工作。

很高兴你提到了这一点。

我知道这篇帖子来自 2018 年，但考虑到预期的用户群体，当时要正确实现这个命令可能并不简单。

过去几天我一直在逐行拆解启动器脚本，现在正研究 `run` 命令。在研究启动器命令时，我也会尝试使用相应的 Docker 命令来重现相同的步骤。

对于 `run`，我知道有两个 Docker 命令使用了 `run`：

[docker container run](https://docs.docker.com/engine/reference/commandline/container_run/)  
[docker run](https://docs.docker.com/engine/reference/commandline/run/)

但因为我不是 Docker 专家，我无法向“橡皮鸭”解释它们之间的区别，或者是否根本没有区别。

因此，当我尝试一个简单的 [ls](http://manpages.ubuntu.com/manpages/bionic/man1/ls.1.html) 命令时，它花费了太长时间，我差点去喝杯饮料休息一下。它确实返回了正确的 `ls` 结果，于是我仔细查看了 `launcher run` 到底在做什么。

当我看到这段代码时：

```plaintext
  (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 命令](https://meta.discourse.org/t/trying-to-understand-launcher-as-a-series-of-docker-commands/153861)

在相关帖子中提到的运行 `launcher run app ls` 的结果，即：

```BASH
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

```

输出：

```BASH
+ 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

```
