Windows 上的 Docker 引擎会忽略 Spring Boot Web 应用程序的 server.port 属性

Pin*_*ing 2 java windows tomcat docker spring-boot

长话短说

\n\n

Spring Bootserver.port中定义的属性在 Tomcat 中运行 Web 应用程序时,Docker 引擎不会遵循

\n\n
\n\n

背景 :

\n\n

我有一个简单的 Spring Boot 应用程序,其中包含一个休息端点。我能够在 Eclipse 中运行此应用程序并从浏览器成功访问其余端点。

\n\n

但是,当我尝试在 Docker 容器中部署相同的应用程序时,我无法从浏览器访问其余端点。

\n\n

Dockerfile:

\n\n
FROM tomcat\nEXPOSE 8000\nRUN rm -rf /user/local/tomcat/webapps/*\nCOPY ./target/my-web-app.war /usr/local/tomcat/webapps/ROOT.war\nCMD ["catalina.sh","run"]\n
Run Code Online (Sandbox Code Playgroud)\n\n

Spring Boot application.properties :

\n\n
spring.application.name=my-web-app\nserver.port=8000\nspring.jpa.show-sql=true\nspring.h2.console.enabled=true\n
Run Code Online (Sandbox Code Playgroud)\n\n

Docker 图像输出:

\n\n
CK@Ping MINGW64 /c/Program Files/Docker Toolbox\n$ docker images\nREPOSITORY           TAG                  IMAGE ID            CREATED             SIZE\nmyrepo/my-web-app    0.0.1-SNAPSHOT       625e9d889139        4 minutes ago       694MB\n
Run Code Online (Sandbox Code Playgroud)\n\n

启动容器:

\n\n

请注意,我映射了Spring Bootserver.port application.properties映射到外部端口。

\n\n
docker run -p 8000:8000 -d myrepo/my-web-app:0.0.1-SNAPSHOT\n
Run Code Online (Sandbox Code Playgroud)\n\n

docker 容器 ls 输出:

\n\n
CONTAINER ID        IMAGE                                                COMMAND                  CREATED                  STATUS              PORTS                               NAMES\n3eff09347de3      myrep/my-web-app:0.0.1-SNAPSHOT              "catalina.sh run"        Less than a second ago            Up 4 seconds        0.0.0.0:8000->8000/tcp, 8080/tcp    hardcore\n
Run Code Online (Sandbox Code Playgroud)\n\n

浏览器中的错误:

\n\n
This site can\xe2\x80\x99t be reached\n
Run Code Online (Sandbox Code Playgroud)\n\n

我正在尝试使用以下方式访问 URL:

\n\n
http://192.168.99.100:8000/my-web-app/getResults\n
Run Code Online (Sandbox Code Playgroud)\n\n

当从 Eclipse 而不是 Docker 容器启动时,同一个应用程序运行得很好,我可以使用以下命令访问其余端点:

\n\n
http://localhost:8000/my-web-app/getResults\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

更新/编辑:

\n\n

我找到了根本原因。我需要将端口8000 映射到 8080,而不是映射8000 到 8000本身:

\n\n
docker run -p 8000:8080 -d myrepo/my-web-app:0.0.1-SNAPSHOT\n
Run Code Online (Sandbox Code Playgroud)\n\n

这意味着server.port我在我的中定义的属性application.properties在启动容器时不会得到尊重。

\n\n

更奇怪的是,我可以设置server.port8111例如,如果我使用仍然能够访问该URL-p 8000:8080

\n\n

但是,tomcat 在指定的端口上启动server.port但是,如果我在 Eclipse 中而不是 Docker 容器中运行相同的应用程序,

\n\n

底线:Spring Bootserver.port中定义的属性 D​​ocker 引擎不支持

\n

mic*_*alk 5

docker镜像上独立tomcat的解决方案

server.portproperty用于配置spring boot嵌入式服务器的端口。在您的情况下,您尝试将war应用程序的文件部署到独立的 tomcat 服务器(包含在您的映像中) - 因此甚至不使用嵌入式 spring boot 服务器,并且设置此属性没有任何效果。

要实现您想要的效果,您必须修改server.xml安装在映像上的 tomcat 文件并修改连接器端口。因此,您可以将覆盖复制server.xml到您的图像中:

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">
    <!-- change port here-->
    <Connector port="8000" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>
Run Code Online (Sandbox Code Playgroud)

和 dockerfile :

FROM tomcat:9.0
EXPOSE 8000

COPY ./target/my-web-app.war /usr/local/tomcat/webapps/ROOT.war

#override server.xml
COPY server.xml /usr/local/tomcat/conf/

CMD ["catalina.sh","run"]
Run Code Online (Sandbox Code Playgroud)

然后运行你的图像:

docker run -p 8000:8000 -d myrepo/my-web-app:0.0.1-SNAPSHOT
Run Code Online (Sandbox Code Playgroud)

docker容器中运行嵌入式tomcat的spring boot jar的解决方案

如果您已将 Spring Boot jar 复制到映像中,则可以SERVER_PORT在容器启动期间设置环境变量,以覆盖中定义的属性application.properties

docker container run -e SERVER_PORT=8000 -p 8000:8000 myimage
Run Code Online (Sandbox Code Playgroud)