Shell进入一个在Heroku dyno上运行的Docker容器。如何?

时间:2017-10-09 18:36:05

标签: docker heroku

鉴于容器正在运行的dyno,Heroku相当于docker exec -it blarg /bin/bash的是什么?也就是说,如何在已经运行的容器中打开shell?

示例Dockerfile:

FROM heroku/heroku:16
CMD while true; do sleep 1; done

示例运行:

$ heroku container:push my_app
<wait a minute>
$ heroku ps
=== my_app (Free): /bin/sh -c while\ true\;\ do\ sleep\ 1\;\ done (1) 
my_app.1: up 2017/10/09 12:13:07 -0600 (~ 4m ago)

到目前为止一切顺利。

但现在......

$ heroku ps:exec --dyno=my_app.1
Establishing credentials... error
 ▸    Could not connect to dyno!
 ▸    Check if the dyno is running with `heroku ps'

为了更好地衡量,我现在检查heroku ps,它表明dyno仍然在运行。

是的,我已经完成了Heroku所建议的所有事情to enable Docker support。根据文档,我尝试使用我选择的基本图像,同时确保存在bashcurlopensshpython。我也尝试过使用Heroku-16基本图像,如上例所示。

(链接文档还引用了私有空间所需的步骤。由于我没有使用私有空间,我没有应用这些步骤。)

5 个答案:

答案 0 :(得分:8)

TL; DR确保图像中安装了bash并将其添加到Dockerfile中:

RUN rm /bin/sh && ln -s /bin/bash /bin/sh

<强>解释

the documentation导致人们相信的相反,Heroku不会开箱即用支持heroku ps:exec到已经在dyno中运行的Docker容器中。

引自Heroku团队的回复:

  

我们的ps:exec功能......通过将一个bash文件注入dynos来工作...   在后台打开一个额外的端口,并允许你   连接到它。

     

[T]他默认   Docker使用的shell是/ bin / sh,它不兼容   Heroku Exec脚本(需要/ bin / bash)。

     

您可以使用一种解决方法。把以下内容放入你的   Dockerfile:

     

RUN rm /bin/sh && ln -s /bin/bash /bin/sh

     

这绝对是一个缺口   我们的产品,我们将努力做到这一点。

答案 1 :(得分:2)

<强>被修改: 为了在使用Docker的应用程序上运行heroku ps:exec并通过Container Registry部署,您必须启用runtime-heroku-exec。 您可以heroku features:enable runtime-heroku-exec启用它

Here您可以查看exec的文档以及启用泊坞窗支持的说明

答案 2 :(得分:1)

如果安装了bash,请运行heroku run bash。这将使您从命令行进入shell。

您也可以使用GUI并转到&#34;更多&#34; - &GT; &#34;运行控制台&#34;在你的heroku应用程序上,输入&#34; bash&#34;把它带到那里。

答案 3 :(得分:0)

在我的情况下,要使其与Ubuntu 20.04(本地)一起使用,我必须另外将python-is-python3软件包安装到docker映像中,以使heroku-exec工作。


这是一个基于ubuntu的dockerfile的工作示例(2020年10月),可与heroku-exec一起使用:

FROM ubuntu:focal

# install required packages
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -y python3 curl python-is-python3 openssh-server iproute2 nginx && apt-get clean

# simplfy nginx config to enable ENV variable substitution
RUN echo 'server { listen PORT_NUMBER; }' > /etc/nginx/sites-enabled/default

# add config required for HEROKU_EXEC
# ENV HEROKU_EXEC_DEBUG=1
RUN rm /bin/sh \
 && ln -s /bin/bash /bin/sh \
 && mkdir -p /app/.profile.d/ \
 && printf '#!/usr/bin/env bash\n\nset +o posix\n\n[ -z "$SSH_CLIENT" ] && source <(curl --fail --retry 7 -sSL "$HEROKU_EXEC_URL")\n' > /app/.profile.d/heroku-exec.sh \
 && chmod +x /app/.profile.d/heroku-exec.sh

# configure NGINX to listen on dynamic $PORT env variable supplied by Heroku.
CMD sed -i 's/PORT_NUMBER/'"$PORT"'/g' /etc/nginx/sites-enabled/default; nginx -g 'daemon off;'

答案 4 :(得分:0)

heroku run /bin/bashheroku ps:exec 在我的情况下都不起作用。前者打开一个新的容器,与真实运行的容器不同!后者在我的 alpine3 容器中不起作用,尽管 heroku features:enable runtime-heroku-exec 可以成功。我的解决方案是在容器中启动一个 shell 服务器和一个流量转发器。然后在客户端通过流量转发器创建的隧道连接到 shell 服务器。

流量:

localhost:2023 -> chisel client -> ...tunnel... -> chisel server -> localhost:8182

在conainer中,用socat启动一个shell服务器,用chisel启动一个隧道服务器:

nohup socat tcp-l:8182,reuseaddr,fork exec:/bin/bash,pty,setsid,setpgid,stderr,ctty > /tmp/socat.log 2>&1 &

nohup ./chisel server --port $PORT --proxy http://httpbin.org > /tmp/chisel.log 2>&1 &

在客户端,启动一个chisel客户端将来自localhost:8182的流量转发到服务器上的socat

chisel client http://yourapp.herokuapp.com/  0.0.0.0:2023:localhost:8182

在客户端,打开另一个终端窗口:

socat -,raw,echo=0 tcp:127.0.0.1:2023

如何在服务器上获得凿子?下载或直接从 Dockerfile 中的源代码编译

下载chisel