Docker 컨테이너에서 여러 프로그램을 실행할 수 있습니까?


150

데스크톱의 사용자에게 실행되는 응용 프로그램을 배포하는 시점에서 Docker 주위에 머리를 감 으려고합니다. 내 응용 프로그램은 플라스크 웹 응용 프로그램 및 mongo 데이터베이스입니다. 일반적으로 VM에 설치하고 호스트 포트를 게스트 웹 앱으로 전달합니다. Docker를 사용 해보고 싶지만 둘 이상의 프로그램을 어떻게 사용할 것인지 잘 모르겠습니다. 설명서에는 ENTRYPOINT 만있을 수 있으므로 Mongo와 플라스크 응용 프로그램을 어떻게 가질 수 있습니까? 아니면 별도의 컨테이너에 있어야합니까?이 경우 서로 어떻게 대화하고 어떻게 앱을 쉽게 배포 할 수 있습니까?


2
(? 단일 프로세스 ..) :에 스팟 .. 고정 표시기가 그렇게 인기가 왜 궁금한데 - 그러나하자가 답변 .. 우리에게 무엇을 참조
javadba

답변:


120

하나의 ENTRYPOINT 만있을 수 있지만 해당 대상은 일반적으로 필요한 많은 프로그램을 시작하는 스크립트입니다. 예를 들어 Supervisord 또는 이와 유사한 것을 추가로 사용하여 단일 컨테이너 내에서 여러 서비스를 시작할 수 있습니다. 이것은 단일 컨테이너 내에서 mysql, apache 및 wordpress를 실행하는 도커 컨테이너의 예입니다 .

예를 들어, 단일 웹 응용 프로그램에서 사용하는 데이터베이스가 하나 있습니다. 그러면 단일 컨테이너에서 둘 다 실행하는 것이 더 쉬울 것입니다.

둘 이상의 응용 프로그램에서 사용하는 공유 데이터베이스가있는 경우 데이터베이스를 자체 컨테이너에서 실행하고 응용 프로그램을 각각 자체 컨테이너에서 실행하는 것이 좋습니다.

응용 프로그램이 서로 다른 컨테이너에서 실행될 때 서로 통신 할 수있는 방법은 적어도 두 가지입니다.

  1. 노출 된 IP 포트를 사용하여 연결하십시오.
  2. 최신 도커 버전 은 연결을 지원 합니다.

1
Docker의 새 버전이 이제 Docker 컨테이너 네트워크를 지원하는 것 같습니다 .
jpierson

도커 이제 등 자동 재시작 = 사실, stdout_logfile, stderr_logfile 한 번 봐 걸릴 각 프로세스에 대해 동작을 sepcify 할 수 있도록 관리자를 실행하는 지원 docs.docker.com/engine/admin/using_supervisord
안드레아스 Lundgren은

4
이 예제에서 동일한 컨테이너에서 웹 애플리케이션과 mongodb를 실행하지 않는 것이 좋습니다. Docker에는 supervisord 또는 비슷한 init-like 프로세스의 유스 케이스가 있지만 이것은 일부가 아닙니다. docker-compose를 사용하여 두 서비스를 별도의 컨테이너에서 실행하는 것이 더 간단합니다.
nicolas-van

@ nicolas-van 왜 더 간단합니까? db가 죽으면 전체를 다시 시작하지 않고 db의 컨테이너를 다시 시작할 수 있기 때문입니까?
brillout

동일한 머신의 응용 프로그램은 Unix 도메인 소켓을 통해 통신 할 수도 있습니다 . 최고 성능 보장.
회의적인 Jule

21

LAMP 스택, Mongo DB 및 자체 서비스를 실행 해야하는 비슷한 요구 사항이 있습니다.

Docker는 OS 기반 가상화이므로 실행중인 프로세스 주위에서 컨테이너를 격리하므로 FOREGROUND에서 실행되는 프로세스가 하나 이상 필요합니다.

