如何在运行时给Docker容器提供端口号?

时间:2019-06-28 10:09:55

标签: scala rest docker containers akka-http

我已经编写了一个基于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提供命令行参数吗?

例如:

  1. REST API的第一个实例应在端口5555上启动/运行,因此此5555参数应到达REST API的主类
  2. REST API的第二个实例应在端口1111上启动/运行,因此此5555参数应到达REST API的主类

为此,我尝试使用ENTRYPOINTCMD,但我的命令行参数根本无法到达主类,并且REST API仅在8080端口上启动。

3 个答案:

答案 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作为端口值