0

I have a scrip that gets called in a Dockerfile entrypoint:

ENTRYPOINT ["/bin/sh", "-c", "/var/run/Scripts/entrypoint.sh"]

I need to set an environment variable based on a value in a file. I am using the following command to retrieve the value: RSYSLOG_LISTEN_PORT=$(sed -nE 's/.*port="([^"]+)".*/\1/p' /etc/rsyslog.d/0_base.conf)

Locally, this command works and even running the command from the same directory that the entrypoint script is located in will result in the env var being set.

However, adding this command after export (export SYSLOG_LISTEN_PORT=$(sed -nE 's/.*port="([^"]+)".*/\1/p' /etc/rsyslog.d/0_base.conf)) in the entrypoint script does not result in the env var being set.

Additionally, trying to use another script and sourcing the script within the entrypoint script also does not work:

#!/bin/bash

. ./rsyslog_listen_port.sh

I am unable to use source as I get a source: not found error - I have tried a few different ways to use source but it doesn't seem compatible.

Can anyone help me as I have spent too much time on trying to get this to work at this point for what seems like a relatively simple task.

5
  • source: not found indicates you're using sh, not bash. As your ENTRYPOINT indeed shows. Commented Aug 16, 2022 at 13:30
  • @Thomas So what would the change be? Change it to /bin/bash in entrypoint or change to #!/bin/sh in the script? Commented Aug 16, 2022 at 13:33
  • If you invoke a particular shell directly, the shebang is ignored since it's only interpreted by the kernel. You could just use ENTRYPOINT ["/var/run/Scripts/entrypoint.sh"] if you take care to make your script executable. Commented Aug 16, 2022 at 13:34
  • Ok. So would sourcing another script with . ./rsyslog_listen_port.sh within the entrypoint script work then? Commented Aug 16, 2022 at 13:38
  • It would, within that script. You cannot affect the environment of a parent shell. Commented Aug 16, 2022 at 15:06

1 Answer 1

1

A container only runs one process, and then it exits. A pattern I find useful here is to make the entrypoint script be a wrapper that does whatever first-time setup is useful, then exec the main container process:

#!/bin/sh

# set the environment variable
export SYSLOG_LISTEN_PORT=$(sed -nE 's/.*port="([^"]+)".*/\1/p' /etc/rsyslog.d/0_base.conf)

# then run the main container command
exec "$@"

In your Dockerfile, set the ENTRYPOINT to this script (it must use JSON-array syntax, and it must not have an explicit sh -c wrapper) and CMD to whatever you would have set it to without this wrapper.

ENTRYPOINT ["/var/run/Scripts/entrypoint.sh"]
CMD ["rsyslog"]

Note that this environment variable will be set for the main container process, but not for docker inspect or a docker exec debugging shell. Since the wrapper sets up the environment variable and then runs the main container process, you can replace the command part (only) when you run the container to see this.

docker run --rm your-image env \
  | grep SYSLOG_LISTEN_PORT

(source is a bash-specific extension. POSIX shell . does pretty much the same thing, and I'd always use . in preference to source.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.