도커 컨테이너를 실행할 때 서비스를 자동으로 시작하는 방법은 무엇입니까?


157

컨테이너에 MySQL 서버를 설치 하는 Dockerfile 이 있는데 다음과 같이 시작합니다.

sudo docker run -t -i 09d18b9a12be /bin/bash

그러나 MySQL 서비스가 자동으로 시작되지 않으므로 컨테이너 내에서 수동으로 실행해야합니다.

service mysql start

도커 컨테이너를 실행할 때 MySQL 서비스를 자동으로 시작하려면 어떻게합니까?


1
아니, 하나 개의 간단한 서비스를 위해, 관리자는 그것을 시작 사용자에 대한 복잡하게 필요하지 않습니다
래리 카이

8
더 이상 존재하지 않는 파일에 연결하는 대신 여기에 dockerfile을 복사 할 수 있습니다.
neo112

supervisord의 도커 기사는 다음과 같습니다. docs.docker.com/config/containers/multi-service_container && tail 명령을 사용하여 서비스를 작동 시켰지만 도커에 "--cap-add SYS_PTRACE"를 추가해야했습니다. 명령을 실행하십시오.
Ted Cahall

답변:


205

먼저, 당신 의 문제 가 있습니다 Dockerfile:

RUN service mysql restart && /tmp/setup.sh

Docker 이미지는 실행중인 프로세스를 저장하지 않습니다. 따라서 RUN명령은 docker build단계 중에 만 실행 되고 빌드가 완료된 후에 중지됩니다. 대신 아래와 같이 CMD또는 ENTRYPOINT명령을 사용하여 컨테이너를 시작할 때 명령을 지정해야 합니다.

CMD mysql start

둘째, 도커 컨테이너는 계속 실행하기 위해 프로세스 (마지막 명령)가 필요합니다. 그렇지 않으면 컨테이너가 종료 / 중지됩니다. 따라서 일반 service mysql start명령은 Dockerfile에서 직접 사용할 수 없습니다.

해결책

프로세스를 계속 실행하는 세 가지 일반적인 방법이 있습니다.

  • 그런 다음에 service명령을 사용 하고 끝이 아닌 명령을 추가하십시오.tail -F

    CMD service mysql start && tail -F /var/log/mysql/error.log
    

출력 된 로그를 docker가 액세스 할 수 있도록 단일 서비스를 실행하는 경우에 종종 선호됩니다.

  • 또는 전경 명령을 사용 하여이 작업을 수행하십시오.

    CMD /usr/bin/mysqld_safe
    

이 같은 스크립트가있는 경우에만 작동합니다 mysqld_safe.

  • 또는 스크립트를 감싸서 start.sh끝내십시오.

    CMD /start.sh
    

명령이 일련의 단계를 다시 수행해야하고 실행 상태를 유지해야하는 경우에 가장 좋습니다 /start.sh.

노트

초보자는 사용 supervisord하지 않는 것이 좋습니다. 솔직히, 그것은 과잉입니다. 컨테이너에 단일 서비스 / 단일 명령을 사용하는 것이 훨씬 좋습니다.

BTW : https://registry.hub.docker.com 에서 기존 MySQL 도커 이미지를 참조하십시오.


Docker 컨테이너에서 서비스가 시작되면 어떻게 다시 시작합니까?
K-SO의 독성이 증가하고 있습니다.

3
@KarlMorrisondocker exec -it <CONTAINER NAME> mysql /etc/init.d/mysqld restart
kaiser

1
데이터베이스의 실행 여부를 확인하기 위해 tailing MySQL의 오류 로그를 권장하지 않습니다. 대부분의 mysqld 설정에서 서버는 SOE 오류를 복구하며이 과정에서 오류 로그가 닫힌 다음 다시 열립니다. 또한 꼬리 -F가 모든 경우 또는 일부 경우에 당신에게 잘 맞는지 확신 할 수 없습니다.
Brian Aker

