如何从主机编辑Docker容器文件?

时间:2014-07-03 12:31:55

标签: docker

现在我找到了一种方法将主机文件暴露给容器(-v选项),我想做一些相反的事情:

如何使用主机编辑器编辑正在运行的容器中的文件?

sshfs可能可以完成这项工作,但由于正在运行的容器已经是某种主机目录,我想知道是否有便携式(在aufs,btrfs和设备映射器之间)这样做?

10 个答案:

答案 0 :(得分:22)

最好的方法是:

  $ docker cp CONTAINER:FILEPATH LOCALFILEPATH
  $ vi LOCALFILEPATH
  $ docker cp LOCALFILEPATH CONTAINER:FILEPATH

$ docker exec的限制:它只能附加到正在运行的容器。

使用$ docker运行的限制:它将创建一个新容器。

答案 1 :(得分:21)

虽然可以,但其他答案解释了如何,如果可以的话,你应该避免在联盟文件系统中编辑文件。

您对卷的定义并不十分正确 - 它更多地是绕过Union文件系统,而不是在主机上公开文件。例如,如果我这样做:

$ docker run --name="test" -v /volume-test debian echo "test"

容器内的目录/volume-test不会成为Union File System的一部分,而是存在于主机的某个位置。我没有指定主机上的位置,因为我可能不在乎 - 我没有暴露主机文件,只是创建一个可在容器和主机之间共享的目录。您可以通过以下方式找到主机的确切位置:

$ docker inspect -f "{{.Volumes}}" test
map[/volume_test:/var/lib/docker/vfs/dir/b7fff1922e25f0df949e650dfa885dbc304d9d213f703250cf5857446d104895]

如果您真的需要快速编辑文件来测试某些内容,请使用docker exec在容器中获取shell并直接编辑,或使用docker cp将文件复制出来,在主机上编辑并复制回来。

答案 2 :(得分:2)

有两种方法可以将文件挂载到您的容器中。看起来您想要绑定安装

绑定坐骑

这会将本地文件直接挂载到容器的文件系统中。容器端路径和主机端路径都指向同一个文件。从任一侧进行的编辑将显示在两侧

  • 挂载文件:
❯ echo 'bar' > ./foo # make a hostside change
  • 在单独的 shell 中,编辑文件:
# cat /foo
bar # the hostside change shows up
# echo baz > /foo # make a containerside change
# exit
 
❯ cat foo
baz # the containerside change shows up
  • 回到容器中:
❯ docker run --mount type=volume,source=foovolume,target=/foo  -it debian:latest
root@containerB# echo 'this is in a volume' > /foo/data

卷安装

  • 挂载卷
❯ docker volume ls
DRIVER    VOLUME NAME
local     foovolume
  • 本地文件系统未更改
  • docker 看到一个新卷:
❯ docker run --mount type=volume,source=foovolume,target=/foo  -it debian:latest
root@containerC:/# cat /foo/data
this is in a volume # data is still available
  • 创建一个具有相同体积的新容器
-v

语法:--mount vs -v

它们做同样的事情。 --mount 更简洁,-v /hostside/path:/containerside/path --mount type=bind,source=/hostside/path,target=/containerside/path 更明确。

绑定坐骑

-v /containerside/path
-v volumename:/containerside/path
--mount type=volume,source=volumename,target=/containerside/path

卷安装

+

(如果未指定卷名,则随机选择一个。)

The documentaion 试图说服你使用一种东西来支持另一种东西,而不是仅仅告诉你它是如何工作的,这很令人困惑。

答案 3 :(得分:1)

我们可以使用另一种方式编辑工作容器内的文件(如果容器被停止,这将不起作用)。

逻辑是:
- )将文件从容器复制到主机
- )使用主机编辑器在主机上编辑文件 - )将文件复制回容器

我们可以手动完成所有这些步骤,但我已经编写了简单的bash脚本,通过一次调用就可以轻松完成。

<强> / bin中/ dmcedit:

#!/bin/sh
set -e

CONTAINER=$1
FILEPATH=$2
BASE=$(basename $FILEPATH)
DIR=$(dirname $FILEPATH)
TMPDIR=/tmp/m_docker_$(date +%s)/

mkdir $TMPDIR
cd $TMPDIR
docker cp $CONTAINER:$FILEPATH ./$DIR
mcedit ./$FILEPATH
docker cp ./$FILEPATH $CONTAINER:$FILEPATH
rm -rf $TMPDIR

echo 'END'
exit 1;

用法示例:

  

dmcedit CONTAINERNAME / path / to / file / in / container

脚本非常简单,但它对我来说很好。

任何建议都表示赞赏。

答案 4 :(得分:1)

这是我使用的脚本:

#!/bin/bash
IFS=$'\n\t'
set -euox pipefail


CNAME="$1"
FILE_PATH="$2"

TMPFILE="$(mktemp)"
docker exec "$CNAME" cat "$FILE_PATH" > "$TMPFILE"
$EDITOR "$TMPFILE"
cat "$TMPFILE" | docker exec -i "$CNAME" sh -c 'cat > '"$FILE_PATH"
rm "$TMPFILE"

以及我解决它时的要点,但忘了更新这个答案: https://gist.github.com/dmohs/b50ea4302b62ebfc4f308a20d3de4213

答案 5 :(得分:1)

我在IDE中使用sftp插件。

  1. 为容器安装ssh服务器并允许root访问。
  2. 使用-p localport:22
  3. 运行docker容器
  4. 从IDE安装sftp插件
  5. 使用sublime sftp插件的示例: https://www.youtube.com/watch?v=HMfjt_YMru0

答案 6 :(得分:0)

如果您认为您的卷是“网络驱动器”,它将更加容易。 要编辑此驱动器中的文件,只需打开另一台计算机并连接到该网络驱动器,然后像平常一样编辑文件即可。

如何仅使用docker来做到这一点(不使用FTP / SSH ...)?

  1. 运行具有编辑器(VI,Emacs)的容器。在Docker集线器中搜索“ alpine vim”

示例:

docker run -d --name shared_vim_editor \
 -v <your_volume>:/home/developer/workspace \
jare/vim-bundle:latest
  1. 运行交互式命令:

docker exec -it -u root shared_vim_editor /bin/bash

希望这会有所帮助。

答案 7 :(得分:0)

我正在做的事情是使用安装了docker软件包的Emacs。我建议使用Spacemacs版的Emacs。我将按照以下步骤操作:

1)安装Emacs(Instruction)并安装Spacemacs(Instruction

2)在您的docker文件中添加.spacemacs

3)启动Emacs

4)查找文件(SPC+f+f)并输入/docker:<container-id>:/<path of dir/file in the container>

5)现在,您的emacs将使用容器环境来编辑文件

答案 8 :(得分:-2)

docker run -it -name YOUR_NAME IMAGE_ID /bin/bash

$>vi path_to_file

答案 9 :(得分:-4)

以下为我工作

docker run -it IMAGE_NAME /bin/bash

例如。我的形象叫做ipython / notebook

docker run -it ipython/notebook /bin/bash