我如何 运行 一个 docker 容器并在脚本完成后提交更改?

How can I run a docker container and commit the changes once a script completes?

我想为 运行 容器内的一组命令设置一个 cron 作业,然后将更改提交到 docker 图像。我能够 运行 容器作为守护进程并使用此命令获取容器 ID:

CONTAINER_ID=$(sudo docker run -d my-image /bin/sh -c "sleep 10")

但是我在处理第二部分时遇到了问题——在 sleep 10 命令完成后提交对图像的更改。有没有办法让我知道 docker 容器何时将被杀死,以及 运行 之前的另一个命令?

编辑:作为替代方案,有没有办法通过容器中的 shell 脚本触发 ctrl-p-q 离开容器 运行ning 但 return主持人?

运行 它在前台,而不是守护进程。当它结束启动的脚本时,它会控制并 commits/push 它

如果你想为所有 运行 自动提交,试试这个。如果有帮助,请将其放入 cron 或其他内容中

#!/bin/bash
for i in `docker ps|tail -n +2|awk '{print }'`; do docker commit -m "commit new change" $i; done

持久化容器数据有以下几种方式:

  1. Docker 卷

  2. Docker 提交

    a) 从 ubuntu 图像和 运行 一个 bash 终端创建容器。

       $ docker run -i -t ubuntu:14.04 /bin/bash
    

    b) 在终端内安装 curl

       # apt-get update
       # apt-get install curl
    

    c) 退出集装箱码头

       # exit
    

    d) 通过执行以下命令记下您的容器 ID:

       $ docker ps -a
    

    e) 将容器保存为新图像

       $ docker commit <container_id> new_image_name:tag_name(optional)
    

    f) 确认您可以看到安装了 curl 的新图像。

       $ docker images           
    
       $ docker run -it new_image_name:tag_name bash
          # which curl
            /usr/bin/curl
    

我没有找到任何令人满意的答案,因为我的目标是 1) 启动容器,2) 运行 安装脚本,以及 3) capture/store 安装后的状态,所以我以后可以立即 运行 针对该状态的各种脚本。并且全部在本地、自动化、持续集成环境中(例如脚本化和非交互式)。

这是我想出的(我 运行 在 Travis-CI install 部分)设置我的测试环境:

#!/bin/bash

# Run a docker with the env boot script
docker run ubuntu:14.04 /path/to/env_setup_script.sh

# Get the container ID of the last run docker (above)
export CONTAINER_ID=`docker ps -lq`

# Commit the container state (returns an image_id with sha256: prefix cut off)
# and write the IMAGE_ID to disk at ~/.docker_image_id
(docker commit $CONTAINER_ID | cut -c8-) > ~/.docker_image_id

请注意,我的基本图像是 ubuntu:14.04,但您的基本图像可以是您想要的任何图像。

有了这个设置,现在我可以 运行 针对这个快照的任意数量的脚本(例如单元测试)(对于 Travis,这些在我的 script 部分)。例如:

docker run `cat ~/.docker_image_id` /path/to/unit_test_1.sh
docker run `cat ~/.docker_image_id` /path/to/unit_test_2.sh