skip to Main Content

I have a config.sh:

IMAGE_NAME="back_end"
APP_PORT=80
PUBLIC_PORT=8080

and a build.sh:

#!/bin/bash

source config.sh

echo "Image name is: ${IMAGE_NAME}"

sudo docker build -t ${IMAGE_NAME} .

and a run.sh:

#!/bin/bash

source config.sh

# Expose ports and run
sudo docker run -it 
        -p $PUBLIC_PORT:$APP_PORT 
        --name $IMAGE_NAME $IMAGE_NAME

and finally, a Dockerfile:

...
CMD ["gunicorn", "-b", "0.0.0.0:${APP_PORT}", "main:app"]

I’d like to be able to reference the APP_PORT variable in my config.sh within the Dockerfile as shown above. However, what I have does not work and it complains: Error: ${APP_PORT} is not a valid port number. So it’s not interpreting APP_PORT as a variable. Is there a way to reference the variables within config.sh from within the Dockerfile?

Thanks!

EDIT: New Files based on suggested solutions (still don’t work)

I have a config.sh:

IMAGE_NAME="back_end"
APP_PORT=80
PUBLIC_PORT=8080

and a build.sh:

#!/bin/bash

source config.sh

echo "Image name is: ${IMAGE_NAME}"

sudo docker build --build-arg APP_PORT="${APP_PORT}" -t "${IMAGE_NAME}" .

and a run.sh:

#!/bin/bash

source config.sh

# Expose ports and run
sudo docker run -it 
        -p $PUBLIC_PORT:$APP_PORT 
        --name $IMAGE_NAME $IMAGE_NAME

and finally, a Dockerfile:

FROM python:buster

LABEL maintainer="..."

ARG APP_PORT
#ENV PORT $APP_PORT
ENV APP_PORT=${APP_PORT}

#RUN echo "$PORT"

# Install gunicorn & falcon
COPY requirements.txt ./
RUN pip3 install --no-cache-dir -r requirements.txt

# Add demo app
COPY ./app /app
COPY ./config.sh /app/config.sh
WORKDIR /app

RUN ls -a

CMD ["gunicorn", "-b", "0.0.0.0:${APP_PORT}", "main:app"]

run.sh still fails and reports: Error: '${APP_PORT} is not a valid port number.'

2

Answers


  1. You need a shell to replace environment variables and when your CMD is in exec form, there’s no shell.

    If you use the shell form, there is a shell and you can use environment variables.

    CMD gunicorn -b 0.0.0.0:${APP_PORT} main:app
    

    Read here for more information on the two forms of the CMD statement: https://docs.docker.com/engine/reference/builder/#cmd

    Login or Signup to reply.
  2. Define a variable in Dockerfile as follows:

    FROM python:buster
    
    LABEL maintainer="..."
    
    ARG APP_PORT
    ENV APP_PORT=${APP_PORT}
    
    
    # Install gunicorn & falcon
    COPY requirements.txt ./
    RUN pip3 install --no-cache-dir -r requirements.txt
    
    # Add demo app
    COPY ./app /app
    COPY ./config.sh /app/config.sh
    WORKDIR /app
    
    CMD gunicorn -b 0.0.0.0:$APP_PORT main:app     # NOTE! without separating with ["",""] 
    

    Pass it as build-arg, e.g. in your build.sh:

    Note! Passing build argument is only necessary when it is used for building docker image. You use it on CMD and one can omit passing it during building docker image.

    #!/bin/bash
    
    source config.sh
    
    echo "Image name is: ${IMAGE_NAME}"
    
    sudo docker build --build-arg APP_PORT="${APP_PORT}" -t "${IMAGE_NAME}" .
    # sudo docker build --build-arg APP_PORT=80 -t back_end .           -> You may omit using config.sh and directly define the value of variables
    

    and pass value of $APP_PORT in run.sh as well when starting the container:

    #!/bin/bash
    
    source config.sh
    
    # Expose ports and run
    sudo docker run -it 
            -e APP_PORT=$APP_PORT 
            -p $PUBLIC_PORT:$APP_PORT 
            --name $IMAGE_NAME $IMAGE_NAME
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search