我正在尝试构建一个映像,该映像可用于通过角度应用程序部署多个容器。
目的是让容器运行命令ng server --host ${HOST} --port ${PORT} --disable-host-check
并使用docker run
或docker-composes
自定义ENV变量,如:
默认env var(在Dockerfile中)
docker run -d --name bar -p 10000:4200 -v /path/to/AngularApp:/www me/ngx-admin:dev
将运行ng server --host 0.0.0.0 --port 4200 --disable-host-check
自定义:
docker run -d --name foo -e HOST='dev.my-domain.fr' -e PORT='4201' -p 10000:4201 -v /path/to/AngularApp:/www me/ngx-admin:dev
将运行ng server --host dev.my-domain.fr --port 4201 --disable-host-check
如果我正确理解了ENTRYPOINT
和CMD
,并且如果我同时将它们用作“执行表单”(JSON数组),则CMD
将串联在ENTRYPOINT
之后作为参数。
谢谢!
这是我的Dockerfile(使用我尝试过的CMD)以及我遇到的其他错误:
# base image
FROM node:12
# install chrome for protractor tests
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
RUN apt-get update && apt-get install -yq google-chrome-stable
# set working directory
WORKDIR /www
# add `/www/node_modules/.bin` to $PATH
ENV PATH /www/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /www/package.json
RUN npm install -g @angular/cli@7.3.9
RUN npm install
# add app
COPY . /www
# default env
ENV HOST 0.0.0.0
ENV PORT 4200
EXPOSE ${PORT}
# start www
ENTRYPOINT ["ng", "serve"]
CMD ["--host", "0.0.0.0", "--port", "4200", "--disable-host-check"] # WORKS!!
#CMD ["--host", "${HOST}", "--port", "${PORT}", "--disable-host-check"] # cf. ERR 1
#CMD ["--host", "${HOST}", "--port", ${PORT}, "--disable-host-check"] # cf. ERR 2
#CMD ["--host", "${HOST}", "--port", "4200", "--disable-host-check"] # cf. ERR 3
Cannot parse arguments. See below for the reasons.
Argument port could not be parsed using value "".Valid type(s) is: number
码头工人检查
"Path": "ng",<br>
"Args": [
"serve",<br>
"--host",<br>
"${HOST}",<br>
"--port",<br>
"${PORT}",<br>
"--disable-host-check"
],
Error: Project '/bin/sh' does not support the 'serve' target.
at ServeCommand.initialize (/www/node_modules/@angular/cli/models/architect-command.js:58:19)<br>
at async ServeCommand.validateAndRun (/www/node_modules/@angular/cli/models/command.js:127:9)<br>
at async Object.runCommand (/www/node_modules/@angular/cli/models/command-runner.js:178:24)<br>
at async default_1 (/www/node_modules/@angular/cli/lib/cli/index.js:32:31)
码头工人检查
"Path": "ng",<br>
"Args": [
"serve",<br>
"/bin/sh",<br>
"-c",<br>
"[\"--host\", \"${HOST}\", \"--port\", ${PORT}, \"--disable-host-check\"]\t\t# ERR 2"
],
rowserslist: caniuse-lite is outdated. Please run next command `npm update`
getaddrinfo EAI_AGAIN ${HOST}<br>
Error: getaddrinfo EAI_AGAIN ${HOST}
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:60:26)
码头工人检查
"Path": "ng",<br>
"Args": [<br>
"serve",<br>
"--host",<br>
"${HOST}",<br>
"--port",<br>
"4200",<br>
"--disable-host-check"
],
答案 0 :(得分:0)
使用执行列表时,Docker将按字面意义解释给定命令(不扩展变量)。
如果要扩展变量,则需要在CMD
中使用shell。您可以将ENTRYPOINT
和CMD
替换为仅使用以下内容:
CMD ["sh", "-c", "ng serve --host ${HOST} --port ${PORT} --disable-host-check"]
进一步阅读:Dockerfile CMD doesn't understand ENV variables [#5509]
答案 1 :(得分:0)
您不需要任何环境变量。
EXPOSE 4200
CMD ["ng", "serve", "--host", "0.0.0.0", "--port", "4200", "--disable-host-check"]
对于端口号,没有什么可以阻止您运行具有相同内部端口号的多个容器。通常,您会选择一个端口号并将其作为映像界面的一部分。您可以使用图像的端口号作为docker run -p
选项中的第二个数字,以完全按照显示的方式在图像之外运行多个容器。
docker run -d --name bar -p 10000:4200 me/ngx-admin:dev
docker run -d --name foo -p 10001:4200 me/ngx-admin:dev
对于--host
选项,实际上只有三件事可以将其设置为0.0.0.0(“每个接口”),127.0.0.1(“无法从此容器外部访问”)或容器最终将拥有的IP地址。由于Docker在组成命令行后分配了IP地址,因此您无法绑定到该地址,并且希望从外部访问该容器,因此127.0.0.1是错误的。剩下的唯一选择是0.0.0.0。
如果您确实要为此使用环境变量,那么查看CMD
和ENTRYPOINT
的Dockerfile文档非常有用。简要回顾一下:
CMD
将作为命令行参数传递到ENTRYPOINT
。sh -c '...'
中。 (对于RUN
也是如此。)(如果ENTRYPOINT
是一个简单的字符串,那么这几乎就根本使它根本就不用考虑CMD
了。)最简单的方法是仅使用CMD
,而不使用JSON数组形式
CMD ng serve --host "$HOST" --port "$PORT" --disable-host-check
Docker将为您提供sh -c
包装器。如问题所示,您无法将其在ENTRYPOINT
和CMD
之间分割,因为只有CMD
部分会被sh -c
包装器缠绕-您会缠绕用一个难以理解的ng serve sh -c '--host ...'
命令。