【问题标题】:Edit files in a Docker container ("remote") from Sublime Text on local machine using SFTP使用 SFTP 从本地机器上的 Sublime Text 编辑 Docker 容器(“远程”)中的文件
【发布时间】:2017-09-06 20:14:51
【问题描述】:

目前我正在使用 vim 在 Docker 容器内编辑文件,但我希望有更好的方法。

根据我的研究,在本地机器的文本编辑器(例如 Sublime Text)上编辑 Docker 容器内文件的最佳方法似乎是使用Sublime SFTP。

这需要编辑sftp-config.json 文件,它看起来像这样:

{
    // The tab key will cycle through the settings when first created
    // Visit http://wbond.net/sublime_packages/sftp/settings for help

    // sftp, ftp or ftps
    "type": "sftp",

    "sync_down_on_open": true,
    "sync_same_age": true,

    "host": "192.168.129.8",
    "user": "root",
    "password": "666",
    //"port": "22",

    "remote_path": "/",
    //"file_permissions": "664",
    //"dir_permissions": "775",

    //"extra_list_connections": 0,

    "connect_timeout": 30,
    //"keepalive": 120,
    //"ftp_passive_mode": true,
    //"ftp_obey_passive_host": false,
    //"ssh_key_file": "~/.ssh/id_rsa",
    //"sftp_flags": ["-F", "/path/to/ssh_config"],

    //"preserve_modification_times": false,
    //"remote_time_offset_in_hours": 0,
    //"remote_encoding": "utf-8",
    //"remote_locale": "C",
    //"allow_config_upload": false,
}

但是- 不完全一样- 因为这种安排不起作用。

主要障碍似乎是不建议(不可能?)ssh 进入 docker 容器,至少不使用 macOS。

This is a similar unanswered question from one year ago。

问题:

我们如何在本地机器上使用 Sublime Text 编辑 Docker 容器内的文件?如果 SFTP 是一个可行的选择,我们如何配置 sftp-config.json 并启动一个可以使这成为可能的 Docker 容器?

【问题讨论】:

  • 是的-我已经看到了-但这是否意味着不可能?
  • 当然不是不可能。 Docker 并不是什么神奇的东西。如果你想在你的 docker 容器中运行一个 ssh 服务器,你当然可以这样做,但代价是一些复杂性。但更重要的是,如果您发现必须定期编辑容器内的文件,我会认为您做错了。 Docker 镜像应该是构建过程的产物;您使用自己喜欢的工具在主机上编辑文件,然后构建新映像并启动它。如果您需要进行更改,请构建一个新映像。
  • 我想做的是在docker容器中创建一个hadoop集群-我的开发环境是mac,所以我需要迭代地修改配置文件参数的设置,我更喜欢在 Sublime Text 中执行此操作,它具有我熟悉的所有文本完成和语法突出显示 - 而不是 vim 或我必须在容器内运行的东西

标签: docker sublimetext3 sftp


【解决方案1】:

简短的回答是您不能通过 FTP 访问没有运行 FTP 守护程序的服务器。但是,有几个替代方案可能对您有用。

卷

您可以将自定义docker run 用于开发目的,以便将您的配置暴露给主机。你可以这样做:

docker run \
    -v `pwd`/sftp-config.json:/etc/sftp/sftp-config.json \
    myimage

如果合适的话,您也可以对整个文件夹执行此操作。格式是<hostfile>:<containerfile>,我似乎记得它们需要是完全限定的路径(因此是pwd)。

这里发生的情况是,包含 sftp-config.json 构建版本的映像被动态反映指定主机副本状态的卷覆盖。

在某些情况下,可以像这样 (Traefik, for example) 设置实时环境,以便在容器内使用主机上的配置文件。但是,值得记住的是,Docker 的目的是创建通过 CI 流程的独立映像。因此,为方便起见,您移动到主机的依赖项越多,它们就会变得越脆弱和未经测试。

出于兴趣,我在开发时使用卷,因此我不需要为每一个小更改都经历重建/重新启动周期。我为我的应用程序中的每个关键文件夹创建一个卷,这极大地加快了修改和尝试循环。当然,这并不能取代正确的构建/CI 流程,也不会像这样在现场运行:

#!/bin/bash
#
# Note the web service is on port 8080

