Bash 脚本在 Dockerfile 构建过程中失败



我有一个看起来像这样的Dockerfile:

FROM node:14.0.0 as dev-stage
WORKDIR /app
ENV NODE_ENV=development
COPY package.json ./
RUN yarn install
FROM node:14.0.0 as build-stage
WORKDIR /app
ENV NODE_ENV=production
COPY --from=dev-stage /app/node_modules node_modules
COPY . .
RUN yarn run build
FROM abiosoft/caddy:1.0.3
COPY Caddyfile /etc/Caddyfile
COPY --from=build-stage /app/dist /usr/share/caddy/html
WORKDIR /usr/share/caddy/html
COPY ./env.sh .
COPY .env .
RUN chmod +x env.sh && /usr/share/caddy/html/env.sh

以及如下所示的env.sh脚本:


# Recreate config file
rm -rf ./config.js
touch ./config.js
# Add assignment 
echo "window._env_ = {" >> ./config.js
# Read each line in .env file
# Each line represents key=value pairs
while read -r line || [[ -n "$line" ]];
do
# Split env variables by character `=`
if printf '%sn' "$line" | grep -q -e '='; then
varname=$(printf '%sn' "$line" | sed -e 's/=.*//')
varvalue=$(printf '%sn' "$line" | sed -e 's/^[^=]*=//')
fi
# Read value of current variable if exists as Environment variable
value=$(printf '%sn' "${!varname}")
# Otherwise use value from .env file
[[ -z $value ]] && value=${varvalue}
# Append configuration property to JS file
echo "  $varname: "$value"," >> ./config.js
done < .env
echo "}" >> ./config.js

当我尝试构建它时,我收到此错误消息

Step 18/18 : RUN chmod +x env.sh && /usr/share/caddy/html/env.sh
---> Running in 9e928ef2d9fd
/usr/share/caddy/html/env.sh: line 27: syntax error: bad substitution
/usr/share/caddy/html/env.sh: line 27: syntax error: bad substitution
/usr/share/caddy/html/env.sh: line 27: syntax error: bad substitution
/usr/share/caddy/html/env.sh: line 27: syntax error: bad substitution
/usr/share/caddy/html/env.sh: line 27: syntax error: bad substitution
/usr/share/caddy/html/env.sh: line 27: syntax error: bad substitution
/usr/share/caddy/html/env.sh: line 27: syntax error: bad substitution

在本地运行脚本工作得很好,完全符合我的意图,只是不在 Docker 构建过程中。 我在这里错过了什么。

任何帮助将不胜感激。

您的脚本是为bash编写的,但您正在使用/bin/sh运行它,在node:14.0.0图像中,它不是指向bash的链接。相反,它是一个传统的POSIX外壳。

特别是${!varname}语法是一种bash-ism:

value=$(printf '%sn' "${!varname}")

解决此问题的最简单方法是使用以下命令启动脚本:

#!/bin/bash

或者只需将最后一行RUN更改为如下所示:

RUN bash /usr/share/caddy/html/env.sh

这是我的测试。 如果我从一个看起来像这样的env.sh开始:

#!/bin/sh
foo=1
varname=foo
echo "foo is ${!varname}"

而这个Dockerfile

FROM node:14.0.0
COPY env.sh /tmp/env.sh
RUN chmod +x /tmp/env.sh; /tmp/env.sh

它按预期失败,并显示:

/tmp/env.sh: 5: /tmp/env.sh: Bad substitution

但是如果我将Dockerfile修改为如下所示:

FROM node:14.0.0
COPY env.sh /tmp/env.sh
RUN bash /tmp/env.sh

它按预期工作。

最新更新