왜 그런지 잘 모르겠지만 첫 번째 솔루션 옵션은 서비스 스크립트에 적합합니다. 테일을 사용하지 않으면 서비스가 시작되었지만 (적어도 tomcat7 서비스의 경우) 테일이 실패합니다. 꼬리와 함께 작동합니다. 두 경우 모두 들어 당신이 사용하는 스위치 cap_add 필요 (- 실행을위한 캡 추가 SYS_PTRACE) 적어도 SYS_PTRACE와
zhrist


73

Dockerfile에서 마지막 줄에 추가 하십시오 .

ENTRYPOINT service ssh restart && bash

그것은 나를 위해 작동

그리고 이것은 결과입니다 :

root@ubuntu:/home/vagrant/docker/add# docker run -i -t ubuntu
 * Restarting OpenBSD Secure Shell server sshd   [ OK ]                                                                      
root@dccc354e422e:~# service ssh status
 * sshd is running

2
이것은 좋지만 이런 식으로 분리 된 컨테이너를 가질 수는 없다고 생각합니다.
mdob

1
이것은 나를 위해 잘 작동했습니다. Nginx 1.8을 자동 시작하는 데 문제가있었습니다. 다음을 추가하면 도움이 될 것입니다. RUN echo "daemon off;" >> /etc/nginx/nginx.conf RUN ln -sf / dev / stdout /var/log/nginx/access.log RUN ln -sf / dev / stderr /var/log/nginx/error.log
Lionel Morrison

1
이 솔루션에 단점이 있습니까?
srph

2
Bash를 시작하는 것은 서비스를 정상적으로 중지하고 싶을 때 나쁜 생각입니다.이 방법으로 도커 컨테이너가 중지 docker stop되거나 docker restart정상적으로 중지 될 수 없기 때문에 죽일 수 있습니다.
Mohammed Noureldin

도커 이미지를 만들기 위해 패커에서 작업 중이며 패커 파일의 conaitner 관련 문제를 해결하는 것 같습니다. "변화": [ "엔트리 포인트 서비스는 && / 빈 / bash는 시작의 nginx"]
karthik101

8

단순한! dockerfile 끝에 추가하십시오.

ENTRYPOINT service mysql start && /bin/bash

이것은 현재 Docker Container 문제를 해결하는 가장 좋은 답변입니다. Docker version 18.09.7, build 2d0083d, && /bin/bash서비스가 즉시 중단되지 않습니다
Long

7

항상 더 읽기 쉬운 것으로 밝혀진 또 다른 방법이 있습니다.

rabbitmq와 mongodb를 실행할 때 다음 CMD과 같이 보일 것이라고 가정하십시오.

CMD /etc/init.d/rabbitmq-server start && \
    /etc/init.d/mongod start

트릭 CMD당 하나만 가질 수 있으므로 Dockerfile모든 명령을 연결 &&한 다음 \각 명령에 새 줄을 시작하는 것입니다.

많은 것들을 추가하게되면 모든 명령을 스크립트 파일에 넣고 @ larry-cai가 제안한 것처럼 시작하십시오.

CMD /start.sh

3

제 경우에는 MYSQL 백엔드 데이터베이스에 연결하는 docker 컨테이너 내에서 Apache2가 제공하는 PHP 웹 응용 프로그램이 있습니다. Larry Cai의 솔루션은 약간만 수정되었습니다. entrypoint.sh서비스를 관리 하는 파일을 만들었습니다 . entrypoint.sh컨테이너가 시작될 때 실행할 명령이 둘 이상있을 때를 만드는 것이 도커를 부트 스트랩하는 더 확실한 방법이라고 생각합니다.

#!/bin/sh

set -e

echo "Starting the mysql daemon"
service mysql start

echo "navigating to volume /var/www"
cd /var/www
echo "Creating soft link"
ln -s /opt/mysite mysite

a2enmod headers
service apache2 restart

a2ensite mysite.conf
a2dissite 000-default.conf
service apache2 reload

if [ -z "$1" ]
then
    exec "/usr/sbin/apache2 -D -foreground"
else
    exec "$1"
fi

