Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docker: Add proper entrypoint #531

Closed
wants to merge 1 commit into from

Conversation

oliv3r
Copy link
Contributor

@oliv3r oliv3r commented Jun 3, 2023

As per docker guidelines 0 a container should always really have a consistent entrypoint, without having to override it or do special tricks.

The behavior should be identical as before, but will no longer trigger errors because docker-gen doesn't understand certain parameters (/bin/sh for example being common). Further more, allows a proper entrypoint for a CI to work easily with the container as well. Allowing for scenario's such as apk add git && docker-gen renew in a docker-gen image for example.

E.g. docker run docker-gen --help works, as does docker run docker-gen /bin/sh or docker run docker-gen ls.

@oliv3r oliv3r force-pushed the add_default_entrypoint branch 4 times, most recently from 38aa71b to e626f5d Compare June 4, 2023 16:10
Copy link
Member

@buchdag buchdag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi. Thanks for the PR.

In addition to the change requests I made below, I'd prefer the entrypoint script to be located at /app/docker-entrypoint.sh, both in the repo and inside the image, for consistency with https://github.com/nginx-proxy/nginx-proxy

Comment on lines 12 to 22
bin='docker-gen'

# run command if it is not starting with a "-" and is an executable in PATH
if [ "${#}" -le 0 ] || \
[ "${1#-}" != "${1}" ] || \
[ -d "${1}" ] || \
! command -v "${1}" > '/dev/null' 2>&1; then
entrypoint='true'
fi

exec ${entrypoint:+${bin:?}} "${@}"
Copy link
Member

@buchdag buchdag Jun 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the rationale behind the [ -d "${1}" ] check (this would end up passing a folder as argument to docker-gen, and AFAIK this does not work) ? 🤔

While I understand the command -v "${1}" > '/dev/null' 2>&1 check, I don't think that's the way to go because it would mean commands with typo would be passed as argument to docker-gen instead of failing with a foo: not found as they should. A simple [ -f "${1}" ] work in this case: executables in PATH do not check as files.

Finally the exec ${entrypoint:+${bin:?}} "${@}" is hard to decipher and needlessly complex, the way it's done in the official docker example is clearer.

Suggestion taking all of the above into account:

#!/bin/sh

set -eu

# if command starts with an "-" or is a file, pass it as argument(s) to docker-gen, else run it.
if [ "${#}" -le 0 ] || [ "${1#-}" != "${1}" ] || [ -f "${1}" ]; then
    set -- docker-gen "${@}"
fi

exec "${@}"

The exit 0 at the end as no real use since we're using set -e.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like github ate my comment, as I'm very sure I replied in detail. I'll try to find it again.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aw crap. 😞

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, gone; was hoping I could get it in the edit field on my laptop, no such luck ... so let me try again.

What's the rationale behind the [ -d "${1}" ] check (this would end up passing a folder as argument to docker-gen, and AFAIK this does not work) ? thinking

I have to dig deep now, as I use this template for everything (to keep them all the same, nice and consistent). Afaik, if you have a container, that accepts a directory as input, lets say the ls container, if the directory exists, it'll allow you to pass the directory as argument to the binary. But you got me, I'm trying remember really hard what the usecase was (there was one :p)

While I understand the command -v "${1}" > '/dev/null' 2>&1 check, I don't think that's the way to go because it would mean commands with typo would be passed as argument to docker-gen instead of failing with a foo: not found as they should. A simple [ -f "${1}" ] work in this case: executables in PATH do not check as files.

But was it a command you where trying to execute? or was it something you wanted to pass a long. If you assume the script to be dedicated only to docker-gen yeah, sure. But in a more generic case. Also, if I supply cp instead of /usr/bin/cp it should still work.

Finally the exec ${entrypoint:+${bin:?}} "${@}" is hard to decipher and needlessly complex, the way it's done in the official docker example is clearer.

Eye of the beholder, sure enough. I used to have ${bin:+${bin}} before, is that easier on the eyes? I took this new approach, as I wanted to keep the bin definition at the top of the file, for easy recognition.

