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

时间:2018-12-25 08:46:30

标签: python bash docker docker-compose

我想创建一个包含两个Python软件包和一个具有可执行文件的软件包的容器。


这是我的主包(dockerized_pa​​ckeg)树:

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

MAINTAINER Benyamin Jafari <benyamin@infravision.ir>

ENV PYTHONUNBUFFERED 1

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

docker-compose内容:

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命令,并且我认为CMD中的先前Dockerfile命令将被杀死,因为当我评论时最后两个CMD,第一个CMD可以正常工作(CMD)。

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

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

3 个答案:

答案 0 :(得分:2)

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

#!/bin/bash

exec python3 /path/to/script1.py &
exec python3 /path/to/script2.py

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

答案 1 :(得分:1)

通过entrypoint.sh尝试

for i = 0 to size 
    print array[0]

ENTRYPOINT ["/docker_entrypoint.sh"]

docker_entrypoint.sh

符号#!/bin/bash set -e exec python3 not__main__.py & exec python3 __main__.py 表示您在后台将服务作为守护程序运行

答案 2 :(得分:1)

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

在每个项目子目录中创建一个单独的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

如果您确实无法重新排列Dockerfile,则可以至少从docker-compose.yml文件中的同一映像启动三个容器:

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

使用多个容器和图像来构建项目有几个很好的理由:

  • 如果您滚动自己的shell脚本并使用后台进程(如其他答案所述),它只会注意到其中一个进程是否死亡;在这里,您可以使用Docker的重启机制来重启单个容器。
  • 如果您对其中一个程序进行了更新,则只能更新和重新启动该单个容器,其余的保持不变。
  • 如果您使用更复杂的容器协调器(Docker Swarm,Nomad,Kubernetes),则不同的组件可以在不同的主机上运行,​​并且在单个节点上需要较小的CPU /内存资源块。
  • 如果您使用更复杂的容器协调器,则可以分别扩展使用更多CPU的组件。