skip to Main Content

Dockerfile CMD not executing a bash script as expected e.g. the echo commands in set-env.sh do not get executed.

First, I pass in an env var to the image for Dockerfile to use

docker build -f Dockerfile --pull --build-arg env=prod -t test-app .

Here’s the Dockerfile I’m using

# Multi-stage
# 1) Node image for building frontend assets
# 2) nginx stage to serve frontend assets

# Name the node stage "builder"
FROM node:16 AS builder
# Set working directory
WORKDIR /project
# Copy all files from current directory to working dir in image
COPY . .
# install node modules and build assets
RUN yarn install --network-timeout 100000 && yarn build

# nginx state for serving content
FROM nginx:alpine

# Nginx config
RUN rm -rf /etc/nginx/conf.d
COPY conf /etc/nginx

# Set working directory to nginx asset directory
WORKDIR /usr/share/nginx/html
# Remove default nginx static assets
RUN rm -rf ./*
# Copy static assets from builder stage
COPY --from=builder /project/build .

# Set enviorment so the set-env.sh script can read the correct env file
ARG env
ENV ENVIRONMENT=$env

# these statements print out the env vars as expected during the build
RUN echo $env
RUN echo $ENVIRONMENT

# Default port exposure
EXPOSE 443

# Copy environment file and script into container
COPY ./set-env.sh .

# Add bash
RUN apk add --no-cache bash

# Containers run nginx with global directives and daemon off
CMD ["/bin/bash", "-c", "/usr/share/nginx/html/set-env.sh && nginx -g 'daemon off;'"]

set-env.sh (referenced in the last Dockerfile line above)

#!/bin/bash

# Recreate config file
rm -rf ./env-config.js
touch ./env-config.js

# Choose the .env file base on "ENV" defined in the DockerFile
if [ $env == "dev" ]; then
  echo "TEST: DEV " >> ./env-config.js
elif [ $env == "prod" ]; then
  echo "TEST: PROD " >> ./env-config.js
else
  echo "Unsupported environment"
  exit 1
fi

Above does NOT echo anything out to env-config.js – not sure why.

However, whenever I run set-env.sh manually from within the container, it works as expected e.g. prints out DEV or PROD test line to env-config.js based on the env param passed in to the docker build command

Any ideas?

2

Answers


  1. Chosen as BEST ANSWER

    Thanks for all the info posted by everyone.

    The issue was related to how I was testing the script. I ran the following and logged in into the container to check on what actually happened.

    docker run test-app tail -F asdflg

    Unbeknown to me, the tail command, while allowing the container to run, actually seemed to hold up the processing of the CMD on the last line of my Dockerfile... Once I ran the container with docker compose up instead, everything worked as expected.


  2. In your Dockerfile, you set the variable ENVIRONMENT but in your script, you test on the variable env.

    Build argument variables are not passed on as environment variables, so you can’t use env without setting it in the Dockerfile.

    Either change

    ENV ENVIRONMENT=$env
    

    to

    ENV env=$env
    

    in the Dockerfile or change your script if statements to

    if [ $ENVIRONMENT == "dev" ]; then
      echo "TEST: DEV " >> ./env-config.js
    elif [ $ENVIRONMENT == "prod" ]; then
      echo "TEST: PROD " >> ./env-config.js
    else
      echo "Unsupported environment"
      exit 1
    fi
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search