【问题标题】:Copy files or clone via ssh in Dockerfile when building docker image构建 docker 镜像时通过 Dockerfile 中的 ssh 复制文件或克隆
【发布时间】:2019-06-25 23:25:01
【问题描述】:

我一直在尝试通过 ssh 从要构建的 docker 映像内的远程服务器(不是 gihub)复制文件,但我无法连接到主机。这是 Dockerfile 直到关键点:

FROM r-base:latest

### Install libs
RUN apt-get update && apt-get install -y \
    sudo \
    gdebi-core \
    pandoc \
    pandoc-citeproc  \
    openssh-server \
    openssh-client \
    libcurl4-gnutls-dev \
    libcairo2-dev \
    libxt-dev \
    xtail \
    wget \
    libssl-dev \
    libxml2 \
    libxml2-dev \
    libv8-dev \
    curl \
    gnupg \
    git

COPY ./setup setup

RUN mv setup/.ssh ~/.ssh
RUN touch ~/.ssh/known_hosts
RUN chmod -R 400 ~/.ssh
RUN ssh-agent sh -c 'ssh-add /root/.ssh/id_rsa'
#RUN eval "$(ssh-agent -s)"
#RUN ssh-add -K ~/.ssh/id_rsa #This is commented out as it causes an error
RUN ssh-keyscan hostname > ~/.ssh/known_host
RUN ssh-keygen -R hostname

## THIS IS THE COMMAND WE NEED TO RUN...
RUN scp -r user@hostname:/path/to/folder ./

文件夹的所有者是user。 id_rsa.pub 被添加到主机上用户user 的authorized_keys 文件中,并在那里重新启动了ssh。但是我得到一个失败的身份验证错误。我尝试使用我的个人 id_rsa,它可以从命令行工作,但它在 docker 内部也失败了。这是一个 docker 问题,可以解决吗?

【问题讨论】:

  • 您是否管理过从容器内部运行 scp 命令?
  • @gCoh 我可以在容器内运行它,但系统会提示我输入“是”以获取主机真实性和用户密码。

标签: docker ssh


【解决方案1】:

我终于设法通过使用this post 中建议的命令生成密钥来做到这一点

所以要在本地重现我的案例:

cd setup/.ssh/
ssh-keygen -q -t rsa -N '' -f id_rsa

然后在服务器上将id_rsa.pub 内容添加到用户user 的已知主机。可以使用 xclip 将内容复制到剪贴板:xclip -sel clip < setup/.ssh/id_rsa.pub)

Dockerfile:

一段时间以来,我一直在尝试通过 ssh 从要构建的 docker 映像内的远程服务器(不是 gihub)复制文件,但我无法连接到主机。这是 Dockerfile 直到关键点:

FROM r-base:latest

### Install libs
RUN apt-get update && apt-get install -y \
    sudo \
    gdebi-core \
    pandoc \
    pandoc-citeproc  \
    openssh-server \
    openssh-client \
    libcurl4-gnutls-dev \
    libcairo2-dev \
    libxt-dev \
    xtail \
    wget \
    libssl-dev \
    libxml2 \
    libxml2-dev \
    libv8-dev \
    curl \
    gnupg \
    git

COPY ./setup setup

RUN chmod -R 600 ~/.ssh
RUN echo "IdentityFile /root/.ssh/id_rsa" >> /etc/ssh/ssh_config
RUN echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config

## THIS IS THE COMMAND WE NEED TO RUN...
RUN scp -r user@hostname:/path/to/folder ./

【讨论】:

    【解决方案2】:

    没有特定要求您必须在 Dockerfile 中执行所有操作。尤其是需要远程 ssh 访问的事情最好在 Docker 之外完成:考虑到以后获取您的映像的任何人都可以docker cp 从中获取有效的 ssh 密钥,并有可能访问您的内部系统。

    出于 Docker 缓存的原因,git clone 或尝试从 Dockerfile 中远程检索您的应用程序也不是一个好主意。如果您重新运行 docker build,并且 Dockerfile 中的其他内容没有发生任何变化,那么 Docker 也会跳过 scp 步骤,即使远程内容发生了变化。

    我的一般建议是从 Dockerfile 外部复制此内容,然后构建它

    # Using whatever credentials are in your local ssh-agent
    scp -r user@hostname:/path/to/stuff dist/
    
    # Then your Dockerfile doesn’t need scp or credentials
    docker build .
    

    你的 Dockerfile 就不需要一堆只与这个路径相关的额外包:你应该能够删除 sudo openssh-server openssh-client xtail curl gnupg git不会真正影响您尝试在容器内运行的单个主进程。

    【讨论】:

    • 感谢您的回答!这个想法也是这个图像将部署在服务器上(可能也用于其他用户),并且可以通过拉取来更新正在运行的容器中的代码。类似于 github 上的部署密钥。
    • 这不是 Docker 通常的工作方式。如果您需要更新代码,您通常会构建一个新镜像,删除现有容器,然后使用新镜像重新启动。您无需修补或更新容器,只需替换它们即可。
    • 代码的更新将是错误修复,如果有的话。新的现实将出现在新的图像中。 Docker 为你工作,你不为 docker 工作:))
    • 如果你不使用它,为什么还要在容器中安装 git?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    • 2018-10-31
    相关资源
    最近更新 更多