The docker approach is equally 'confusing'. What's with the set --, that is also less clear (doesnt' that eat the existing set -eu also? Idk, never had to use it yet). The reason it is a variable though; is to ensure a single exit point of the script.

Suggestion taking all of the above into account:

#!/bin/sh

set -eu

# if command starts with an "-" or is a file, pass it as argument(s) to docker-gen, else run it.
if [ "${#}" -le 0 ] || [ "${1#-}" != "${1}" ] || [ -f "${1}" ]; then
    set -- docker-gen "${@}"
fi

exec "${@}"

The exit 0 at the end as no real use since we're using set -e.
ah, but what if some hacker dude does echo 'rm -rf /' >> script.sh? It's a shell scripting best-practise (afaik its in the google bash styleguide even). I like best-practises :) 'always have a defined exit point at the end of your script', in case something goes haywire.

container-entrypoint.sh Outdated Show resolved Hide resolved
As per docker guidelines [0] a container should always really have a
consistent entrypoint, without having to override it or do special
tricks.

The behavior should be _identical_ as before, but will no longer trigger
errors because docker-gen doesn't understand certain parameters (/bin/sh
for example being common). Further more, allows a proper entrypoint for
a CI to work easily with the container as well. Allowing for scenario's
such as `apk add git && docker-gen renew` in a docker-gen image for example.

E.g. `docker run docker-gen --help` works, as does `docker run
docker-gen /bin/sh` or `docker run docker-gen ls`.

[0]: https://github.com/docker-library/official-images#consistency

Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
entrypoint='true'
fi

exec ${entrypoint:+${bin:?}} "${@}"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

entrypoint should be initialized to the empty string in case it is already exported to this script's environment.

Comment on lines +16 to +17

exit 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed; exec cannot return unless it can't execute the command, in which case exec's return value should be returned.

Suggested change
exit 0

# run command if it is not starting with a "-" and is an executable in PATH
if [ "${#}" -le 0 ] || \
[ "${1#-}" != "${1}" ] || \
[ -d "${1}" ] || \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this implied by the command check?


# run command if it is not starting with a "-" and is an executable in PATH
if [ "${#}" -le 0 ] || \
[ "${1#-}" != "${1}" ] || \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you pass -- to command, it will prevent $1 from being interpreted as an option. That would make it possible to eliminate this check. (I don't think it's a problem accidentally running a command named something like -x; such commands shouldn't exist, and if they do then running it is no worse than accidentally running any other command that was intended to be a command-line option to docker-gen.)

bin='docker-gen'

# run command if it is not starting with a "-" and is an executable in PATH
if [ "${#}" -le 0 ] || \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

command will return 1 if the command name is the empty string, so this check isn't necessary.

entrypoint='true'
fi

exec ${entrypoint:+${bin:?}} "${@}"
Copy link
Collaborator

@rhansen rhansen Jun 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @buchdag that this should use set -- docker-gen "$@". This is the idiomatic way to "unshift", which makes it more readable.

Comment on lines +5 to +17
bin='docker-gen'

# run command if it is not starting with a "-" and is an executable in PATH
if [ "${#}" -le 0 ] || \
[ "${1#-}" != "${1}" ] || \
[ -d "${1}" ] || \
! command -v "${1}" > '/dev/null' 2>&1; then
entrypoint='true'
fi

exec ${entrypoint:+${bin:?}} "${@}"

exit 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting it all together, I would do something like this:

Suggested change
bin='docker-gen'
# run command if it is not starting with a "-" and is an executable in PATH
if [ "${#}" -le 0 ] || \
[ "${1#-}" != "${1}" ] || \
[ -d "${1}" ] || \
! command -v "${1}" > '/dev/null' 2>&1; then
entrypoint='true'
fi
exec ${entrypoint:+${bin:?}} "${@}"
exit 0
command -v -- "$1" >/dev/null 2>&1 || set -- docker-gen "$@"
exec "$@"

@buchdag
Copy link
Member

buchdag commented Dec 9, 2023

Superseded by #573

@buchdag buchdag closed this Dec 9, 2023
@buchdag buchdag added enhancement docker Pull requests that update Docker code labels Dec 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docker Pull requests that update Docker code enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants