V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
caneman
V2EX  ›  Docker

Dockerfile CMD 中如何执行多条命令?

  •  
  •   caneman · 2019-06-18 18:00:05 +08:00 · 13035 次点击
    这是一个创建于 1996 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Dockerfile 中 CMD 只能有一条,多了只会执行最后一条,如何解决这个问题?

    我想在镜像里执行 python 1.py 和 python 2.py

    Dockerfile 中

    ....
    ....
    CMD python 1.py
    CMD python 2.py
    

    只会执行最后一句,我该如何解决这个问题?

    (进入内容器里面确实可以再去执行另一条,但有没有办法,在容器启动的时候就能执行两条?)

    不太懂 shell 脚本,可以通过ENTRYPOINT xx.sh指定脚本的方式来实现吗?

    如果可以的话,脚本该怎么写呢?

    1.py 2.py xx.sh 均在同一工作目录)

    第 1 条附言  ·  2019-06-20 15:06:34 +08:00

    解决方案:

    1. 通过线程/进程,把1.py2.py糅合成一个
    2. Dockerfile中运行1.py,进入容器内,执行2.py(此方法docker logs xx查看不到2.py的运行日志)
    3. python 1.py && python 2.py > 1.sh, Dockerfile定义ENTRYPOINT ["/xx/1.sh"] (此方法可以看到两个的日志)
    4. 分成两个容器
    5. supervisor(未尝试)

    我采用的第一种方法

    第三种方法可能会遇到的坑(针对我这种一点shell脚本不懂的人来说)

    1.Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"1.sh\": executable file not found in $PATH": unknown.

    解决方法:ENTRYPOINT sh写绝对路径 , ENTYPOINT ["/root/1.sh"]

    2.Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"/code/1.sh\": permission denied": unknown.

    解决方法:给sh文件添加执行权限 RUN chmod +x /code/1.sh(+x中间不要加空格)

    3.standard_init_linux.go:207: exec user process caused "exec format error"

    两个原因:

    1. sh文件类型不是UNIX 解决方法:

    vi filename

    :set ff 回车后看到当前文件的fileformat格式

    :set ff=unix 回车后输入:wq保存文件,重新build镜像即可。

    1. sh没有添加#!/bin/bash 在1.sh文件第一行添加#!/bin/bash

    感觉V友们的帮助!

    第 2 条附言  ·  2019-06-20 15:12:19 +08:00

    PS:v2ex 增加附言的时候预览功能坏掉了, 所以上面的排版有点糟糕,sry (Chrom 版本 73.0.3683.103(正式版本) (64 位))

    9 条回复    2019-06-20 15:00:13 +08:00
    tony601818
        1
    tony601818  
       2019-06-18 18:11:07 +08:00 via Android
    用`&&`配合反斜杠换行转译,或者写 shell script
    HuHui
        2
    HuHui  
       2019-06-18 18:13:28 +08:00 via Android
    分俩镜像
    endoffight
        3
    endoffight  
       2019-06-18 18:19:02 +08:00 via Android   ❤️ 1
    1,托管程序,比如 supervisor
    2,分成两个容器
    3, 让第一个 cmd 后台运行,然后&&接 cmd2
    hzwjz
        4
    hzwjz  
       2019-06-18 18:21:08 +08:00
    你回顾一下,你是怎么在 terminal 中怎么执行那两个 py 文件的,把两命令按前后顺序放到 xx.sh 。再配合 entrypoint 即可

    [entrypoint]( https://docs.docker.com/engine/reference/builder/#entrypoint)
    liqingcan
        5
    liqingcan  
       2019-06-18 18:21:35 +08:00
    这两个都是在启动镜像的时候执行吗?是的话只能写 sh 脚本。如果不是的话。是在打包镜像的时候就可以执行的用 RUN 命令
    liqingcan
        6
    liqingcan  
       2019-06-18 18:22:09 +08:00
    @liqingcan 个人愚见
    ysjiang4869
        7
    ysjiang4869  
       2019-06-18 19:11:54 +08:00 via Android   ❤️ 1
    docker 官网推荐 supervisor 或者自己写一个脚本执行多程序;执行多程序不建议放到后台,因为可能要考虑日志和检测进程退出后退出容器,自己写过 shell 脚本如果需要可以给你参考
    caneman
        8
    caneman  
    OP
       2019-06-20 14:57:11 +08:00
    @ysjiang4869
    我创建了一个 1.sh, 里面写的是`python 1.py && python 2.py`在 linux 里面测试这个 sh 正常运行

    但是我在 Dockerfile 中设置 ENTRYPOINT ["/xx/1.sh"]的时候会报

    `standard_init_linux.go:207: exec user process caused "exec format error"`

    这个错误是怎么回事?查阅了一些资料,都说是 sh 文件类型的问题,但是我通过 vim 的 :set ff 查看了 1.sh 的文件类型,是

    unix 的没错,我想问一下是因为我的脚本写的有问题吗?不太懂这一块
    caneman
        9
    caneman  
    OP
       2019-06-20 15:00:13 +08:00
    @ysjiang4869 解决了,我的 sh 没有加`#!/bin/bash`这个.....感觉是不是就跟把 main 写成了 mian 一样的错误?...好低级...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6052 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 02:03 · PVG 10:03 · LAX 18:03 · JFK 21:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.