如何在 运行 时间给 docker 容器的端口号?

How to give port number for docker container at run time?

我已经编写了一个基于 Scala 和 Akka HTTP 的 REST API 并创建了 Docker 文件来为这个 API 创建 Docker 图像。我的Docker文件如下:

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 main class,这样它将把它必须 运行 的端口号作为命令行参数。如果未提供命令行参数,则它将在 8080 端口上侦听请求。

我想知道如何在启动容器时向我的 REST API 提供命令行参数?

例如:

  1. REST API 的第一个实例应该 start/run 在端口 5555 上,所以这个 5555 参数应该到达 REST API
  2. 的主要 class
  3. REST API 的第二个实例应该 start/run 在端口 1111 上,所以这个 5555 参数应该到达 REST API
  4. 的主要 class

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

您可以将 ARG 设置为您的容器:

ARG MYPORT

然后像这样导出:

CMD [ $MYPORT ]

然后像这样开始你的 docker:

export MYPORT=5000 ; docker run ....

通过环境变量

在 Dockerfile 中:

ENV PORT 8080 

您可以通过传递 -e 来覆盖 cmd 上的上述 env,例如

docker run -d my_image -e "PORT=5555"

在您的应用程序代码中使用 env

例如如果您不在 cmd 上提供 env,您的应用程序代码将收到 8080 作为 PORT 值。如果您在 cmd 上覆盖 env,您的应用程序代码将收到 5555 作为 PORT 值

Docker端口映射就是你的答案。

Docker设置您的 API 与为您的 API 提供您想要 运行 的端口完全相反。这正是您在采用 Docker 方式时不想做的事情。

您的 API 应该能够通过您决定在 docker 图像上 EXPOSE 的任何端口处理您的请求,然后在 运行 时间,您只需要将您希望的任何端口从您的主机映射到您的 API 的内部端口(在其容器内,将始终使用相同的 "internal" 端口。

所以..它看起来怎么样?

docker run -d --name api-1 -p 5555:8080 my/api

然后...

docker run -d --name api-2 -p 1111:8080 my/api

现在这两个实例都在您的主机上 运行,您可以访问它们,每个实例都有不同的主机端口(即使它们在内部使用相同的端口号)