如何运行 Docker 容器并在脚本完成后提交更改?

10
我想设置一个 cron job 在 docker 容器内运行一组命令,然后将更改提交到 docker 镜像。我能够使用以下命令作为守护进程运行容器并获取容器 ID:
``` CONTAINER_ID=$(sudo docker run -d my-image /bin/sh -c "sleep 10") ```
但是我在第二部分 - 提交更改到镜像方面遇到了问题。有没有办法告诉我何时 docker 容器即将被杀死,并在其之前运行另一个命令?
编辑:作为替代方案,是否有办法通过容器内的 shell 脚本触发 `ctrl-p-q` 进入宿主机而不终止容器?
4个回答

16
以下是持久化容器数据的几种方法:
  1. Docker volumes

  2. Docker commit

    a) create container from ubuntu image and run a bash terminal.

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

    b) Inside the terminal install curl

       # apt-get update
       # apt-get install curl
    

    c) Exit the container terminal

       # exit
    

    d) Take a note of your container id by executing following command :

       $ docker ps -a
    

    e) save container as new image

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

    f) verify that you can see your new image with curl installed.

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

这似乎在更改环境变量时无法正常工作。由于某种原因,“export FOO =“ bar””不会在提交中持久存在。 - Granitosaurus
1
@Granitosaurus 这是因为你当前正在运行的 shell 中导出它,然后退出 shell。这不会节省内存,只会节省存储空间。如果你想要保存它,你需要将其放在你的 ~/.bashrc、/etc/profile 等文件中。 - Daniel Santos
自动化此过程时,我不想查看 docker ps -a 的输出,因此从进程中将其输出似乎是可行的:docker run -i -t ubuntu:14.04 /bin/bash -c echo "MY_CONTAINER_ID=$HOSTNAME'"。然后,我只需使用 grep '^MY_CONTAINER_ID=' 来获取我要提交的容器 ID(可能与之匹配,也可能不匹配)。 - Daniel Santos

8

在前台运行它,而不是作为守护进程。当它结束时,启动它的脚本将控制并提交/推送它


谢谢回复。尽管如此,我仍然无法在容器被杀死之前提交。有没有办法在它被杀死之前运行一个命令?或者有没有办法从shell脚本发送ctrl-p-q信号以使容器保持运行状态但返回到主机? - mrdziuban
1
容器已结束,但未被删除,您可以使用存储库或系统名称提交该容器ID。 - gmuslera
太棒了,谢谢!我不知道在容器停止后还可以提交它。 - mrdziuban
1
这个答案需要命令来展示如何获取容器ID等信息。 - user239558

4
我没有找到任何满意的答案,因为我的目标是1)启动容器,2)运行设置脚本,3)捕获/存储设置后的状态,以便稍后立即运行各种脚本来访问该状态。而且这全部在本地自动化的持续集成环境中进行(例如,脚本化和非交互式)。以下是我为设置测试环境想出的方法(我在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

1

如果您希望自动提交所有正在运行的内容,请尝试以下方法。如果有帮助的话,请将其放入cron或其他类似的工具中。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接