我已经编写了一个基于Scala和Akka HTTP的REST API,并创建了Dockerfile来为此API创建Docker映像。我的Dockerfile如下:
FROM maven:3.6.0-jdk-8-alpine AS MAVEN_TOOL_CHAIN
COPY pom.xml /tmp/parent/
COPY data-catalogue/pom.xml /tmp/parent/data-catalogue/
COPY data-catalogue/src /tmp/parent/data-catalogue/src/
WORKDIR /tmp/parent/data-catalogue/
RUN mvn package
FROM java:openjdk-8
COPY --from=MAVEN_TOOL_CHAIN /tmp/parent/data-catalogue/target/data-catalogue-1.0-SNAPSHOT.jar /opt/data-catalogue.jar
COPY data-catalogue/src/main/resources/logback.xml /opt/logback.xml
ENTRYPOINT ["java", "-Dlogging.config=/opt/logback.xml", "-jar", "/opt/data-catalogue.jar", "prod"]
CMD ["8080"]
到目前为止一切都很好。我可以使用此图像运行一个容器。
现在的要求是使用同一镜像在同一Docker主机上运行两个容器。我已经修改了REST APIs主类,以便它将必须在其上作为命令行参数运行的端口号。如果未提供命令行参数,它将在8080端口上侦听请求。
我想知道在启动容器时如何向REST API提供命令行参数吗?
例如:
为此,我尝试使用ENTRYPOINT
和CMD
,但我的命令行参数根本无法到达主类,并且REST API仅在8080端口上启动。
答案 0 :(得分:3)
Docker PORT映射是您的答案。
对API进行码头处理与为API提供每次要运行它的端口完全相反。这正是您采用Docker方式时不想做的事情。
您的API应该能够通过您决定在docker映像上EXPOSE
的任何端口来处理您的请求,然后,在运行时,您只需要将主机上希望的任何端口映射到API的内部端口(在其容器内,它将始终处于同一“内部”端口。
所以..看起来如何?
docker run -d --name api-1 -p 5555:8080 my/api
然后...
docker run -d --name api-2 -p 1111:8080 my/api
现在,这两个实例都在您的主机上运行,并且您都可以使用各自的主机端口(即使在内部使用相同的端口号)访问这两个实例
答案 1 :(得分:2)
您可以将ARG设置为您的容器:
ARG MYPORT
然后将其导出为:
CMD [ $MYPORT ]
然后像这样启动您的docker:
export MYPORT=5000 ; docker run ....
答案 2 :(得分:2)
通过环境变量
在Dockerfile中:
ENV PORT 8080
您可以通过传递env
来替代cmd上的上述-e
。
docker run -d my_image -e "PORT=5555"
在应用程序代码中使用env
例如如果未在cmd上提供env,则您的应用程序代码将收到8080
作为PORT值。如果您确实在cmd上覆盖了环境,则您的应用程序代码将收到5555
作为端口值