I have a Dockerfile
which currently uses the following:
COPY ./compose/local/django/start.sh /start.sh
RUN sed -i 's/\r//' /start.sh
RUN chmod +x /start.sh
As you can see it copies the file and then makes it executable. I now need to change this depending on a argument provided when I build the image. I have tried using this:
RUN if [ "$arg" = "True" ]; then \
COPY ./compose/local/django/new.sh /new.sh \
RUN sed -i 's/\r//' /new.sh \
RUN chmod +x /new.sh; else \
COPY ./compose/local/django/start.sh /start.sh \
RUN sed -i 's/\r//' /start.sh \
RUN chmod +x /start.sh; fi
But this fails as it appears that I can't run COPY
or RUN
commands inside a conditional statement. It always fails with:
/bin/sh: 1: COPY: not found
or
/bin/sh: 1: RUN: not found
So, I think that the best course of action is to create a separate bash file which does the copies, something like:
#!/usr/bin/env bash
if [ "${arg}" = "True" ]; then
echo "arg = ${arg}"
cp ./compose/local/django/new.sh /new.sh
elif [ "${arg}" = "False" ]; then
echo "arg = ${arg}"
cp ./compose/local/django/start.sh /start.sh
fi
But I am struggling with how to make the copied bash files executable. I know I can do it by running chmod +x
in the command line, but as I am not the only person who is going to be building this, I was hoping that there would be a better solution, something like I was doing previously in the original Dockerfile
script.
Can anyone help me with this? Any help would be much appreciated.
Accepted answer does not cover "if else condition" part of the question. Would be better to rename it to "Dockerfile with external arguments" if condition check didn't mean to be a requirement.
There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect. If CMD is used to provide default arguments for the ENTRYPOINT instruction, both the CMD and ENTRYPOINT instructions should be specified with the JSON array format.
The basic syntax for the command is: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] You can run containers from locally stored Docker images. If you use an image that is not on your system, the software pulls it from the online registry.
Using ENTRYPOINT or CMD Both ENTRYPOINT and CMD are essential for building and running Dockerfiles—it simply depends on your use case. As a general rule of thumb: Opt for ENTRYPOINT instructions when building an executable Docker image using commands that always need to be executed.
Use only one 'RUN' statement. It's a best practice as it will reduce the size taken by your image.
This is how you can pass an argument to docker build.
Dockerfile:
...
ARG NEW
COPY ./compose/local/django/new.sh /new.sh
COPY ./compose/local/django/start.sh /start.sh
RUN if [ "$NEW" = "True" ]; then \
sed -i 's/\r//' /new.sh && \
chmod +x /new.sh; \
else \
sed -i 's/\r//' /start.sh && \
chmod +x /start.sh; \
fi
and build it like this
docker build --build-arg NEW="True" .
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