2015-10-22 21 views
5

Chcę, aby dwa oddzielne pliki JAR były uruchamiane automatycznie po wywołaniu kontenera w doku za pomocą polecenia uruchamiania, więc gdy wpiszesz docker run mycontainer, oba zostaną wywołane. Do tej pory mam plik docker, który wygląda tak:Sposób automatycznego uruchamiania dwóch plików JAR na "kontenerze dokowania"

# base image is java:8 (ubuntu) 
FROM java:8 

# add files to image 
ADD first.jar . 
ADD second.jar . 

# start on run 
CMD ["/usr/lib/jvm/java-8-openjdk-amd64/bin/java", "-jar", "first.jar"] 
CMD ["/usr/lib/jvm/java-8-openjdk-amd64/bin/java", "-jar", "second.jar"] 

To jednak zaczyna się tylko od second.jar.

Teraz oba słoiki są serwerami w pętli, więc domyślam się, że po uruchomieniu blokuje tylko terminal. Jeśli uruchomię kontener używając run -it mycontainer bash i wykonam je ręcznie, pierwszy wykona swoje wyjścia i nie będę mógł uruchomić drugiego.

Czy istnieje sposób otwierania różnych terminali i przełączania się między nimi, aby każdy JAR działał we własnym kontekście? Najlepiej już w pliku dockerfile.

Nie wiem prawie nic na temat ubuntu, ale znalazłem polecenie xterm, które otwiera nowy terminal, jednak nie zadziała po wywołaniu pliku JAR. Czego szukam, to instrukcje do wewnątrz pliku dockerfile, które na przykład otwierają nowy terminal, wykonują first.jar, alt-tab do starego terminala i wykonują second.jar tam, lub przynajmniej osiągają to samo.

Dzięki!

Odpowiedz

2

Druga instrukcja CMD zastępuje pierwszy, więc trzeba użyć pojedynczą instrukcję dla obu poleceń.

łatwe (nie tak dobre) Podejście

Można dodać skrypt bash, który wykonuje zarówno komend i bloki na drugim:

# start.sh 
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar first.jar & 
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar second.jar 

Następnie zmienić Dockerfile do tego:

# base image is java:8 (ubuntu) 
FROM java:8 

# add files to image 
ADD first.jar . 
ADD second.jar . 
ADD start.sh . 

# start on run 
CMD ["bash", "start.sh"] 

Podczas korzystania z docker stop może nie być poprawnie zamknięty, patrz: https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/

lepsze podejście

Aby rozwiązać ten problem, można użyć Phusion: https://hub.docker.com/r/phusion/baseimage/
Ma init-system, który jest znacznie łatwiejszy w użyciu niż np supervisord.

Oto dobry punkt wyjścia: https://github.com/phusion/baseimage-docker#getting_started

Instrukcja korzystania Phusion

Niestety nie ma oficjalnych openjdk-8-jdk dostępna dla Ubuntu 14.04 LTS. Możesz spróbować z nieoficjalnym ppa, które jest używane w poniższym wyjaśnieniu.

W twoim przypadku trzeba by bash skryptów (które działają jak „Usługi”):

# start-first.sh (the file has to start with the following line!): 
#!/bin/bash 
usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar /root/first.jar 

# start-second.sh 
#!/bin/bash 
usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar /root/second.jar 

A twój Dockerfile będzie wyglądać następująco:

# base image is phusion 
FROM phusion/baseimage:latest 

# Use init service of phusion 
CMD ["/sbin/my_init"] 

# Install unofficial openjdk-8 
RUN add-apt-repository ppa:openjdk-r/ppa && apt-get update && apt-get dist-upgrade -y && apt-get install -y openjdk-8-jdk 

ADD first.jar /root/first.jar 
ADD second.jar /root/second.jar 

# Add first service 
RUN mkdir /etc/service/first 
ADD start-first.sh /etc/service/first/run 
RUN chmod +x /etc/service/first/run 

# Add second service 
RUN mkdir /etc/service/second 
ADD start-second.sh /etc/service/second/run 
RUN chmod +x /etc/service/second/run 

# Clean up 
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

Należy zainstalować dwie usługi, które będzie uruchamiany przy uruchomieniu i wyłączony poprawnie po użyciu docker stop.

+0

Dzięki rozwiązanie skrypt jest dokładnie to, czego szukałem. Działa bez problemów do tej pory! Patrzę też na phusion, na wypadek, gdyby coś się zepsuło. – buggy

+1

Dobrze to słyszeć! Dodałem przykład, jak można ustawić phusion, aby uruchomić oba słoiki jako oddzielne "usługi". – craeckie

0

Jeśli chcesz rozpocząć dwa różne procesy wewnątrz jednego kontenera Döcker (nie recommanded zachowanie), można użyć coś jak supervisord

1

Masz kilka opcji. Wiele z tych odpowiedzi wspomniało o zastosowaniu do tego celu opiekuna, co jest dobrym rozwiązaniem. Oto kilka innych:

Stwórz krótki scenariusz, który właśnie uruchamia oba słoiki. Dodaj to do swojej CMD. Na przykład, skrypt, który będziemy nazywać run_jars.sh mógłby wyglądać następująco:

/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar first.jar; 
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar second.jar; 

Wtedy twój CMD byłoby CMD sh run_jars.sh

Inną alternatywą jest właśnie uruchomiony dwa oddzielne containers-- jeden dla first.jar a drugi dla second.jar. Można uruchomić każdy z nich poprzez docker run, na przykład:

docker run my_repo/my_image:some_tag /usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar second.jar

+0

Dzięki za różne sugestie pojemników! Grałem z nim i jeśli skrypt basha powoduje problemy podczas implementacji, mogę wrócić do dwóch kontenerów i użyć polecenia --link, aby wywoływać się nawzajem. – buggy