Страницы

Поиск по вопросам

понедельник, 24 февраля 2020 г.

Как исполнить скрипт при запуске docker-контейнера?

#bash #docker


Здравствуйте!

Вопрос, возможно, несколько избит, но ответа на него я не нашел. А похожие вопросы
на тостере, как в и гугле не помогли. 
Я буду премного благодарен тем людям, что уделят немного своего времени и дадут развернутый
ответ!

И так, задача минимум - запустить apache при старте контейнера

Задача максимум - выполнить bash скрипт при старте контейнера

Я опишу варианты которые я пробовал.

1. Сборка простейшего образа и запуск контейнера из консоли

Dockerfile
    FROM ubuntu:14.04

RUN apt-get update && \
    apt-get install -y apache2


В консоли:
    sudo docker build -t apache .
    sudo docker run -dit --name cont_apache apache /bin/bash service   apache2 start

В ответ код контейнера, docker ps чист. docker logs cont_apache сообщает о запуске
апача - Starting web server apache2 ...
Но сам контейнер почему-то умирает. хотя флаг -d установлен. 

Попытался:
    sudo docker run -dit --name cont_apache apache service apache2 start

Результат точно такой же.

2. Сборка образа и запуск апача при помощи CMD

Dockerfile:
    FROM ubuntu:14.04

RUN apt-get update && \
    apt-get install -y apache2

CMD ["service" "apache2", "start"]


В консоли:
    sudo docker build -t apache .
    sudo docker run -dit --name cont_apache apache /bin/bash service apache2 start 

Контейнер запущем, висит как демон, перехожу в контейнер:
root@2a97628fd78b:/# service apache2 status
* apache2 is not running
Апач не запустился.
Почему?

3. Сборка образа с проброской bash скрипта и его выполнение

Dockerfile:
    FROM ubuntu:14.04

RUN apt-get update && \
    apt-get install -y apache2 

COPY ./apache2_start.sh /root/apache2_start.sh

CMD ["chmod", "777", "/root/apache2_start.sh"]

CMD ["/root/apache2_start.sh"]


Script apache2_start.sh:
    #!/bin/bash

service apache2 start
echo "127.0.0.1"


В консоли:
    sudo docker build -t apache .
    sudo docker run -dit --name cont_apache apache 

В docker ps контейнера нет. В логах docker logs cont_apache:
     * Starting web server apache2                                              
   AH00558: apache2: Could not reliably determine the server's fully qualified domain
name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
     * 
    127.0.0.1

Пробовал также с запуском bash из консоли:
    sudo docker run -dit --name cont_apache apache /bin/bash

В результате контейнер висит в docker ps. Docker logs conf_apache чист.

А в самом контейнере:
    root@d2c9831773a9:/# service apache2 status
    * apache2 is not running

Итог.

Я попытался добиться нужного результата разными способами, но ни одним у меня не вышло. 

Очевидно, что я допускаю ошибки в работе с докером.

Я буду очень! благодарен за конструктивную помощь в данном вопросе как в целом, так
и что в каком конкретном случае я делал не так.

Конечно, эти примеры высосаны из пальца, и можно найти кучу примеров запуска окружения
при помощи docker compose. Но моя цель разобраться в вопросе, и уже в дальнейшем использовать
всякие крутые штуки вроде docker compose
    


Ответы

Ответ 1



Докер-контейнер - это один процесс, обернутый в изолированную среду. Этот процесс может порождать дочерние процессы, но основной постулат остается одинаковым: время жизни контейнера - это время жизни процесса, указанного в ENTRYPOINT/CMD. Насколько понимаю, команда apache2 service start попытается запустить апач в фоновом режиме и тут же закончит свое выполнение; как только докер увидит, что процесс закончился, он прибьет контейнер. Таким образом, ваша конечная цель - выполнить в начале скрипта требуемые действия, а потом сделать так, чтобы он выполнялся все время жизни приложения (в случае с апачем - условно бесконечно). Проще всего это сделать следующим образом: выполнить требуемые действия последней командой в шелл-скрипте запустить апач с отключенным фоновым режимом (-DFOREGROUND), предварив команду инструкцией exec. Эта инструкция позволит текущему процессу (выполняющемуся шелл-скрипту) стать процессом, вызванным exec. После этого ctrl-c и прочие плюшки будут отправляться на обработку напрямую апачу. пример такой работы можно увидеть прямо в официальном изображении library

Ответ 2



Если уже есть подходящий официальный image, то лучше использовать его, а не брать ubuntu и туда делать apt-get install. Для Apache: https://hub.docker.com/_/httpd/ Можно сделать свой image, который наследуется от него, а можно запускать его напрямую. Вероятно, нужен ещё php. Для этого можно взять image php:apache https://hub.docker.com/_/php/ Если нужны ещё другие приложения, например, MySQL, то по идеологии Docker надо запускать их в отдельном контейнере.

Ответ 3



По идеологии docker запустить bash скрипт при старте контейнера не получится, т.к. в нем не обрабатывается init как в хостовой машине. Для автозапуска процессов нужно использовать DockerFile с указанными в директиве CMD процессами. Или можно сделать следующим образом: run контейнера делать с ключом --restart unless-stopped, тогда контейнер будет стартовать при запуске системы. А для запуска процессов в контейнере написать простой баш скрипт на хостовой машине вроде этого: #!/bin/bash sudo docker exec service nginx start sudo docker exec service php7.2-fpm start sudo docker exec service mysql start Стартует nginx, php-fpm и mysql в указанном контейнере. Можно добавить своего пользователя в группу docker для исключения "sudo" и поставить скрипт в автозапуск init хостовой машины

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

Отправить комментарий