java docker dropwizard dockerfile

SIGTERM no fue recibido por el proceso java utilizando ''docker stop'' y la imagen java oficial



dropwizard dockerfile (2)

La respuesta de @ h3nrik es correcta, pero a veces es necesario utilizar un script para configurar el lanzamiento. Simplemente use el comando exec para hacer el truco en la mayoría de los casos:

#!/bin/sh #--- Preparations exec java -jar ...

Ver esta maravillosa entrada de blog.

Estoy ejecutando una aplicación Java de Dropwizard en un contenedor Docker utilizando la imagen java:7u79 basada en debian/jessie .

Mi aplicación Java maneja la señal SIGTERM para apagar con gracia. El manejo de SIGTERM funciona perfectamente cuando ejecuto la aplicación sin Docker.

Cuando lo ejecuto en un contenedor Docker, el SIGTERM no llega a la aplicación Java cuando docker stop un comando de docker stop . Mata el proceso bruscamente después de 10 segundos.

Mi Dockerfile :

FROM java:7u79 COPY dropwizard-example-1.0.0.jar /opt/dropwizard/ COPY example.keystore /opt/dropwizard/ COPY example.yml /opt/dropwizard/ WORKDIR /opt/dropwizard RUN java -jar dropwizard-example-1.0.0.jar db migrate /opt/dropwizard/example.yml CMD java -jar dropwizard-example-1.0.0.jar server /opt/dropwizard/example.yml EXPOSE 8080 8081

¿Qué está mal con este Dockerfile ? ¿Hay alguna otra manera de abordar este problema?


Suponiendo que inicie un servicio Java definiendo lo siguiente en su Dockerfile :

CMD java -jar ...

Cuando ahora ingresa al contenedor y enumera los procesos, por ejemplo, por docker exec -it <containerName> ps AHf (no probé eso con el java sino con la imagen de ubuntu ) verá que su proceso Java no es el proceso raíz (no el proceso raíz). proceso con PID 1) pero un proceso hijo de un proceso /bin/sh :

UID PID PPID C STIME TTY TIME CMD root 1 0 0 18:27 ? 00:00:00 /bin/sh -c java -jar ... root 8 1 0 18:27 ? 00:00:00 java -jar ...

Básicamente, tiene un shell de Linux que es el proceso principal con PID 1 que tiene un proceso secundario (Java) con PID 8.

Para que el manejo de la señal funcione correctamente, debe evitar los procesos de shell padre. Eso se puede hacer usando el comando incorporado shell exec . Eso hará que el proceso del niño se haga cargo del proceso padre. Así que al final el proceso padre anterior ya no existe. Y el proceso secundario se convierte en el proceso con el PID 1. Pruebe lo siguiente en su Dockerfile :

CMD exec java -jar ...

La lista de procesos debería mostrar algo como:

UID PID PPID C STIME TTY TIME CMD root 1 0 0 18:30 ? 00:00:00 java -jar ...

Ahora solo tiene ese proceso con PID 1. En general, una buena práctica es que los contenedores de la ventana acoplable contengan un solo proceso: el que tiene PID 1 (o si realmente necesita más procesos, debe usar, por ejemplo, supervisord como PID 1, que a su vez requiere). Cuidado del manejo de la señal para sus procesos hijo).

Con esa configuración, el proceso Java tratará directamente a SIGTERM . Ya no hay un proceso de shell que pueda interrumpir el manejo de la señal.

EDITAR :

El mismo efecto exec podría lograrse usando una sintaxis CMD diferente que lo hace implícitamente (gracias a Andy por su comentario):

CMD ["java", "-jar", "..."]