just-containers / s6-overlay

s6 overlay for containers (includes execline, s6-linux-utils & a custom init)
Other
3.7k stars 208 forks source link

Container environment variables with dotted names are not working #466

Closed akusei closed 2 years ago

akusei commented 2 years ago

I may be doing something very wrong here but it looks like environment variables with dots in the name are not carried over into the s6 environment. I've included a sample Dockerfile and a couple CLI examples that illustrate the problem. Is this an actual bug or am I doing something wrong?

FROM ubuntu:latest

ENV PATH "${PATH}:/command"

ADD https://github.com/just-containers/s6-overlay/releases/download/v3.1.1.2/s6-overlay-noarch.tar.xz /tmp/
ADD https://github.com/just-containers/s6-overlay/releases/download/v3.1.1.2/s6-overlay-x86_64.tar.xz /tmp/

RUN apt-get update && apt-get install -y xz-utils && \
    tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz && \
    tar -C / -Jxpf /tmp/s6-overlay-x86_64.tar.xz && \
    rm -rf /tmp/* /var/lib/apt/lists/*

ENTRYPOINT ["/init"]

For the following exmaples s6test is the container of the above image. The following produces the expected result; 2 added environment variables TEST1 and TEST2

docker run --rm -e TEST1=test1 -e TEST2=test2 s6test with-contenv env

Result:

...
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/command
TEST1=test1
PWD=/
HOSTNAME=a6c8bf24ee9d
TEST2=test2
...

The following produces an unexpected result; 1 added environment variable TEST1

docker run --rm -e TEST1=test1 -e this.will.fail=test2 s6test with-contenv env

Result:

...
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/command
TEST1=test1
PWD=/
HOSTNAME=ba058c7fd8dc
...
skarnet commented 2 years ago

That's very unexpected and pretty wild. I cannot reproduce the problem on an alpine image, but I can reproduce it on an ubuntu:latest image. This is not a good sign and may take some time to fully understand.

Thanks for the report; I'll be investigating.

skarnet commented 2 years ago

It's a bug in the dash shell.

I have performed various tests, and when you run a dash shell from an environment containing variables with dotted names, dash does not have these variables in its environment. This is different from the normal behaviour shown by e.g. bash, or ash (from busybox).

Ubuntu images use dash as their /bin/sh shell. I suggest reporting the bug either to Ubuntu, or to the dash upstream, if there's one.

This is unfortunately not something we can fix in s6-overlay, because we cannot hardcode shebangs for any other shell than /bin/sh. (We cannot assume the presence of /bin/bash, for instance, on every image.)

A workaround for you would be to change the shell used in the s6-overlay scripts, at least the ones that lead to the supervision tree and the CMD execution. For instance with the following command in your Dockerfile:

RUN sed -i -e 's|#!/bin/sh -e|#!/bin/bash -e|' /init /package/admin/s6-overlay/libexec/stage0 /package/admin/s6-overlay/etc/s6-linux-init/skel/rc.init

Good luck.

akusei commented 2 years ago

It's a bug in the dash shell.

I have performed various tests, and when you run a dash shell from an environment containing variables with dotted names, dash does not have these variables in its environment. This is different from the normal behaviour shown by e.g. bash, or ash (from busybox).

Ubuntu images use dash as their /bin/sh shell. I suggest reporting the bug either to Ubuntu, or to the dash upstream, if there's one.

This is unfortunately not something we can fix in s6-overlay, because we cannot hardcode shebangs for any other shell than /bin/sh. (We cannot assume the presence of /bin/bash, for instance, on every image.)

A workaround for you would be to change the shell used in the s6-overlay scripts, at least the ones that lead to the supervision tree and the CMD execution. For instance with the following command in your Dockerfile:

RUN sed -i -e 's|#!/bin/sh -e|#!/bin/bash -e|' /init /package/admin/s6-overlay/libexec/stage0 /package/admin/s6-overlay/etc/s6-linux-init/skel/rc.init

Good luck.

Thanks for running this down! I was so confused, I had drilled down all the way to your dump_env function in your c library but the code looked like it should work so I figured I'd open an issue. I doubt this will be fixed in dash anytime soon but it may be worth it to add a short warning in the readme about using Ubuntu so others don't fall victim to the same dash issue.

Thanks again! This can be closed as the workaround works. Another option would be to symlink bash to sh. This could have unintended consequences but for my use case it won't be an issue either way. I would love to use alpine instead but the software I'm using doesn't work well on that distro