따라서 시작점으로 고유 한 시작 스크립트를 제공하므로 시작 스크립트는 확장 된 Docker 이미지 스크립트가되며 , 최종 도큐먼트 서비스 가 시작되는 시점부터 끝까지 너무 많은 서비스를 쌓을 수있는 확장 된 Docker 이미지 스크립트가됩니다.

따라서 Docker 이미지 파일에는 맨 아래에 두 줄이 있습니다.

COPY myStartupScript.sh /usr/local/myscripts/myStartupScript.sh
CMD ["/bin/bash", "/usr/local/myscripts/myStartupScript.sh"]

내 스크립트에서 모든 MySQL, MongoDB, Tomcat 등을 실행합니다. 결국 Apache를 포 그라운드 스레드로 실행합니다.

source /etc/apache2/envvars
/usr/sbin/apache2 -DFOREGROUND

이를 통해 모든 서비스를 시작하고 마지막 서비스가 포 그라운드에서 시작된 상태에서 컨테이너를 활성 상태로 유지할 수 있습니다

그것이 도움이되기를 바랍니다.

업데이트 :이 질문에 마지막으로 답변 한 이후 Docker compose 와 같은 새로운 것들이 나타났습니다.이 서비스는 자체 컨테이너에서 각 서비스를 실행하는 데 도움이 될 수 있지만 모든 서비스를 해당 서비스 간의 종속성으로 묶고 docker-compose 및 필요에 맞지 않는 한 더 우아하게 사용하십시오.


6

동일한 컨테이너에서 두 서비스를 모두 실행하도록 권장하는 일부 이전 솔루션에 동의하지 않습니다. 설명서에 권장되지 않음이 명확하게 명시되어 있습니다 .

일반적으로 컨테이너 당 하나의 서비스를 사용하여 관심 영역을 분리하는 것이 좋습니다. 이 서비스는 여러 프로세스로 분기 될 수 있습니다 (예 : Apache 웹 서버는 여러 작업자 프로세스를 시작 함). 여러 프로세스를 사용하는 것이 좋지만 Docker를 최대한 활용하려면 하나의 컨테이너가 전체 애플리케이션의 여러 측면을 담당하지 않도록하십시오. 사용자 정의 네트워크 및 공유 볼륨을 사용하여 여러 컨테이너를 연결할 수 있습니다.

수퍼바이저 또는 유사한 프로그램에 대한 유용한 사용 사례가 있지만 웹 애플리케이션 + 데이터베이스 실행은 그 일부가 아닙니다.

docker-compose 를 사용 하여 다른 컨테이너로 여러 컨테이너를 조율해야합니다.


2
이것은 답변이 아니라 의견입니다. 이 입장을 뒷받침 할 설명 및 / 또는 링크 추가를 고려하십시오. 그렇지 않으면 도움이되지 않습니다.
Ivan Ivanov

1
이것은 그러한 유스 케이스에서 줄 수있는 최선의 명령은 docker-compose를 사용하는 것입니다. 어쨌든, 당신은 내가 공식적인 명령에 더 많은 링크를 줄 수 있다고 옳습니다. 업데이트하겠습니다.
nicolas-van

질문은 하나의 컨테이너에서 2 개의 프로세스를 실행하는 것에 관한 것이므로 모범 사례는 신경 쓰지 않습니다. 예를 들겠습니다 : PhotonOS 기반 이미지와 java 프로세스 내에서 rabbitmq를 실행해야했습니다 ... 그래서 입력 스크립트를 사용하여 ENTRYPOINT로 사용했습니다 :)
Vallerious

원래 질문은 Docker 컨테이너에서 두 프로세스를 실행하는 기술적 타당성에 대한 일반적인 질문이 아닙니다. MongoDB 데이터베이스와 함께 Python 응용 프로그램을 배포하는 특정 사용 사례를 설명합니다. 그리고 해당 사용 사례의 경우 가장 좋은 방법은 단일 컨테이너의 사용을 권장하지 않고 docker-compose의 사용을 권장하는 것입니다.
nicolas-van

5

그것들은 별도의 컨테이너에있을 수 있으며 실제로 응용 프로그램이 더 큰 환경에서 실행되도록 계획되어 있다면 아마도 그럴 것입니다.

