I'm using a python script for send websocket notification, as suggested here.
The script is _wsdump.py
and I have a script script.sh
that is:
#!/bin/sh
set -o allexport
. /root/.env set
env
python3 /utils/_wsdump.py "wss://mywebsocketserver:3000/message" -t "message" &
If I try to dockerizing this script with this Dockerfile
:
FROM python:3.8-slim-buster
RUN set -xe \
pip install --upgrade pip wheel && \
pip3 install websocket-client
ENV TZ="Europe/Rome"
ADD utils/_wsdump.py /utils/_wsdump.py
ADD .env /root/.env
ADD script.sh /
ENTRYPOINT ["./script.sh"]
CMD []
I have a strange behaviour:
if I execute
docker run -it --entrypoint=/bin/bash mycontainer
and after that I call thescript.sh
everything works fine and I receive the notification.if I run
mycontainer
withdocker run mycontainer
I see no errors but the notification doesn't arrive.
What could be the cause?
CodePudding user response:
Your script doesn't launch a long-running process; it tries to start something in the background and then completes. Since the script completes, and it's the container's ENTRYPOINT
, the container exits as well.
The easy fix is to remove the &
from the end of the last line of the script to cause the Python process to run in the foreground, and the container will stay alive until the process completes.
There's a more general pattern of an entrypoint wrapper script that I'd recommend adopting here. If you look at your script, it does two things: (1) set up the environment, then (2) run the actual main container command. I'd suggest using the Docker CMD
for that actual command
# end of Dockerfile
ENTRYPOINT ["./script.sh"]
CMD python3 /utils/_wsdump.py "wss://mywebsocketserver:3000/message" -t "message"
You can end the entrypoint script with the magic line exec "$@"
to run the CMD
as the actual main container process. (Technically, it replaces the current shell script with a command constructed by replaying the command-line arguments; in a Docker context the CMD
is passed as arguments to the ENTRYPOINT
.)
#!/bin/sh
# script.sh
# set up the environment
. /root/.env set
# run the main container command
exec "$@"
With this use you can debug the container setup by replacing the command part (only), like
docker run --rm your-image env
to print out its environment. The alternate command env
will replace the Dockerfile CMD
but the ENTRYPOINT
will remain in place.
CodePudding user response:
You install script.sh
to the root dir /
, but your ENTRYPOINT
is defined to run the relative path ./script.sh
.
Try changing ENTRYPOINT
to reference the absolute path /script.sh
instead.