PROJECT_ROOT=/var/www/missive_controller

docker run \
    --detach \
    -p 10000:8080 \
    -p 10002:8081 \
    -v $(pwd)/bin:${PROJECT_ROOT}/bin \
    -v $(pwd)/src:${PROJECT_ROOT}/src \
    -v $(pwd)/vendor:${PROJECT_ROOT}/vendor \
    -v $(pwd)/web:${PROJECT_ROOT}/web \
    missive-controller

我也对仅限开发人员的docker-compose.yml 中的定义做同样的事情,它工作得非常好。

炮击

如果您想在开发过程中快速更改容器,您可能不想通过 SSH 进入 - 主要是因为镜像通常不应该运行 SSH 守护程序。但是,您可以轻松地加入:

docker exec -it <containername> sh

sh 是你的 shell 的名称。 BusyBox 发行版倾向于使用 sh,而基于 Ubuntu 的容器可能会有 bash 可用。

从那里,您可以使用容器内编辑器进行更改。在容器的早期开发阶段,我倾向于将RUN apk --update add nano 留在我的 Dockerfile 中(当然随着开发的稳定它会被删除)。

分层FS

为了总结 cmets 中的一些说明,值得将 Docker 映像视为:

  • 不可变;
  • 版本化;
  • 由 CI/构建流程生成,仅在通过自动化功能测试后才能推广;
  • 由文件系统层组成

我认为,最后一点对于理解图像至关重要。当您执行docker build 时,它会为每个命令添加一个层,这就是为什么可以从缓存中检索中间层和未更改层而不是每次都重新构建的原因。

添加卷时,您可以将其视为顶部的另一层,但更改不是永久性的。考虑以下步骤:

  • 图像 1234 包含一个文件 /etc/mywidget.conf,其中包含“a=1”
  • 这是从您的主机上的一个文件创建的,在您的项目中,名为conf/mywidget.conf,您将COPY 复制到您的Dockerfile 中的容器中
  • 如果您修改主机中的文件,在您重建之前它不会更改容器中的副本
  • 因此,如果您将主机副本更改为“a=2”,然后重新启动容器,它仍会看到旧副本;
  • 但是,如果您创建卷 -v /path/to/conf/mywidget.conf:/etc/mywidget.conf 并重新启动容器,它将看到“a=2”的主机版本;
  • 您可以将此卷视为已构建容器版本之上的新层
  • 如果您重新启动容器并删除卷,它将返回到“a=1”的构建版本
  • 最后,如果你重建镜像然后重新启动它,它会将COPY文件的新状态放入镜像中,所以即使没有卷它也会看到“a=2”。

【讨论】:

  • 所以我认为通过您刚刚进行的编辑,我们现在在同一页面上 - 重点是我不想使用 nano 因为它没有任何我在构建软件时喜欢使用的语法突出显示或自动完成,我想在我的正常开发环境中迭代地将容器放到我想要的位置,在配置、安装等方面,然后提交/冻结它,然后将其推送到 docker hub - 你知道我的意思吗?
  • 当然@s.matthew。所以,使用 nano 是在容器中,所以可能不是你想要的。在开发过程中使用-v 卷方法,然后当您对配置文件感到满意时,重建您的映像,它将包含最新的副本,假设您的Dockerfile 使用COPY 将该配置文件添加到映像中。在非开发环境中,您可以删除 -v 选项,它将回退到容器副本。
  • 如果您希望能够在主机上编辑文件,即使是在现场,那么您可以对所有环境使用卷方法。请记住我提到的“脆弱性”权衡。
  • 对于脆性 - 这只是意味着我需要在退出之前提交图像,不是吗?所以-我仍然不确定这个卷的内容是什么,当我这样做之前,它似乎只是将文件从我的主机安装到我的容器中-例如,我会在我的本地 macos ~/Desktop ubuntu 镜像容器,你是说我应该复制我想要开发的文件夹,将它们从我的容器中删除,然后放在主机上,然后在它们按照我喜欢的方式配置时保存?
  • 例如-如果有一些名为hadoop 的虚构文件夹存在于我的映像中,我还会在我的本地计算机上创建一个名为hadoop 的文件夹,然后我将启动映像并删除容器自己版本的hadoop 文件夹,用我的本地版本替换它,像这样?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-01
  • 2023-01-19
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多