- 부두 노동자의 v0.6.5 +에서, 도커 자체에 내장 된 그 도움에 새로운 시설이 있지만 멀티 컨테이너 시스템은 필요한 모든 종속성을 가져올 수 있도록 좀 더 오케스트레이션을 필요로 링크하기는 . 그러나 다중 머신 솔루션을 사용하면 여전히 Docker 환경 외부에서 배열해야합니다.

두 개의 다른 컨테이너를 사용하는 경우 두 부분은 여전히 ​​TCP / IP를 통해 통신하지만 포트가 특별히 잠겨 있지 않은 경우 (여러 사본을 실행할 수 없으므로 권장하지 않음) 새 포트를 전달해야합니다. 데이터베이스가 Mongo와 통신 할 수 있도록 응용 프로그램에 노출되었습니다. 이것은 다시 연결이 도움이 될 수있는 것입니다.

모든 종속성이 동일한 컨테이너에있는 더 단순하고 작은 설치의 경우 처음에 ENTRYPOINT라고하는 프로그램에 의해 데이터베이스와 Python 런타임이 모두 시작되는 것도 가능합니다. 이것은 쉘 스크립트 나 다른 프로세스 컨트롤러처럼 간단 할 수 있습니다. Supervisord 는 매우 유명하며 공개 Dockerfile에 많은 예제가 있습니다.


3

나는 두 개의 컨테이너를 사용하는 것이 바람직하다는 다른 답변에 동의하지만, 단일 컨테이너에 여러 서비스를 묶는 마음이 있다면 감독자와 같은 것을 사용할 수 있습니다.

Hipache 예를 들어, 포함 된 Dockerfile는 supervisord를 실행하고 hipache 및 레디 스 서버 모두에 대한 파일 supervisord.conf 지정하는 실행 할 수 있습니다.


2

Docker는이 를 수행하는 방법에 대한 몇 가지 예 를 제공 합니다. 경량 옵션은 다음과 같습니다.

모든 명령을 랩퍼 스크립트에 넣고 테스트 및 디버깅 정보로 완성하십시오. 랩퍼 스크립트를로 실행하십시오 CMD. 이것은 매우 순진한 예입니다. 먼저 래퍼 스크립트 :

#!/bin/bash

# Start the first process
./my_first_process -D
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start my_first_process: $status"
  exit $status
fi

# Start the second process
./my_second_process -D
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start my_second_process: $status"
  exit $status
fi

# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container will exit with an error
# if it detects that either of the processes has exited.
# Otherwise it will loop forever, waking up every 60 seconds

while /bin/true; do
  ps aux |grep my_first_process |grep -q -v grep
  PROCESS_1_STATUS=$?
  ps aux |grep my_second_process |grep -q -v grep
  PROCESS_2_STATUS=$?
  # If the greps above find anything, they will exit with 0 status
  # If they are not both 0, then something is wrong
  if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
    echo "One of the processes has already exited."
    exit -1
  fi
  sleep 60
done

다음은 Dockerfile입니다.

FROM ubuntu:latest
COPY my_first_process my_first_process
COPY my_second_process my_second_process
COPY my_wrapper_script.sh my_wrapper_script.sh
CMD ./my_wrapper_script.sh

2

을 사용하여 포 그라운드에서 2 개의 프로세스를 실행할 수 있습니다 wait. 다음 내용으로 bash 스크립트를 만드십시오. 예 start.sh:

# runs 2 commands simultaneously:

mongod & # your first application
P1=$!
python script.py & # your second application
P2=$!
wait $P1 $P2

Dockerfile에서 시작하십시오.

CMD bash start.sh

0

전용 스크립트가 너무 많은 오버 헤드처럼 보이면를 사용하여 별도의 프로세스를 명시 적으로 생성 할 수 있습니다 sh -c. 예를 들면 다음과 같습니다.

CMD sh -c 'mini_httpd -C /my/config -D &' \
 && ./content_computing_loop
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.