ChatGPT解决这个技术问题 Extra ChatGPT

使用一个命令构建和运行 Dockerfile

是否可以从 Dockerfile 构建映像并使用单个命令运行它?
有一个命令 docker build 来构建 Dockerfile,而 docker run -it 来运行映像。

这两个命令是否有任何组合可以使仅使用一个命令就可以更轻松地构建和运行?

如果您详细说明您的用例,我们可能会提供更好的选择。
@JonathonReinhart 我的用例是在编辑正在处理的 Dockerfile 时快速迭代。

a
abernier

如果您想避免标记,docker build -q 只输出 最终图像哈希,您可以将其用作 docker run 的参数:

docker run -it $(docker build -q .)

如果您希望容器在退出时自动删除,请将 --rm 添加到 docker run

docker run --rm -it $(docker build -q .)

比公认的答案更好,因为它不会弄乱本地图像存储库
@InsOp 实际上,这也会产生本地图像。他们只是没有被标记。
遗憾的是,这并没有向您显示 docker build 的常规构建输出:/
@Lion 那点 -q 选项。为了让它安静,只输出自动生成的标签。就是这样。您可以随意转换该标准输入。
这个答案是一个很好的技术!我使用了一段时间,但后来意识到每当我需要在末尾附加一个运行时命令(例如 docker run ... $(docker build -q .) python foo.py)时,它是不可取的。问题是,如果“docker build ...”部分意外出错,结果“docker run ...”部分将有效地忽略构建错误,并继续处理下一个单词(在这种情况下, “python”)就好像它是一个图像名称。换言之,它现在尝试使用名为 python 的图像运行 foo.py。那不是你想要的。
J
Jonathon Reinhart

不,没有单一的命令。但是如果你在构建图像时标记它,它会更容易运行:

docker build -t foo . && docker run -it foo

很好的答案,因为您可以根据需要轻松删除图像:docker rmi foo
P
Pang

我使用 docker-compose 是为了方便起见,因为我正在构建的大多数应用程序迟早都会与外部服务通信,所以如果我还是要使用它,为什么不从一开始就使用它。只需将 docker-compose.yml 设置为:

version: "3"
services:
  app:
    build: .

然后只需运行应用程序:

docker-compose up --build app

它将重建图像或重用容器,具体取决于是否对图像定义进行了更改。


b
bozdoz

最近,我开始收到关于每次构建后使用 docker scan促销消息。

使用 'docker scan' 对图像运行 Snyk 测试以发现漏洞并学习如何修复它们

这是我以前做的:

docker build -q .

这就是现在的工作:

docker build -q . | head -n1

请参阅 github.com/docker/scan-cli-plugin/issues/…,了解如何永久禁用该消息。 export DOCKER_SCAN_SUGGEST=false
@bozdoz 促销消息与在一个命令中构建和运行有什么关系?
@AlxVallejo 见上面的评论。 Docker 在每次构建后都会打印一条关于使用 Snyk 的信息。因此,根据我的回答,我以前所做的不再有效(因为 docker build 不再仅打印图像哈希)
t
tavlima

如果你使用 Makefile,我发现这个片段很有用:

build:
    @docker build . | tee .buildlog

bash: build
    @docker run --rm -it $(shell grep "Successfully built" .buildlog | cut -d ' ' -f 3) /bin/bash

您不需要标记,就像在@jonathon-reinhart 回答中一样,但您也可以获得构建输出。


V
Viacheslav Shalamov

您还可以执行 docker build 并将图像名称输出到 docker run

docker build . | tail -n1 | cut -d' ' -f3 | xargs -I{} docker run {}

docker build 会给你多行文本... 成功构建 18e77bc0d83a

你得到最后一行 tail -n1

用 ' ' 分割并用 cut -d' ' -f3 得到第三个单词

将其作为参数传递给 xargs -I{} docker run {}


docker build . 之后添加 | tee /dev/tty 以获得完整的输出!
D
Denis Babochenko

对于任何寻找可重用解决方案的人,您可以安装我创建的这个 docker 插件:https://github.com/stasmihailov/docker-script

然后您可以按如下方式构建和运行 Dockerfile:

docker script ./Dockerfile

R
Rob

视窗电脑

创建一个 run.bat 文件。然后在文件中添加:

docker build -t foo . 
docker run -it foo

要使用 powershell 或 cmd 运行文件,请执行以下操作:

./run.bat

S
Scott Rippey

docker-build-and-run

我在一个命令中创建了一个用于构建和运行的小辅助命令。在 Linux 或 Mac 上,您可以将其添加到您的 ~/.bash_profile 以使其在终端中可用。

用法:

docker-build-and-run BUILD_ARGS [-- RUN_ARGS] [-- RUN_COMMAND]

例子:

docker-build-and-run . -- npm run test
docker-build-and-run --file ./Dockerfile . -- -v ~/volume:/var/volume -- node server.js

剧本:

将此添加到 .sh 文件,或将其添加到您的 ~/.bash_profile

TERM_GREEN="\033[1;32m"
TERM_BLUE="\033[1;34m"
TERM_NC="\033[0m"
docker-build-and-run() {
    if [[ -z "$@" ]]; then
        echo "
            Usage:
                docker-build-and-run BUILD_ARGS [-- RUN_ARGS] [-- RUN_COMMAND]
            Examples:
                docker-build-and-run . -- npm run test
                docker-build-and-run --file ./Dockerfile . -- -v ~/volume:/var/volume -- node server.js
        "
        return
    fi

    # Extract the segments between the dashes:
    BEFORE_THE_DASHES=
    while (( "$#" )); do
        if [[ "$1" = "--" ]]; then
            shift
            break
        fi
        BEFORE_THE_DASHES="$BEFORE_THE_DASHES $1"
        shift
    done
    SEGMENT_1=$BEFORE_THE_DASHES

    BEFORE_THE_DASHES=
    while (( "$#" )); do
        if [[ "$1" = "--" ]]; then
            shift
            break
        fi
        BEFORE_THE_DASHES="$BEFORE_THE_DASHES $1"
        shift
    done
    SEGMENT_2=$BEFORE_THE_DASHES

    SEGMENT_3=$@


    BUILD_ARGS=$SEGMENT_1
    RUN_ARGS=$SEGMENT_2
    RUN_COMMAND=$SEGMENT_3
    if [ -z "$RUN_COMMAND" ]; then
      RUN_COMMAND=$RUN_ARGS
      RUN_ARGS=
    fi


    TEMP_TAG=docker-build-and-run-temp

    docker rm -f $TEMP_TAG 2>/dev/null
    printf "${TERM_GREEN}Building Docker container (${TERM_BLUE}docker build $BUILD_ARGS${TERM_GREEN})${TERM_NC}\n" \
    && docker build --tag $TEMP_TAG $BUILD_ARGS \
    && printf "${TERM_GREEN}Running Docker container (${TERM_BLUE}docker run $RUN_ARGS $RUN_COMMAND${TERM_GREEN})${TERM_NC}\n" \
    && docker run --rm -it $RUN_ARGS --label $TEMP_TAG $TEMP_TAG $RUN_COMMAND
}