I am trying to avoid using docker compose if possible, and so I'm building a Dockerfile
that creates the entrypoint.sh
within the Dockerfile. This works flawlessly with one issue - I need to accept an environment variable in the entrypoint.sh
file
Here's the end of my Dockerfile
:
FROM kalilinux/kali-rolling
RUN echo "\n##### Provision openvas user #####\n" >> /opt/entrypoint.sh && \
echo "useradd -rm -d /home/openvas -s /bin/bash -g _gvm openvas" >> /opt/entrypoint.sh && \
echo "chown -R openvas:_gvm /home/openvas" >> /opt/entrypoint.sh && \
echo "gvmd --user=admin --new-password=${OV_PASSWORD}" >> /opt/entrypoint.sh && \
chmod x /opt/entrypoint.sh
ENTRYPOINT ["/opt/entrypoint.sh"]
CMD ["tail", "-f","/dev/null"]
However, when I try to start the container with docker run
and passing an environment variable to it, it doesn't seem to work because of some format error. Here's an example of what I'm running and its output:
ubuntu@ip-10-20-32-116:~/openvas$ docker run -e OV_PASSWORD=password -ti 05190b668480 /bin/bash
standard_init_linux.go:228: exec user process caused: exec format error
Any thoughts as to what may be happening here? I believe the error started as soon as I added the ${OV_PASSWORD}
into the echo statement. I also tried with just OV_PASSWORD
and got a similar error, so not quite sure what I'm doing wrong in terms of formatting.
CodePudding user response:
At a mechanical level, you may find it easier to create the entrypoint script as a separate file on your host, then simply COPY
it into the image. This avoids the quoting problem that @DannyB highlights in their answer.
FROM kalilinux/kali-rolling
COPY entrypoint.sh /opt/entrypoint.sh
# RUN chmod x /opt/entrypoint.sh # if not already executable
ENTRYPOINT ["/opt/entrypoint.sh"]
CMD ["tail", "-f","/dev/null"]
Make sure that script ends with the line exec "$@"
to run the CMD
, and that the ENTRYPOINT
line in the Dockerfile uses JSON-array syntax. (Comments suggest your setup already has this correctly.)
There are a couple of things in the setup you show that will always be done exactly the same way every time you start the container, and these could be refactored to run only once when you build the image. So I might have instead:
FROM kalilinux/kali-rolling
... do the other things to install the application ...
# Create a non-root user
RUN useradd -rM -g _gvm openvas
# Change file ownership so the non-root user can modify the application
# at runtime (not usually recommended)
# RUN chown -R openvas:_gvm /home/openvas
# Copy in the entrypoint script
COPY entrypoint.sh /opt/entrypoint.sh
# RUN chmod x /opt/entrypoint.sh # if not already executable
# Specify how to run the container
USER openvas
ENTRYPOINT ["/opt/entrypoint.sh"]
CMD ["openvas", "-u"]
Where the entrypoint just contains
#!/bin/sh
# /opt/entrypoint.sh
# Configure the application password
if [ -n "$OV_PASSWORD" ]; then
gvmd --user=admin "--new-password=${OV_PASSWORD}"
fi
# Run the main container command
exec "$@"
CodePudding user response:
when both CMD
and ENTRYPOINT
are given, the CMD is treated as default input to entrypoint.
I suggest, you remove CMD and use docker logs <container-id>
instead
CodePudding user response:
You have a couple of issues with your Dockerfile.
CMD
is used as arguments toENTRYPOINT
, therefore not behaving as you expect.- When you
echo
with variables, and you wish the variables to NOT be evaluated during the echo, use single quotes. - Your
ENTRYPOINT
does not need to use the[...]
syntax.
To achieve what you want, put the tail -f
command inside your entrypoint.
Here is a working sample
FROM alpine
RUN echo 'echo got password $PASS' > /opt/entrypoint.sh && \
echo "tail -f /dev/null" >> /opt/entrypoint.sh && \
chmod x /opt/entrypoint.sh
ENTRYPOINT "/opt/entrypoint.sh"
Run with:
$ docker run --rm -it -e PASS=123 your_image_name
CodePudding user response:
RUN echo "\n##### Provision openvas user #####\n" >> /opt/entrypoint.sh && \
echo "useradd -rm -d /home/openvas -s /bin/bash -g _gvm openvas" >> /opt/entrypoint.sh && \
echo "chown -R openvas:_gvm /home/openvas" >> /opt/entrypoint.sh && \
echo "gvmd --user=admin --new-password=${OV_PASSWORD}" >> /opt/entrypoint.sh && \
chmod x /opt/entrypoint.sh
Your shell script doesn't have an interpreter defined, e.g. the first line that's normally #!/bin/sh
. And then you try to execute that script from the kernel with an exec rather than from within a shell that would default to using itself to interpret the script since you've used the json/exec format for your entrypoint:
ENTRYPOINT ["/opt/entrypoint.sh"]
That is what is triggering the:
standard_init_linux.go:228: exec user process caused: exec format error
Which is saying your executable/binary isn't properly formatted for the kernel to run. To fix, make the first line a shell that exists in your image:
RUN echo '#!/bin/sh\n' > /opt/entrypoint.sh && \
echo '\n##### Provision openvas user #####\n' >> /opt/entrypoint.sh && \
echo 'useradd -rm -d /home/openvas -s /bin/bash -g _gvm openvas' >> /opt/entrypoint.sh && \
echo 'chown -R openvas:_gvm /home/openvas' >> /opt/entrypoint.sh && \
echo 'gvmd --user=admin --new-password=${OV_PASSWORD}' >> /opt/entrypoint.sh && \
chmod x /opt/entrypoint.sh