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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30607569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 13:06:34  来源:igfitidea点击:

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

bashdockershcommit

提问by mrdziuban

I want to set up a cron job to run a set of commands inside a docker container and then commit the changes to the docker image. I'm able to run the container as a daemon and get the container ID using this command:

我想设置一个 cron 作业来在 docker 容器内运行一组命令,然后将更改提交到 docker 镜像。我可以将容器作为守护程序运行并使用以下命令获取容器 ID:

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

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

but I'm having trouble with the second part--committing the changes to the image once the sleep 10command completes. Is there a way for me to tell when the docker container is about to be killed and run another command before it is?

但是我在第二部分遇到了麻烦——一旦sleep 10命令完成就提交对图像的更改。有没有办法让我知道 docker 容器何时将被杀死并在它之前运行另一个命令?

EDIT: As an alternative, is there a way to trigger ctrl-p-qvia a shell script in the container to leave the container running but return to the host?

编辑:作为替代方案,有没有办法ctrl-p-q通过容器中的 shell 脚本触发以保持容器运行但返回到主机?

采纳答案by gmuslera

Run it in the foreground, not as daemon. When it ends the script that launched it takes control and commits/push it

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

回答by kalyani chaudhari

There are following ways to persist container data:

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

  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
    
  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
    

回答by Phan Dolphy

Try this if you want an auto commit for all which are running. Put this in a cron or something, if this helps

如果您想要对所有正在运行的自动提交,请尝试此操作。把它放在一个 cron 或其他东西中,如果这有帮助的话

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

回答by Jeff Ward

I didn't find any of these answers satisfying, as my goal was to 1) launch a container, 2) run a setup script, and 3) capture/store the state after setup, so I can instantly run various scripts against that state later. And all in a local, automated, continuous integration environment (e.g. scripted and non-interactive).

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

Here's what I came up with (and I run this in Travis-CI installsection) for setting up my test environment:

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

#!/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

Note that my base image was ubuntu:14.04but yours could be any image you want.

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

With that setup, now I can run any number of scripts (e.g. unit tests) against this snapshot (for Travis, these are in my scriptsection). e.g.:

有了这个设置,现在我可以针对这个快照运行任意数量的脚本(例如单元测试)(对于 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