【问题标题】:rsync files from inside a docker container?rsync 来自 docker 容器内的文件?
【发布时间】:2017-04-01 22:09:04
【问题描述】:

我们正在使用 Docker 来构建/部署 NodeJS 应用程序。我们有一个由 Jenkins 构建的 test 容器,并执行我们的单元测试。 Dockerfile 如下所示:

FROM node:boron

# <snip> some misc unimportant config here

# Run the tests
ENTRYPOINT npm test

我想修改这一步,以便我们运行 npm run test:cov,它运行单元测试 + 生成覆盖率报告 HTML 文件。我已将 Dockerfile 修改为:

# Run the tests + generate coverage
ENTRYPOINT npm run test:cov

...这行得通。耶!

...但是现在我不确定如何将覆盖率报告(由 Dockerfile 中的上述命令生成)rsync 发送到远程服务器。

在 Jenkins 中,上面的配置是这样调用的:

docker run -t test --rm

再次运行上述测试并存在容器。

如何在入口点命令执行后添加一些额外的步骤,以(例如)将一些结果同步到远程服务器?

【问题讨论】:

    标签: node.js docker jenkins dockerfile


    【解决方案1】:

    我不是“节点”专家,所以请耐心等待细节。

    首先,您可以考虑是否需要单独的 Dockerfile 来运行测试。理想情况下,您希望在不修改实际图像的情况下构建并测试您的图像。

    构建一个使用您的 NodeJS 应用程序作为基础镜像 (FROM my-nodejs-image) 的测试镜像可以解决问题,但如果您只需运行不同的命令,则可能不需要/入口点在图片上。

    其次;有状态数据(覆盖率报告属于该类别)不应存储在容器内(即,不存储在容器的文件系统中)。您希望您的容器是短暂的,并且任何应该在容器生命周期之外存在的东西(任何应该在容器本身消失后保留的东西)都应该存储在容器的外部;要么在“卷”中,要么在绑定挂载的目录中。

    让我从“单独的 Dockerfile”这一点开始。假设您的 NodeJS 应用程序 Dockerfile 看起来像这样;

    FROM node:boron
    
    COPY package.json /usr/src/app/
    RUN npm install && npm cache clean
    COPY . /usr/src/app
    
    CMD [ "npm", "start" ]
    

    你构建你的镜像,并标记它,例如,使用它构建的提交;

    docker build -t myapp:$GIT_COMMIT .
    

    成功构建映像后,您需要对其进行测试。可能是一个快速测试来验证它是否真正“运行”。有很多方法可以做到这一点,也许是这样的;

    docker run \
      -d \
      --rm \
      --network=test-network \
      --name test-{$GIT_COMMIT} \
      myapp:$GIT_COMMIT
    

    而一个用来测试它的容器实际上做了一些事情;

    docker run --rm --network=test-network my-test-image curl test-{$GIT_COMMIT}
    

    一旦测试(并移除临时容器),您就可以运行覆盖率测试,但是,不要在容器内编写覆盖率报告,而是将其写入卷或绑定挂载。您可以使用docker run覆盖在容器中运行的命令;

    mkdir -p /coverage-reports/{$GIT_COMMIT}
    docker run \
      --rm \
      --name test-{$GIT_COMMIT}\
      -v /coverage-reports/{$GIT_COMMIT}:/usr/src/app/coverage \
      myapp:$GIT_COMMIT npm run test:cov
    

    上面的命令;

    • 创建一个唯一的本地目录来存储测试工件(覆盖率报告)
    • 运行您构建的映像(并标记为myapp:$GIT_COMMIT
    • /coverage-reports/{$GIT_COMMIT}绑定安装到容器usr/src/app/coverage
    • 运行覆盖测试(如果我没记错的话,它会写信给 /usr/src/app/coverage - 再说一遍,不是 Node 专家)
    • 一旦容器退出就移除它

    容器退出后,覆盖率报告存储在主机上的/coverage-reports/{$GIT_COMMIT}。你可以使用你的常规工具来rsync那些你想要的。

    作为替代方案,您可以使用volume plugin 将结果写入(例如)s3 存储桶,这样您就不必重新同步结果。

    测试成功后,您可以通过docker tag 将应用程序的版本(例如docker tag myapp:1.0.12345)、docker push 更新到您的注册表,然后部署新版本。

    【讨论】:

      【解决方案2】:

      制作一个脚本作为入口点执行并将命令放入脚本中。您在调用 docker run 时传入 args 并将它们传递给脚本。

      文档有一个 postgres 图像脚本的示例。你可以以此为基础。

      Docker Entrypoint Docs

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-04
        • 1970-01-01
        • 2014-03-28
        • 1970-01-01
        • 1970-01-01
        • 2021-06-04
        • 1970-01-01
        相关资源
        最近更新 更多