Dockerfile CMD не выполняет скрипт bash

Dockerfile CMD не выполняет сценарий bash, как ожидалось, например. эхо-команды в set-env.sh не выполняются.

Во-первых, я передаю env var в образ, который Dockerfile использует.

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

Вот Dockerfile, который я использую

# 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 (упоминается в последней Dockerfile строке выше)

#!/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

Выше ничего НЕ повторяется в env-config.js - не знаю, почему.

Однако всякий раз, когда я запускаю set-env.sh вручную из контейнера, он работает так, как ожидалось, например. выводит тестовую строку DEV или PROD в env-config.js на основе параметра env, переданного в команду сборки docker

Есть идеи?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
71
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В вашем Dockerfile вы устанавливаете переменную ENVIRONMENT, но в своем скрипте вы тестируете переменную env.

Переменные аргумента сборки не передаются как переменные среды, поэтому вы не можете использовать env, не установив его в Dockerfile.

Либо изменить

ENV ENVIRONMENT=$env

к

ENV env=$env

в Dockerfile или измените операторы скрипта if на

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

Лучше использовать =, а не == - таким образом, операторы работают так же хорошо с базовым стандартом [ (по крайней мере, когда добавляются дополнительные кавычки), и вы не создаете память пальца только для bash. В качестве альтернативы рассмотрите case $ENVIRONMENT in dev) echo "TEST: DEV";; prod) echo "TEST: PROD";; *) echo "Unsupported environment" >&2; exit 1;; esac >>./env-config.js, который вообще не требует никаких расширений bash.

Charles Duffy 04.04.2023 16:56

(Я также собирался предложить в вопросе изменить строку shebang на #!/bin/sh и не устанавливать bash в Dockerfile; похоже, что на самом деле это не использует какие-либо функции bash.)

David Maze 04.04.2023 17:29

Спасибо за всю информацию, размещенную всеми.

Проблема была связана с тем, как я тестировал скрипт. Я выполнил следующее и вошел в контейнер, чтобы проверить, что на самом деле произошло.

docker run test-app tail -F asdflg

Без моего ведома команда tail, разрешая запуск контейнера, на самом деле, казалось, задерживает обработку CMD в последней строке моего Dockerfile... Как только я вместо этого запустил контейнер с помощью docker compose up, все заработало, как и ожидалось.

Другие вопросы по теме