0

I want insert a varialbe on Dockerfile in cmd command, but the variable is not recognize on CMD command on docker run, like above

ARG VAR1
ENV VAR1=$VAR1

COPY files/etc/supervisor/supervisord_"$VAR1".conf /etc/supervisor/supervisord_"$VAR1".conf
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord_${VAR1}.conf"]

on docker run id, I have got :

Error: could not find config file /etc/supervisor/supervisord_${ENV1}.conf

without ARG on Dockerfile, my suprevisord works very well

docker build --build-arg ARG1=conf1

looock7897
  • 27
  • 3

2 Answers2

0

ARG in Dockerfile is only available in the build stage.

When you want to run it as a container, ARG values will not be available but ENV will be. This means you can not directly access those values in CMD (also not available in ENTRYPOINT). You can read this similar question for more info.

If you want to pass environment parameters to the container using the build arguments (ARG), the simple solution will be to do something like this:

ARG ARG1
ENV ENV1=$ARG1

Then update your CMD

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord_${ENV1}.conf"]

Remember your COPY instruction should still use ARG since it is used in the build stage. So your Dockerfile will be:

ARG ARG1
ENV ENV1=$ARG1

COPY files/etc/supervisor/supervisord_"$ARG1".conf /etc/supervisor/supervisord_"$ARG1".conf
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord_${ENV1}.conf"]

Then you can use the usual docker run ... command you used to run this image.


You can simplify this further like below as well:

ARG VAR1
ENV VAR1=$VAR1

COPY files/etc/supervisor/supervisord_"$VAR1".conf /etc/supervisor/supervisord_"$VAR1".conf
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord_${VAR1}.conf"]

Then use the following build command to build the Dockerfile:

docker build --build-arg VAR1=conf1
Eranga Heshan
  • 3,938
  • 3
  • 21
  • 38
  • thanks for your replying, but on docker run id, but I have gave an error Error: could not find config file /etc/supervisor/supervisord_${ENV1}.conf – looock7897 Aug 09 '21 at 10:09
  • What was your docker build command? It should be `docker build --build-arg VAR1=conf1 .` – Eranga Heshan Aug 09 '21 at 10:30
  • my command is docker build --build-arg VAR1=conf1 -f toto/Dockerfile . and after docker run id_contenair – looock7897 Aug 09 '21 at 11:14
  • Can you try, `docker build --build-arg VAR1=conf1 -f toto/Dockerfile -t supervisor:latest .` for building and `docker run supervisor:latest` to run the built image. This is to make sure you are running the correct image you build. – Eranga Heshan Aug 09 '21 at 11:24
  • still the same problem – looock7897 Aug 09 '21 at 12:36
  • It seems like @David Maze's answer is a better solution than trying to just fix the issue you have. Try it and comment on it if you have issues. Good luck! – Eranga Heshan Aug 09 '21 at 12:39
0

If you need to override the command that's eventually being run, you can directly specify that when you run the container; you shouldn't need to rebuild the image to run a different command or have a different input file.

docker run your-image \
  supervisord -c /etc/supervisor/supervisord_foo.conf

The way you've written your Dockerfile, though, there will never be more than one configuration file in the image. When you COPY it in, you can use a fixed name.

ARG ARG1
# Copy the file to its default location; then you don't need a -c option
COPY files/etc/supervisor/supervisord_"$ARG1".conf /etc/supervisor/supervisord.conf
CMD ["/usr/bin/supervisord"]

Many tools and configuration frameworks support passing most or all of their options as environment variables, and in your own application you should consider this pattern as well. Setting environment variables directly (with a docker run -e option) tends to be much easier than overriding the command.

Finally: this overall setup looks like you're trying to run multiple processes in a container, and then configure the container to run different subsets of those processes. Usual best practice is to run only one process in a container, and avoid process managers like supervisord. You might consider whether a tool like Docker Compose that can start multiple containers together is a good match for your application; you can run commands like docker-compose up -d backend to start only a part of your application stack.

David Maze
  • 94,671
  • 18
  • 109
  • 144