为什么此 Docker CMD 生成零长度文件?

Why is this Docker CMD producing a zero-length file?

我创建了一个简单的 Docker 图像,可用于使用 openssl 创建密钥对。但是当我 docker run 容器时,它会生成一个零长度的密钥文件。然而 运行 openssl 命令以交互方式生成一个正常大小的密钥文件。 为什么 运行 通过 Docker 容器不保存文件的内容?

我的 Dockerfile 看起来像这样:

# Very small Docker image that provides openssl
#
FROM gliderlabs/alpine:3.3
MAINTAINER Dave Hein <someone@example.org>

ARG REFRESHED_AT=2016-05-17T18:29-0500
RUN apk-install --update openssl
RUN apk-install --update expect
WORKDIR /data/root/ca

ARG CMD_AT=2016-05-17T19:42-0500 
CMD mkdir -p certs crl newcerts private && \
    expect -c "spawn openssl genrsa -aes256 -out private/${KEY_NAME}.key.pem 4096" \
    -c "expect \"Enter pass phrase\"" \
    -c "send \"${PP_}\r\"" \
    -c "expect \"Verifying - Enter pass phrase\"" \ 
    -c "send \"${PP_}\r\"" \
    -c "interact" && \
    echo

我用这个脚本构建容器:

#! /bin/bash
#
docker build -t datihein/ca-cert --file Dockerfile .

运行容器的脚本如下所示:

#! /bin/bash
#
docker run --rm \
  -e KEY_NAME=datihein -e PP_="wat dat?!" \
  -v /var/lib/dockerdata/root/ca:/data/root/ca \
  datihein/ca-cert

我已经尝试在 echo 之前向 CMD 添加 syncsync -f,但我仍然在 /var/lib/dockerdata/root/ca/private/datihein.key.pem 中得到一个零长度文件在主机上。

我怀疑这个问题与从 expect 内部产生有关,但我不知道如何在容器被拆除之前强制刷新文件。

(以防万一,我的 Docker 主机系统是 OS X 10.9.5 系统上 VirtualBox 中的 boot2docker VM 运行。)

更新: 解决方案是使用 expect 命令 wait 等待 openssl 进程在完成 expect 之前终止命令并销毁容器。更新后的 Docker CMD 如下所示:

CMD mkdir -p certs crl newcerts private && \
    expect -c "spawn openssl genrsa -aes256 -out private/${KEY_NAME}.key.pem 4096" \
    -c "expect \"Enter pass phrase\"" \
    -c "send \"${PP_}\r\"" \
    -c "expect \"Verifying - Enter pass phrase\"" \ 
    -c "send \"${PP_}\r\"" \
    -c "wait" && \
    echo

我找到了解决方案。确实和expect.

里面的spawn命令有关

expect 命令 wait 将等待生成的进程完成。

我只是用 wait 替换了 interact 命令,它生成了一个正常长度的密钥文件;即,openssl 命令在容器被销毁之前刷新并关闭了输出文件。

(呃。也许这会对其他人有所帮助。)