Dockerfile과 함께 넣으십시오. 그런 다음 Dockerfile 에이 파일을 원하는 위치로 복사하는 지침이 있어야합니다. 그런 다음 ENTRYPOINT ['your location']지시 사항을 스크립트 파일로 지정하십시오. 그래도 스크립트에 대한 실행 권한을 설정해야합니다. COPY entrypoint.sh /entrypoint.sh RUN chmod 755 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]. 이 예제에서는 시작 지점을 도커 컨테이너의 루트 디렉토리에 복사했습니다.
Mr. Doomsbuster

Dockerfile은 어디에 있습니까?
빅터 조 라스

3

ssh 서비스를 자동으로 시작하려고 할 때도 같은 문제가 있습니다. 나는 그 추가를 발견

/etc/init.d/ssh 시작
~ / .bashrc
그것을 해결할 수는 있지만 bash로 열면됩니다.


1

코드를 한 번만 실행하려면 다음 코드를 /root/.bashrc에 추가하십시오.

이 스크립트를 실행하기 전에 컨테이너를 이미지에 커밋하십시오. 그렇지 않으면 이미지에 'docker_services'파일이 만들어지고 서비스가 실행되지 않습니다.

if [ ! -e /var/run/docker_services ]; then
    echo "Starting services"
    service mysql start
    service ssh start
    service nginx start
    touch /var/run/docker_services
fi

1

도커 컨테이너가 실행될 때마다 MySQL 서비스를 자동으로 시작하는 방법은 다음과 같습니다.

필자의 경우 MySQL뿐만 아니라 PHP, Nginx 및 Memcached도 실행해야합니다.

Dockerfile에 다음 줄이 있습니다.

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80
EXPOSE 3306
CMD service mysql start && service php-fpm start && nginx -g 'daemon off;' && service memcached start && bash

&& bash를 추가하면 Nginx, MySQL, PHP 및 Memcached가 컨테이너 내에서 계속 실행됩니다.


1

이 작동하지 않습니다 CMD service mysql start && /bin/bash

이 작동하지 않습니다 CMD service mysql start ; /bin/bash ;

-대화식 모드가 포 그라운드를 지원하지 않는 것 같습니다.

이 작동합니다! CMD service nginx start ; while true ; do sleep 100; done;

이 작동합니다! CMD service nginx start && tail -F /var/log/nginx/access.log

docker run -p 80:80 nginx_bash명령 매개 변수없이 사용해야합니다 .


0

Docker 웹 사이트의 다음 설명서는 docker 컨테이너에서 SSH 서비스를 구현하는 방법을 보여줍니다. 서비스에 쉽게 적용 할 수 있어야합니다.

이 질문에 대한 변형도 여기에서 요청되었습니다.


nsenter 도구는 SSH 서버 설치없이 github.com/jpetazzo/nsenter 컨테이너에 들어가는 또 다른 방법 입니다. 그러나이 방법을 사용하려면 Docker 호스트에 액세스해야합니다 (일반적으로 SSH 액세스이면 충분합니다).
Fabien Balageas 12

docs.docker.com/sorry/#/examples/running_ssh_service 링크 가 작동하지 않습니다. 업데이트 하시겠습니까?
Ankur

0
docker export -o <nameOfContainer>.tar <nameOfContainer>

docker prune을 사용하여 기존 컨테이너를 정리해야 할 수도 있습니다 ...

필요한 수정 사항으로 가져 오기 :

cat <nameOfContainer>.tar | docker import -c "ENTRYPOINT service mysql start && /bin/bash" - <nameOfContainer>

컨테이너를 예를 들어 always restart 옵션으로 실행하여 호스트 / 데몬 재활용 후 자동으로 다시 시작되도록합니다.

docker run -d -t -i --restart always --name <nameOfContainer> <nameOfContainer> /bin/bash

참고 사항 : 합리적인 의견은 컨테이너를 가능한 한 깨끗하게 남겨두고 cron 서비스 만 시작한 다음 해당 검사 / 모니터링 스크립트로 crontab 또는 cron.hourly, .daily 등을 수정하는 것입니다. 이유는 하나의 데몬에만 의존하기 때문이며 변경시에는 부팅시 시작되는 추적 서비스 대신 크론 스크립트를 재배포하는 것이 가능합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.