Как запустить Docker-контейнеры из сценария оболочки на основе аргументов - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть приложение на python, которое имеет следующую структуру:

./DB  
./lib  
./docker-compose.yml  
./Dockerfile  
./module1.py  
./module2.py  
./module3.py  
./app_run.sh  
./requirements.txt  

Что я хочу получить

  • Сервер Mysql работает в отдельном контейнере,
  • Образ докера приложения.
  • Скрипты модулей работают отдельно как контейнеры из app_run.sh.

Мой образ приложения имеет размер около 1,5 ГБ, поэтому я хочу получить один образ приложения с возможностью запуска нескольких контейнеров только с одним определенным модулем. Чтобы я мог запустить контейнер с помощью скрипта module1.py (или любого другого) или множества таких скриптов.

Таким образом, я надеюсь ускорить процесс, так как не будет необходимости каждый раз создавать образ приложения, только для подключения к нему.

Зачем мне запускать такие контейнеры из сценария оболочки приложения.
Сценарий оболочки получает необходимые параметры, такие как URL и токен, из внешнего источника, которые затем используются в модулях.

Сценарий оболочки имеет следующую структуру:

#!/bin/sh

ip=$1
url=$2
token=$3

folder="./temp/"
folder_oss='./temp/DB/TEST/'
db_folder="./temp/DB"
app="./"

name=$(date '+%Y%m%d%H%M%S')

cd $folder && mkdir -p "$folder$name"
folder="$folder$name"
cd $app

if [ $ip = 1 ]; then
python3.6 ./module1.py -u $url -t $token -f $folder -d $db_folder 
 status=${PIPESTATUS};
elif [ $ip = 3 ]; then
python3.6 ./module2.py -u $url -t $token -f $folder |& tee "$folder/logtemp.txt"
status=${PIPESTATUS};
elif [ $ip = 7 ]; then
python3.6 ./module.py -u $url -t $token -f $folder -d $db_folder |& tee "$folder/load_logtemp.txt"
status=${PIPESTATUS};
else
   echo "Error while predicting"
   status=1;
fi  

Я полагаю, что вместо python3.6 ./module1.py я должен написать что-то вроде запуска контейнера Docker. Но как мне указать эти модули как отдельные контейнеры?

В настоящее время мой Dockerfile выглядит следующим образом:

FROM python:3.6
COPY . /app
WORKDIR /app
RUN pip freeze > requirements.txt
EXPOSE 7524
CMD ["./app_run.sh", "1","link/to/settings.json, "token"]  

И docker_compose.yml:

version: "2"
services:
   app:
     build: .
     environment:
        - DB_HOST=mysql
        - DB_PORT=7524
     ports:
        - 8080:8080
     depends_on:
        - mysql

   mysql:
     image: mysql:latest
     restart: always
     environment:
        - MYSQL_USER=user
        - MYSQL_ROOT_PASSWORD=54321
     ports:
        - 7524:3303
     volumes:
       - my-db:/var/lib/mysql

 volumes:
    my-db:

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Переместить app_run.sh к точке входа и передать имя модуля и IP, токен и т. Д. На CMD. Ваш Dockerfile будет выглядеть как

FROM python:3.6
COPY . /app
WORKDIR /app
EXPOSE 7524
RUN chmod +x app_run.sh
ENTRYPOINT ["./app_run.sh"]
CMD ["1","link/to/settings.json","token"] 

, а затем обрабатывать эти аргументы в entrypoint, в вашем случае это app_run.sh`

#!/bin/sh
ip=$1
url=$2
token=$3
echo "IP is $ip , URL is $url , token is $token"
mkdir temp
folder="./temp/"
folder_oss='./temp/DB/TEST/'
db_folder="./temp/DB"
app="./"

name=$(date '+%Y%m%d%H%M%S')

cd $folder
mkdir -p "$folder$name"
folder="$folder$name"
cd $app

if [ $ip = 1 ]; then
python3.6 ./module1.py -u $url -t $token -f $folder -d $db_folder 
 status=${PIPESTATUS};
elif [ $ip = 3 ]; then
python3.6 ./module2.py -u $url -t $token -f $folder  
status=${PIPESTATUS};
elif [ $ip = 7 ]; then
python3.6 ./module.py -u $url -t $token -f $folder -d $db_folder 
status=${PIPESTATUS};
else
   echo "Error while predicting"
   status=1;
fi 

Запомните одну вещь, если Python работает на переднем планеи его длительный процесс, тогда его статус не будет достигнут status=${PIPESTATUS};

Так что если вы хотите запустить контейнер, используя IP 3 , все, что вам нужно

docker run -it --rm my_image "3" "link/to/settings.json" "token

по умолчанию он будет работать с IP 1.

0 голосов
/ 07 ноября 2019

Одним из вариантов будет переопределение команды в docker-compose.yml (см. https://docs.docker.com/compose/compose-file/compose-file-v2/#command)

Вы даже можете сделать так, чтобы она взяла и переменную окружения.

Что-то вроде:

services:
  app:
    ...
    command:
      - "./app_run.sh"
      - ${IP}
      - ${URL}
      - ${TOKEN}

Затем можно запустить цикл с:

$ IP=1 URL="link/to/settings.json" TOKEN=token docker-compose up

Также может быть полезно смонтировать файлы moduleX.py в контейнер, поэтому вам не придется перестраивать его, если добавляете больше модулей. Это, вероятно, было бы проще, если бы эти файлы модулей были в их собственной папке. Тогда вы могли бы использовать что-то вроде (в docker-compose.yml):

services:
  app:
    ...
    volumes: ./modules:/app/modules

См. Также документы по томам: https://docs.docker.com/compose/compose-file/compose-file-v2/#volumes

...