I am trying the create a single Dockerfile for my development environments that I can use to customize an image by setting various flags.
The following example illustrates this point, I'm currently using ARG and bash if/then to accomplish this. However, it gets pretty cumbersome quickly. This trivial case illustrates that sometimes I want to have Python alone, sometimes, Python and R, sometimes R alone, and then sometimes these mixed with vi. This is a trivial case my real-world use case is just more such options (R, Python, C , vi, EMACS, and so forth.)
FROM debian
ARG R
ARG PY
ARG VI
RUN apt-get update
RUN if [ $VI = 1 ]; then apt-get install vim -y; fi
RUN if [ $PY = 1 ]; then apt-get install python3 -y; fi
RUN if [ $R = 1 ]; then apt-get install r-base r-base-dev -y; fi
So say if I want to build a development image which as R and vi installed I can issue the following:
docker build -t foo --build-arg VI=1 --build-arg R=1 .
Another approach I can take seems to be multi-stage builds but it doesn't seem to offer me the flexibility to choose which components I want.
From my research it seems buildx might be the correct tool for this application. Would appreciate if folks can chime in if buildx is one of the correct approaches to this problem
CodePudding user response:
What you show is the only conditional syntax any version of Docker supports. See the standard Dockerfile reference, the BuildKit Dockerfile extensions, and Build images with BuildKit; none of them support any conditional syntax beyond embedding a shell if ... fi
conditional in a RUN
command.
In practice you don't really need the level of conditional you show. A Docker image typically packages a single application and its dependencies, and you know what those dependencies are. So if your application is in Python, you need to install Python; if it calls subprocess.call(["vim", ...])
then you need that external dependency; and so on. It's usually more straightforward to have a single fixed Dockerfile that installs what you need where you need it than to make it infinitely customizable.