Search code examples
dockeralpine-linux

Docker RUN command in exec form not working


I'm building a docker image based on Alpine.

FROM alpine

RUN apk update \
    && apk add lighttpd \
    && rm -rf /var/cache/apk/*

ENV COLOR red

COPY ./index.html /var/www/localhost/htdocs

RUN /bin/ash -c 'echo abcd'
#working
RUN /bin/ash -c "echo $COLOR; sed -i -e 's/red/\$COLOR/g' /var/www/localhost/htdocs/index.html; cat /var/www/localhost/htdocs/index.html;"
#not working
# RUN ["sh", "-c", "echo $COLOR; sed -i -e 's/red/\$COLOR/g' /var/www/localhost/htdocs/index.html; cat /var/www/localhost/htdocs/index.html;"]

CMD ["lighttpd","-D","-f","/etc/lighttpd/lighttpd.conf"]

When I run in shell form it's working fine, but when I run in exec form it's giving

/bin/sh: [sh,: not found

I tried using bin/sh, sh, bin/ash, ash. Same error for all of them.


Solution

  • Shell is responsible for expanding variables, but only variable in double quotes will be expanded.

    Your error comes from wrong \ before $COLOR, in fact it did no meaning for you to get the value from shell, the correct way is next:

    RUN ["sh", "-c", "echo $COLOR; sed -i -e \"s/red/$COLOR/g\" /var/www/localhost/htdocs/index.html; cat /var/www/localhost/htdocs/index.html;"]
    

    A minimal example to show the effect, FYI:

    Dockerfile:

    FROM alpine
    ENV COLOR rednew
    RUN echo "red" > /tmp/index.html
    RUN ["sh", "-c", "sed -i -e \"s/red/$COLOR/g\" /tmp/index.html; cat /tmp/index.html;"]
    

    Result:

    $ docker build -t abc:1 . --no-cache                                                                                              
    Sending build context to Docker daemon  5.632kB
    Step 1/4 : FROM alpine
     ---> 28f6e2705743
    Step 2/4 : ENV COLOR rednew
     ---> Running in 05c43146fab0
    Removing intermediate container 05c43146fab0
     ---> 28ea1434e626
    Step 3/4 : RUN echo "red" > /tmp/index.html
     ---> Running in 2c8fbbc5fd10
    Removing intermediate container 2c8fbbc5fd10
     ---> f884892ad8c4
    Step 4/4 : RUN ["sh", "-c", "sed -i -e \"s/red/$COLOR/g\" /tmp/index.html; cat /tmp/index.html;"]
     ---> Running in 6930b3d03438
    rednew
    Removing intermediate container 6930b3d03438
     ---> b770475672cc
    Successfully built b770475672cc
    Successfully tagged abc:1