代码之家  ›  专栏  ›  技术社区  ›  Benyamin Jafari

如何使用Docker运行多个Python脚本和可执行文件?

  •  0
  • Benyamin Jafari  · 技术社区  · 6 年前

    我想创建一个包含两个Python包以及一个包含可执行文件的包的容器。


    这是我的主包(dockerized\u包)树:

    dockerized_project
    ├── docker-compose.yml
    ├── Dockerfile
    ├── exec_project
    │   ├── config
    │   │   └── config.json
    │   ├── config.json
    │   ├── gowebapp
    ├── pythonic_project1
    │   ├── __main__.py
    │   ├── requirements.txt
    │   ├── start.sh
    │   └── utility
    │       └── utility.py
    └── pythonic_project2
        ├── collect
        │   ├── collector.py
        ├── __main__.py
        ├── requirements.txt
        └── start.sh
    

    Dockerfile内容:

    FROM ubuntu:18.04
            
    RUN apt update
    RUN apt-get install -y python3.6 python3-pip python3-dev build-essential gcc \
        libsnmp-dev snmp-mibs-downloader
    
    RUN pip3 install --upgrade pip
    
    RUN mkdir /app
    WORKDIR /app
    COPY . /app
    
    WORKDIR /app/snmp_collector
    RUN pip3 install -r requirements.txt
    WORKDIR /app/proto_conversion
    RUN pip3 install -r requirements.txt
    
    WORKDIR /app/pythonic_project1
    CMD python3 __main__.py
    
    WORKDIR /app/pythonic_project2
    CMD python3 __main__.py
    
    WORKDIR /app/exec_project
    CMD ["./gowebapp"]
    

    version: '3'
    
    services:
      proto_conversion:
          build: .
          image: pc:2.0.0
          container_name: proto_conversion
    #      command: 
    #        - "bash  snmp_collector/start.sh"
    #        - "bash  proto_conversion/start.sh"
          restart: unless-stopped
          ports:
            - 8008:8008
          tty: true
    

    当我和 docker-compose up --build ,只有最后一个 CMD 命令运行。因此,我认为 命令 命令被杀死 Dockerfile 因为当我去掉最后两个 命令 效果很好。

    有没有办法在后台运行多个Python脚本和一个可执行文件?

    我也尝试过bash文件,但也没有成功。

    3 回复  |  直到 4 年前
        1
  •  8
  •   Farzad Vertigo    4 年前

    如前所述 documentation ,docker文件中只能有一个CMD,如果有更多,最后一个CMD将覆盖其他CMD并生效。 使用docker的一个关键点可能是隔离您的程序,因此乍一看,您可能希望将它们移动到单独的容器中,并使用共享卷或docker网络相互通信,但如果您确实需要它们在同一容器中运行,请将它们包含在bash脚本中,并用CMD替换最后一个CMD run.sh 将它们并排运行:

    #!/bin/bash
    
    exec python3 /path/to/script1.py &
    exec python3 /path/to/script2.py
    

    添加 COPY run.sh RUN chmod a+x run.sh 使其可执行。CMD应该是 CMD ["./run.sh"]

        2
  •  2
  •   frankegoesdown    6 年前

    通过入口点.sh

    ENTRYPOINT ["/docker_entrypoint.sh"]
    

    docker_entrypoint.sh

    #!/bin/bash
    
    set -e
    
    exec python3 not__main__.py &
    exec python3 __main__.py 
    

    符号 & 表示您在后台作为守护进程运行服务

        3
  •  1
  •   David Maze    6 年前

    最佳做法是将它们作为三个单独的容器发射。这是双重的事实,因为您需要三个独立的应用程序,将它们捆绑到一个容器中,然后尝试从中启动三个独立的东西。

    在每个项目子目录中创建一个单独的Dockerfile。这些可以更简单,特别是对于只包含已编译二进制文件的文件

    # execproject/Dockerfile
    FROM ubuntu:18.04
    WORKDIR /app
    COPY . ./
    CMD ["./gowebapp"]
    

    然后在你的 docker-compose.yml 文件有三个独立的节来启动容器

    version: '3'
    services:
      pythonic_project1:
        build: ./pythonic_project1
        ports:
          - 8008:8008
        env:
          PY2_URL: 'http://pythonic_project2:8009'
          GO_URL: 'http://execproject:8010'
      pythonic_project2:
        build: ./pythonic_project2
      execproject:
        build: ./execproject
    

    如果你真的不能重新排列Dockerfiles,你至少可以从同一个图像中启动三个容器 文件:

    services:
      pythonic_project1:
        build: .
        workdir: /app/pythonic_project1
        command: ./__main__.py
      pythonic_project2:
        build: .
        workdir: /app/pythonic_project1
        command: ./__main__.py
    

    • 如果您滚动自己的shell脚本并使用后台进程(如其他答案所示),它不会注意到其中一个进程是否死亡;在这里,您可以使用Docker的重新启动机制来重新启动单个容器。
    • 如果对其中一个程序进行了更新,则只能更新并重新启动该容器,其余容器保持不变。