My ENV variable in the Dockerfile requires a newline sequence (\n). Using the ENV instruction, it seems impossible to achieve this.
I've tried all possible combinations, I think:
# Dockerfile
ENV FOO @static {\n path_regexp \\n} # @static {n path_regexp \\n}
ENV BAR='@static {\n path_regexp \n}' # @static {\\n path_regexp \\n}
ENV BAZ="@static {\n path_regexp \n}" # @static {\\n path_regexp \\n}
\n is always prepended with a backslash. Is this a "feature"? How can I make my ENV respect the newline sequence?
Putting the variabile directly in Compose file will output the variabile correctly.
Docker doesn't replace escaped characters in the ENV statement.
You can replace them at runtime by echoing them into new variables as this shows
FROM debian
ENV foo="Hello\nWorld!"
CMD bar=$(echo ${foo}) && echo ${#foo} && echo ${#bar}
It prints 13 and 12 showing that foo is 13 characters long and bar is 12 long, so \n has been replaced with a newline.
I don't believe you can do this with only a Dockerfile. The parsing on the ENV step is very minimal. However, you can define the variable outside of the build, and pass it in as a build arg:
$ cat df.env
from alpine
arg hello
env hello=${hello}
cmd env
$ hello="hello
> world"
$ docker build -t test-env -f df.env --build-arg "hello=$hello" .
[+] Building 0.2s (5/5) FINISHED docker:default
=> [internal] load build definition from df.env 0.0s
=> => transferring dockerfile: 84B 0.0s
=> WARN: JSONArgsRecommended: JSON arguments recommended for cmd to prevent unintended behavior r 0.0s
=> [internal] load metadata for docker.io/library/alpine:latest 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 49B 0.0s
=> CACHED [1/1] FROM docker.io/library/alpine:latest 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:11ff645049d1b266b68f2b0fe1da19ef0daccaf103bbafc2030b10d58eb0d6b6 0.0s
=> => naming to docker.io/library/test-env 0.0s
1 warning found (use docker --debug to expand):
- JSONArgsRecommended: JSON arguments recommended for cmd to prevent unintended behavior related to OS signals (line 5)
$ docker run --rm test-env
HOSTNAME=af8f8744374d
SHLVL=1
HOME=/root
hello=hello
world
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
Another option to do this is to expand the variable inside of an entrypoint script, in this case using printf. This will only apply to child processes of the entrypoint, so a docker exec would see the unexpanded variable:
from alpine
env hello=hello\\nworld
copy --chmod=755 <<-"EOT" /entrypoint.sh
#!/bin/sh
export hello="$(printf "$hello")"
if [ $# = 0 ]; then
set -- /bin/sh
fi
exec "$@"
EOT
entrypoint [ "/entrypoint.sh" ]
cmd env
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With