Как сделать так, чтобы контейнер docker работал непрерывно?

#python #docker #shell #docker-compose

Вопрос:

У меня есть образ докера, который на самом деле является сервером для устройства. Он запускается из скрипта Python, и я сделал .ш, чтобы запустить его. Однако всякий раз, когда я запускаю его, он говорит, что он выполнен и заканчивается (сервер вышел с кодом 0). Единственный способ, которым я заставил его работать,-это через docker-compose, когда я запускаю его как отдельный контейнер, затем вхожу в контейнер через bin/bash и выполняю сценарий запуска (ранее упомянутый .sh) из него вручную, затем выхожу из контейнера.

После этого все работает по назначению, но проблема возникает при перезагрузке сервера. Мне снова приходится делать это вручную.

Испытывал ли кто-нибудь еще что-нибудь подобное? Если да, то как я могу это исправить?

Файл, запускающий сервер (start.sh):

 #!/bin/sh
python source/server/main.pyc amp;
python source/server/main_socket.pyc amp;
python source/server/main_monitor_server.pyc amp;
python source/server/main_status_server.pyc amp;
python source/server/main_events_server.pyc amp;
 

Докерфайл:

 FROM ubuntu:trusty

RUN mkdir -p /home/server

COPY server /home/server/

EXPOSE 8854

CMD [ /home/server/start.sh ] 
 

Докер Сочиняет:

 version: "3.9"
services:
  server:
    tty: yes
    image: deviceserver:latest
    container_name: server
    restart: always
    ports:
      - "8854:8854"
    deploy:
      resources:
        limits:
          memory: 3072M
 

Комментарии:

1. Сценарии, которые вы запускаете в своих контейнерах, должны регистрироваться в stdout и не запускаться как демон или фоновые задачи. Все ли пять из этих процессов должны быть запущены? Если это так, вам, возможно, следует подумать о запуске отдельного контейнера для каждого процесса

2. @IainShelvington Да, к сожалению, все они должны запускаться в одном контейнере. Это то, что я не могу изменить.

3. Вы можете добавить tail -f /dev/null в качестве последней строки в свой скрипт. Похоже, это популярный способ создать процесс, который не заканчивается.

4. Почему вы не можете это изменить? Может быть, что-то подобное supervisor может сработать для вас?

Ответ №1:

Это не проблема с docker-compose. Ваш контейнер docker не должен возвращаться (т. е. блокировать) даже при запуске с помощью простого docker run .

Для этого ваш CMD должен работать на переднем плане.

Я думаю, проблема в том, что вы start.sh возвращаетесь, а не блокируете. Вы пытались удалить последнее » amp; » из своего скрипта (я не знаком с python и с тем, что это за разные процессы)?

Комментарии:

1. Это тоже не сработало… @Бонана

2. даже с изменением синтаксиса, предложенным @David Maze, чтобы добавить кавычки: [ «/home/server/start.sh» ] ?

Ответ №2:

Вы можете добавить команду сна в конце вашего start.sh .

 #!/bin/sh
python source/server/main.pyc amp;
python source/server/main_socket.pyc amp;
python source/server/main_monitor_server.pyc amp;
python source/server/main_status_server.pyc amp;
python source/server/main_events_server.pyc amp;
while true
do
  sleep 1;
done
 

Комментарии:

1. Попробовал это, к сожалению, не сработало.

Ответ №3:

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

Следствием этого является то, что основная команда контейнера должна быть процессом переднего плана; но также и то, что вы можете запускать несколько контейнеров с одного и того же изображения с помощью разных команд. В Compose вы можете переопределить значение command: отдельно для каждого контейнера. Так, например, вы можете указать:

 version: '3.8'
services:
  main:
    image: deviceserver:latest
    command: ./main.py
  socket:
    image: deviceserver:latest
    command: ./main_socket.py
  et: cetera
 

Если вы пытаетесь скопировать и вставить именно docker-compose.yml этот файл, обязательно установите a WORKDIR в файле Dockerfile, чтобы сценарии находились в текущем каталоге, убедитесь, что сценарии являются исполняемыми ( chmod x в вашем исходном репозитории), и убедитесь, что они начинаются со строки «shebang» #!/usr/bin/env python3 . Вам не нужно python нигде прямо говорить.

 FROM python:3.9       # not a bare Ubuntu image
WORKDIR /home/server  # creates the directory too
COPY server ./        # don't need to duplicate the directory name here
RUN pip install -r requirements.txt
EXPOSE 8854           # optional, does almost nothing
CMD ["./main.py"]     # valid JSON-array syntax; can be overridden
 

В показанной вами настройке есть две основные проблемы. Массив CMD JSON не является синтаксически допустимым (сама команда таковой не "quoted" является), поэтому Docker запустит его как команду оболочки; [ является псевдонимом для test(1) и немедленно завершит работу. Если вы успешно запустите сценарий, он запустит несколько фоновых процессов, а затем завершит работу, но поскольку сценарий является основной командой контейнера, это также приведет к завершению работы контейнера. Запуск набора контейнеров с одним процессом, как правило, проще в управлении и масштабировании, чем попытка втиснуть несколько процессов в один контейнер.