[docker] 서비스를 시작한 후 Docker 컨테이너를 계속 실행하는 방법은 무엇입니까?

내가하려고하는 것과 똑같은 일을하는 많은 자습서를 보았지만 어떤 이유로 Docker 컨테이너가 종료됩니다. 기본적으로 Docker 컨테이너 안에 웹 서버와 몇 가지 데몬을 설정하고 있습니다. run-all.shDockerfile에서 CMD를 통해 실행 되는 bash 스크립트를 통해 마지막 부분을 수행합니다 . run-all.sh다음과 같이 보입니다 :

service supervisor start
service nginx start

그리고 다음과 같이 Dockerfile 내에서 시작합니다.

CMD ["sh", "/root/credentialize_and_run.sh"]

수동으로 작업을 실행할 때 서비스가 모두 올바르게 시작되는 것을 볼 수 있습니다 (예 : -i -t / bin / bash를 사용하여 이미지에 가져 오기). 이미지를 실행할 때 모든 것이 올바르게 실행되는 것처럼 보이지만 한 번 종료됩니다. 프로세스 시작을 마칩니다. 프로세스가 무기한으로 실행되기를 원하며 이해하는 한 컨테이너가 계속 실행되어야합니다. 그럼에도 불구하고을 실행 docker ps -a하면 다음을 볼 수 있습니다.

➜  docker_test  docker ps -a
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS                      PORTS               NAMES
c7706edc4189        some_name/some_repo:blah   "sh /root/run-all.sh   8 minutes ago       Exited (0) 8 minutes ago                        grave_jones

무엇을 제공합니까? 왜 종료 되나요? bash 스크립트 끝에 while 루프를 배치하여 유지할 수 있다는 것을 알고 있지만 종료하지 못하게하는 올바른 방법은 무엇입니까?



답변

이것이 실제로 Docker 컨테이너를 디자인하는 방법이 아닙니다.

도커 컨테이너를 설계 할 때, 당신은이 같은에만이 있음을 구축하는데있어 하나의 실행중인 프로세스 (즉, 하나 개 Nginx에 대한 컨테이너 및 supervisord 또는 응용 프로그램이 실행중인 하나가 있어야합니다) 또한 해당 프로세스는 포 그라운드에서 실행되어야합니다.

컨테이너는 프로세스 자체가 종료 될 때 “종료”됩니다 (이 경우 해당 프로세스는 bash 스크립트입니다).


그러나 실제로 Docker 컨테이너에서 여러 서비스를 실행 해야하는 경우 의사 초기화 프로세스로 사용 되는 “Docker Base Image”로 시작하는 것을 고려하십시오 runit( runitNginx 및 Supervisor가 실행되는 동안 온라인 상태로 유지됨). 다른 프로세스가 자신의 작업을 수행하는 동안

그들은 상당한 문서를 가지고 있으므로, 당신은 당신이 합리적으로 쉽게하려는 것을 달성 할 수 있어야합니다.


답변

Dockerfile을 사용하는 경우 다음을 시도하십시오.

ENTRYPOINT ["tail", "-f", "/dev/null"]

(이것은 분명히 개발 목적으로 만 사용됩니다. 예를 들어 nginx …와 같은 프로세스를 실행하지 않는 한 컨테이너를 살아있게 유지할 필요는 없습니다.)


답변

방금 같은 문제가 있었고 -tand 및 -d플래그로 컨테이너를 실행하면 계속 실행 된다는 것을 알았습니다 .

docker run -td <image>

다음은 플래그에 따라 수행되는 작업입니다 docker run --help.

-d, --detach=false         Run container in background and print container ID
-t, --tty=false            Allocate a pseudo-TTY

가장 중요한 것은 -t깃발입니다. -d컨테이너를 백그라운드에서 실행할 수 있습니다.


답변

종료하는 이유는 쉘 스크립트가 PID 1로 먼저 실행되고 완료되면 PID 1이 없어지고 docker는 PID 1이있는 동안에 만 실행되기 때문입니다.

수퍼바이저를 사용하여 모든 작업을 수행 할 수 있습니다. “-n”플래그를 사용하여 실행하면 데몬으로 초기화하지 않도록 지시되므로 첫 번째 프로세스로 유지됩니다.

CMD ["/usr/bin/supervisord", "-n"]

그리고 supervisord.conf :

[supervisord]
nodaemon=true

[program:startup]
priority=1
command=/root/credentialize_and_run.sh
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=false
startsecs=0

[program:nginx]
priority=10
command=nginx -g "daemon off;"
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.log
autorestart=true

그런 다음 원하는만큼 다른 프로세스를 가질 수 있으며 필요한 경우 감독자가 프로세스 재시작을 처리합니다.

그렇게하면 nginx와 php5-fpm이 필요할 수 있으며 supervisord를 사용할 수없는 경우 supervisord를 사용할 수 있습니다.


답변

catbro @ Sa’ad가 언급 한대로 아무런 주장없이 평범하게 실행할 수 있습니다 . 컨테이너가 실제로 작동하도록 유지하십시오 (실제로 사용자 입력을 기다리는 것만 없음) (Jenkins의 Docker 플러그인은 동일한 작업을 수행합니다)


답변

daemon off;nginx.conf 를 추가 하거나 CMD ["nginx", "-g", "daemon off;"]공식 nginx 이미지에 따라 실행하십시오.

그런 다음 다음을 사용하여 수퍼바이저를 서비스로 실행하고 nginx를 포 그라운드 프로세스로 실행하여 컨테이너가 종료되지 않도록하십시오.

service supervisor start && nginx

경우에 따라 컨테이너에 프로세스가 두 개 이상 있어야하므로 컨테이너에 프로세스가 정확히 하나만 있으면 작동하지 않아 배포시 더 많은 문제가 발생할 수 있습니다.

따라서 절충점을 이해하고 그에 따라 결정해야합니다.


답변

자극:

도커 컨테이너 내에서 여러 프로세스를 실행하는 데 아무런 문제없습니다 . 도커를 경량 VM으로 사용하는 것을 좋아한다면 그렇게하십시오. 다른 사람들은 응용 프로그램을 마이크로 서비스로 나누기를 좋아합니다. 내 생각 : 하나의 컨테이너에 램프 스택? 그냥 좋아요

대답:

A를 스틱 좋은 기본 이미지phusion의 기본 이미지 . 다른 사람이있을 수 있습니다. 의견을주세요.

그리고 이것은 또 다른 감독자에게 간청입니다. phusion base 이미지는 cron 및 locale setup과 같은 다른 것 외에도 감독자를 제공하기 때문입니다. 그런 가벼운 VM을 실행할 때 설정하고 싶은 것들. 가치가있는 것은 컨테이너에 ssh 연결을 제공합니다.

이 기본 docker run 문을 실행하면 phusion 이미지 자체가 시작되고 계속 실행됩니다.

moin@stretchDEV:~$ docker run -d phusion/baseimage
521e8a12f6ff844fb142d0e2587ed33cdc82b70aa64cce07ed6c0226d857b367
moin@stretchDEV:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS
521e8a12f6ff        phusion/baseimage   "/sbin/my_init"     12 seconds ago      Up 11 seconds

또는 죽은 간단한 :

기본 이미지가 당신을위한 것이 아닌 경우 … 빠른 CMD가 계속 실행되도록하려면 bash에 대해 다음과 같이 가정하십시오.

CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

또는 busybox의 경우 :

CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

a에서 즉시 종료 되기 때문에 좋습니다 docker stop. 컨테이너가 나오기까지 평범 sleep하거나 cat몇 초가 걸립니다.