如何在 运行 时间给 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 提供命令行参数?
例如:
- REST API 的第一个实例应该 start/run 在端口 5555 上,所以这个 5555 参数应该到达 REST API
的主要 class
- REST API 的第二个实例应该 start/run 在端口 1111 上,所以这个 5555 参数应该到达 REST API
的主要 class
我尝试为此使用 ENTRYPOINT
和 CMD
,但我的命令行参数根本无法到达主 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
现在这两个实例都在您的主机上 运行,您可以访问它们,每个实例都有不同的主机端口(即使它们在内部使用相同的端口号)
我已经编写了一个基于 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 提供命令行参数?
例如:
- REST API 的第一个实例应该 start/run 在端口 5555 上,所以这个 5555 参数应该到达 REST API 的主要 class
- REST API 的第二个实例应该 start/run 在端口 1111 上,所以这个 5555 参数应该到达 REST API 的主要 class
我尝试为此使用 ENTRYPOINT
和 CMD
,但我的命令行参数根本无法到达主 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
现在这两个实例都在您的主机上 运行,您可以访问它们,每个实例都有不同的主机端口(即使它们在内部使用相同的端口号)