Reputation: 1215
This is the entrypoint defined in my Dockerfile:
ENTRYPOINT ["/bin/bash", "-c" , "useradd -r user_test -u 2001 -g 100 && chown -R 2001:100 /home/user_test && su - user_test && mkdir -p /home/user_test/external_user_id"]
I need to make it parameterized as follows:
ENTRYPOINT ["/bin/bash", "-c" , "useradd -r user_test -u <user_id> -g 100 && chown -R <user_id>:100 /home/user_test && su - user_test && mkdir -p /home/user_test/<external_user_id>"]
where user_id
and external_user_id
are set by means the DockerSpawner
configuration:
c.DockerSpawner.extra_host_config = {"user_id": "2001", "external_user_id": "id_1234567890"}
How can I edit the ENTRYPOINT in the Dockerfile?
Thanks
Upvotes: 1
Views: 3272
Reputation: 158977
The first thing I'd suggest changing here is to split this into a separate script. It's hard to read and update a lot of code written inline in a single command like this. Conversely, depending on what the script does, it can be easier to edit and maybe even run it outside of Docker if you need to make changes like this.
COPY entrypoint.sh . # should be executable on the host
# For this standard use, ENTRYPOINT _must_ be JSON-array form.
# Do not use an explicit "bash" invocation generally.
ENTRYPOINT ["./entrypoint.sh"]
# Specify the actual command to run
CMD ???
When the script runs, it gets passed the CMD as additional arguments, so you can use any configuration mechanism you'd like here. Calling getopt(1) would be possible, if a little unusual; it's more common to take simple configuration like this using environment variables.
#!/bin/sh
# Do the setup things from the original ENTRYPOINT line:
# Create the user, using the uid from the environment variable, or
# the default from the first line
useradd -r user_test -u "${USER_ID:-2001}" -g 100
# Change directory ownership, using the newly created user name
chown -R user_test:100 /home/user_test
# Do nothing, but proceed to the next line continuing to run as root
su - user_test
# Create another directory
mkdir -p "/home/user_test/${EXTERNAL_USER_ID:-external_user_id}"
# Run the main container CMD
exec "$@"
You'd also need to pass in the environment variables when you start the container:
c.DockerSpawner.extra_host_config = {"user_id": "2001", "external_user_id": "id_1234567890"}
c.DockerSpawner.environment = {"USER_ID": "2001", "EXTERNAL_USER_ID": "id_1234567890"}
What I'd actually do here is delete all of this code. Passing that user_id
setting should cause Docker to run with that numeric user ID. There's no particular need for the user to "exist"; in most cases nothing bad will happen if user 2001 isn't listed in the container's /etc/passwd
file. You'll probably also discover permission problems when you try to run this as-is since you're already not-root by the time the entrypoint script starts running.
If you configure a user ID as you've done here, and you bind-mount a host directory into the container with appropriate permissions, the container will be able to read and write the directory without any special setup. From context I'm guessing you expect the directory to be bind-mounted from the host (otherwise the specific uid doesn't matter at all), in which case you can create the output directory in advance.
In plain docker run
syntax I'd write:
docker run \
--rm \ # clean up container when done
-u $(id -u) \ # with the current host uid
-v "$PWD/id_1234567890:/result" \ # mounting the result directory
-w /result \ # working in that directory
image-name:tag
If you look at the container environment (try appending id
or ls -l
to that docker run
command to see some of these details) you'll see you're running as the host user ID and you should have read/write access to the result directory, without needing to do setup at container startup time.
Upvotes: 1