Reputation: 635
TL;DR
The server.port
property defined in a Spring Boot application.properties file is not getting honored by the Docker engine when running a web application in Tomcat.
Background :
I have a simple Spring Boot application containing a single rest endpoint. I am able to run this application in Eclipse and access the rest endpoint successfully from the browser.
However, when I try to deploy the same application in a Docker container, I am unable to access the rest endpoint from the browser.
Dockerfile :
FROM tomcat
EXPOSE 8000
RUN rm -rf /user/local/tomcat/webapps/*
COPY ./target/my-web-app.war /usr/local/tomcat/webapps/ROOT.war
CMD ["catalina.sh","run"]
Spring Boot application.properties :
spring.application.name=my-web-app
server.port=8000
spring.jpa.show-sql=true
spring.h2.console.enabled=true
Docker images output :
CK@Ping MINGW64 /c/Program Files/Docker Toolbox
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myrepo/my-web-app 0.0.1-SNAPSHOT 625e9d889139 4 minutes ago 694MB
Start the container :
Note that I map the server.port
of my Spring Boot application.properties
file to the external port.
docker run -p 8000:8000 -d myrepo/my-web-app:0.0.1-SNAPSHOT
docker container ls output :
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3eff09347de3 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
Error in the Browser :
This site can’t be reached
I am trying to access the URL using :
http://192.168.99.100:8000/my-web-app/getResults
The same app works just fine when launched from Eclipse instead of a Docker container and I am able to access the rest end point using :
http://localhost:8000/my-web-app/getResults
Update/Edit:
I found the root cause. I need to map port 8000 to 8080 instead of mapping 8000 to 8000 itself :
docker run -p 8000:8080 -d myrepo/my-web-app:0.0.1-SNAPSHOT
This means that the server.port
property that I defined in my application.properties
is not getting honored when starting up the container.
What is even more strange is that I can set the server.port
to 8111
for example and still be able to access the URL if I use -p 8000:8080
.
However, tomcat starts up on the port specified by server.port
if I run the same application in Eclipse rather than a Docker container.
Bottom line : The server.port
property defined in a Spring Boot application.properties file is not getting honored by the Docker engine.
Upvotes: 2
Views: 2468
Reputation: 16930
server.port
property is used to configure port for the spring boot embedded server. In your case you are trying to deploy a war
file with your application to a standalone tomcat server (which is contained in your image) - so the embedded spring boot server is not even used and setting this property has no effect.
To achieve what you want you would have to modify the server.xml
file of the tomcat that is installed on your image and modify the connector port. So you could copy the overriden server.xml
to your image:
<?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 "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
and the 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"]
and then run your image:
docker run -p 8000:8000 -d myrepo/my-web-app:0.0.1-SNAPSHOT
If you have your spring boot jar copied to your image, you can set SERVER_PORT
environment variable during container launching, to override the property defined in application.properties
:
docker container run -e SERVER_PORT=8000 -p 8000:8000 myimage
Upvotes: 5