在Docker容器中运行emacs

23
我正在使用Mac,并希望在我的Docker容器中运行emacs。您有解决此问题的首选方法吗?在我的流程中,我卡住了,因为DISPLAY/TERM未设置。
> docker exec -it c6a7a76db84c bash
> sudo apt-get install emacs
...
> oot@c6a7a76db84c:/var/log/apache2# emacs
Please set the environment variable DISPLAY or TERM (see `tset').
> oot@c6a7a76db84c:/var/log/apache2# tset
tset: unknown terminal type unknown
Terminal type?

我应该使用什么进行测试?或者在Docker容器中运行Emacs有没有更好的方法?


这不是一个好主意。容器适用于服务,而不是交互式应用程序。所有的输入和输出都通过http通道从进程(emacs)到Docker CLI再通过Docker守护程序进行复用。 - Bryan
你正在使用Boot2Docker吗?你试图通过这种方式运行emacs来实现什么目标? - Bryan
我猜正确的做法是以某种方式使用卷。所以最终我会在本地编辑文件。 - John Montague
2
@Bryan 我不明白你为什么认为Docker不能很好地处理交互式应用程序。我经常使用它来处理这样的应用程序! - Adrian Mouat
我相信我已经解释过了 - 这涉及到在HTTP链接中传输字符的大量额外开销。 - Bryan
显示剩余2条评论
3个回答

13

为了在容器内编辑文件,通常最好使用卷和主机上的编辑器,正如Bryan所建议的那样。事实上,您不应编辑未在卷中的文件,因为当容器被删除时,更改将丢失。

然而,在容器内运行编辑器甚至GUI应用程序是完全可能和有用的。为了运行emacs的命令行版本,我所需要做的就是:

$ docker run -it debian /bin/bash
root@02bd877c1052:/# apt-get update && apt-get install -y emacs23-nox
root@02bd877c1052:/# emacs

我已经使用boot2docker和在Linux上本地运行的docker进行了测试。我认为你的问题是因为emacs尝试启动X版本的emacs,这默认情况下不起作用,因为没有运行XServer。

如果您想在容器内运行GUI应用程序,有几种选择:

  • 使用VNC或类似工具
  • 使用ssh -x进行X转发(需要像xquartz这样的XServer)
  • 挂载容器内的xsocket(同样需要XServer,而且我不确定它在xquartz中是否有效,还存在公开xsocket的一些安全问题)

请不要认为容器不应该用于交互式应用程序。有许多原因可以这样做,包括安全性。 subuser项目使用Docker来运行交互式应用程序,并详细介绍了这样做的原因。


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - John Montague
“debian” 是我们正在使用的镜像名称。你可能一直在使用 “ubuntu”。你运行了 “apt-get update” 吗? - Adrian Mouat
我运行了apt-get update命令。由于docker文件以“FROM debian:jessie”开头,因此我认为它不是Ubuntu系统。 - John Montague
4
对于我来说,TERM 设置为 xterm。在运行 emacs 之前,尝试仅执行 export TERM=xterm。可能这是 docker 或 boot2docker 中的一个 bug。 - Adrian Mouat
1
@JohnMontague 在 DockerFile 中,您可以使用 RUN echo export TERM=xterm >> /etc/bash.bashrc - TooTone
显示剩余2条评论

11

正如Adrian Mouat在他的评论中提到的那样,只需执行:

export TERM=xterm

而且您将能够运行emacs(请注意,由于Docker的原因,您将始终需要双击C-p才能移动到上一行)。


1
最近我在Docker上做的另一件事情是在我的桌面上使用emacs进行编辑,将整个文件复制到剪贴板中,然后在容器内执行cat > file.txt,粘贴剪贴板并输入Ctrl+D。 - metakermit
这是正确的答案。所有其他答案都应该被送到/dev/null。 - Stephan Kristyn

2
在容器内部运行编辑器并不是一个好主意。容器适用于服务,而不是交互式应用程序。如果您尝试这样做,所有的输入和输出都会通过 http 通道从进程(如 emacs)经由 Docker 客户端接口到 Docker 守护进程进行多路复用。此外,如果要编辑的文件位于容器的分层文件系统中,则会增加额外的开销。
正如Docker所说,挂载卷是更好的选择:
“您还可以将自己主机上的目录挂载到容器中。”
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

这将把本地目录 /src/webapp 挂载到容器中作为 /opt/webapp 目录。这对于测试非常有用,例如我们可以将源代码挂载到容器内部并在更改源代码时查看我们的应用程序运行情况。
需要注意的是,从 Docker 1.3 开始,-v 开关也可以从外部 Mac 使用。

2
我并不真的觉得使用容器来开发交互式应用程序有什么问题,而且我自己经常这样做。 - Adrian Mouat
对不起,我不应该将您关于使用卷的观点进行“踩”评,虽然我不同意有关交互式应用程序的说法。显然,现在我无法更改它! - Adrian Mouat
我并不那么愚蠢 ;) 在您编辑了帖子之前,我无法更改我的投票。 - Adrian Mouat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接