Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you assign an Array inside a Dockerfile?

I have tried a number of different ways to assign an array inside a RUN command within a Dockerfile. None of them seem to work. I am running on Ubuntu-Slim, with bash as my default shell.

I've tried this (second line below)

RUN addgroup --gid 1000 node \
    && NODE_BUILD_PACKAGES=("binutils-gold" "g++" "gcc" "gnupg" "libgcc-7-dev" "linux-headers-generic" "make" "python3" ) \
...

But it fails with /bin/sh: 1: Syntax error: "(" unexpected.

I also tried assigning it as an ENV variable, as in:

ENV NODE_BUILD_PACKAGES=("binutils-gold" "g++" "gcc" "gnupg" "libgcc-7-dev" "linux-headers-generic" "make" "python3" )

but that fails as well.

Assigning and using arrays in Bash is completely supported. Yet, it appears that I can't use that feature of Bash when running in a Dockerfile. Can someone confirm/deny that you can assign arrays variables inside of shell commands in Dockerfile RUN syntax (or ENV variable syntax)?

like image 213
Kim Gentes Avatar asked Apr 18 '26 12:04

Kim Gentes


2 Answers

You can have array NODE_BUILD_PACKAGES in RUN if you define SHELL :

SHELL ["/bin/bash", "-c"]
like image 98
Philippe Avatar answered Apr 21 '26 02:04

Philippe


The POSIX shell specification does not have arrays. Even if you're using non-standard shells like GNU bash, environment variables are always simple strings and never hold arrays either.

The default shell in Docker is usually /bin/sh, which should conform to the POSIX spec, and not bash. Alpine-based images don't have bash at all unless you go out of your way to install it. I'd generally recommend trying to stick to the POSIX syntax whenever possible.

A typical Dockerfile is fairly straightforward; it doesn't have a lot of parts that get reused multiple times and most of the things you can specify in a Dockerfile you don't need to be user-configurable. So for a list of OS packages, for example, I'd just list them out in a RUN command and not bother trying to package them into a variable.

RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
    apt-get install --no-install-recommends --assume-yes \
      binutils-gold \
      g++ \
      gcc \
      ...

Other things I see in Stack Overflow questions that do not need to be parameterized include the container path (set it once as the WORKDIR and refer to . thereafter), the process's port (needs to be a fixed number for the second docker run -p part), and user IDs (can be overridden with docker run -u, and you don't usually want to build an image that can only run on one system).

WORKDIR /app      # not an ENV or ARG
COPY . .          # into the WORKDIR, do not need to repeat
RUN adduser node  # with no specific uid
EXPOSE 3000       # a fixed port number
RUN mkdir /data   # also use a fixed path for potential mount points
like image 45
David Maze Avatar answered Apr 21 '26 00:04

David Maze



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!