Heroku not setting property $PORT when deploying executable jar - spring-boot

I have a Gradle-Kotlin project that is a Spring boot project, and it runs a server on port 8080 by default.
When I compile and generate a jar with command ./gradlew bootJar, I can set up the server justing by executing this jar. I wanted to run this server remotely, so I used Heroku (heroku deploy:jar) to upload the .jar. I could upload the jar and start the server with Heroku and it detected the buildback as heroku/jvm. With command heroku logs --tail I could verify that the server compiled and was up and running... but on port 8080. That is, I could't reach the server using heroku's public app url (ex https://radiant-crag-94685.herokuapp.com/my-end-point)
Reading some docs, I came to the PORT configuration. So I created a file called application.yml and put it in src/main/resources folder. This .yml file contained the following:
server:
port: $PORT
I generated the .jar file and uploaded to Heroku once more. But this time, the app crashed on its main class, with the message:
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value '$PORT'; nested exception is java.lang.NumberFormatException: For input string: "$PORT"
The exception was thrown here:
#SpringBootApplication
open class AutomatedTestsApplication
fun main(args: Array<String>) {
runApplication<AutomatedTestsApplication>(*args)
}
How can I solve this problem?

You can use the variable in your application.yml like you have doing this:
server:
port: ${PORT}
Alternatively, as you mentioned in your comment, I think it would be better to override via startup command using something like:
java -jar service.jar --server.port=${PORT}

Related

Cannot run Spring Boot aplication in Docker (Getting ERR_EMPTY_RESPONSE) in Windows 10?

I have a problem with my Spring Boot Application running in Docker.
Here is my Dockerfile embedded in my app shown below.
FROM adoptopenjdk:11-jre-hotspot
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","/app-0.0.1-SNAPSHOT.jar"]
After I run mvn clean install, I get an app-0.0.1-SNAPSHOT.jar and then define it into a Docker file
Next, I ran this command docker build -t app . I saw this container installed on my docker desktop.
After running this command docker image ls, I also saw this container in the list.
I ran this command docker run -p 9999:8080 app to run it in docker.
The container worked flawlessly after running this command (docker ps)
Next, I test any URL like http://localhost:9999/getCategoryById/1 instead of http://localhost:8080/getCategoryById/1 in Postman but I get the message (Could not send request). When I test this URL in the browser, I get the message ERR_EMPTY_RESPONSE.
I learned the container IP address via docker inspect container_id then I used http://172.17.0.2:9999/getCategoryById/1 but nothing changed.
I also checked if the IP address manages the package (ping 172.17.0.2) but I got Request timed out message.
Here is my project link : Link
How can I fix my issue?
In your application, server.port property in application.properties file, that's used to configure port for Spring Boot embedded Tomcat Server is 8082.
To access the application on the container port 8080, you'd need to override server.port property. One of the ways property can be overridden is using an environment variable like below,
docker run -e SERVER_PORT=8080 -p 9999:8080 app
where SERVER_PORT corresponds to the container port specified in -p <hostPort>:<containerPort>
Other option is to directly update the property in application.properties file like below. After the update, you can then use the same command you've used to run the docker image docker run -p 9999:8080 app
server.port= 8080

Cloud Run: deploying spring docker image causing error; Failed to start and then listen on the port defined by the PORT environment variable

I am trying to deploy spring boot docker image stored at Docker Registry to Cloud Run.
However, when I deployed the image, I got the error;
Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more information.
I understand this could be caused by port and address setting, so I fixed these parts referring the official doc, though still experiencing the same error. Concretely, I set these things as below, on application.yml.
server:
port: ${PORT:8080}
address: ${ADDRESS:localhost}
I understand PORT variable would be passed by Cloud Run(in my case, port num is set to 8080 on Cloud Run). And also ADDRESS will be passed to by myself(the value is 0.0.0.0, referring the official doc).
For reference, the below is my Dockerfile building spring boot docker image;
# Stage1 - execute build process
FROM openjdk:14-jdk-alpine as build_process
WORKDIR /back_end
COPY . .
RUN ./gradlew build -x test
# Stage2 - boot app with the build output above
FROM openjdk:14-jdk-alpine
EXPOSE ${PORT}
COPY --from=build_process /back_end/build/libs/back_end-0.0.1-SNAPSHOT.jar ./app.jar
RUN adduser -D user
USER user
ENTRYPOINT ["sh","-c","java -jar app.jar"]
Any help would be really appreciated. Thank you so much for reading!
I figured it out why my docker image had failed Cloud Run's health check. After all, it is not about Port and IP address, but about the timing when the health check process executes.
The health check process seems to start immediately once the image is deployed, though my case it took almost 30 secs to launch spring boot tomcat server after deploying to Cloud Run.
That led to the failure of the health check process, so I fixed settings to launch tomcat server immediately too, which solved the issue I posted.

spring boot failed to start due to "The port may already be in use"

I tried to start my spring boot application on centos server with this command line.
SPRING_PROFILES_ACTIVE=prd java -jar ./build/libs/port_switcher-0.0.1-SNAPSHOT.jar
But I got an error message that the port is already in used.
then looked up process list which is used in the port number using netstat
but there is no process that uses the port number
and then I rerun my spring boot application without SPRING_PROFILES_ACTIVE variable. (it was an mistake that forget that variable)
at that time spring boot application run successfully.
I really want to know what problem is in my application properties
this command occur error
SPRING_PROFILES_ACTIVE=prd java -jar ./build/libs/port_switcher-0.0.1-SNAPSHOT.jar
this command works fine
java -jar ./build/libs/port_switcher-0.0.1-SNAPSHOT.jar
application-prd.properties
#Server
server.address=xxx.xxx.xxx.xxx
server.port=9090
#Devtools
spring.devtools.livereload.enabled=true
spring.devtools.restart.enabled=true
# Logging
logging.level.org.springframework.web=INFO
logging.level.com.kakao.portswitcher=INFO
logging.path=logs
server.tomcat.basedir=./
server.tomcat.accesslog.enabled=true
#server.tomcat.accesslog.file-date-format=.yyyy-MM-dd
server.tomcat.accesslog.rotate=true
server.tomcat.accesslog.suffix=.log
server.tomcat.accesslog.prefix=access
server.tomcat.accesslog.directory=logs
server.tomcat.accesslog.buffered=true
#Jackson
spring.jackson.property-naming-strategy=SNAKE_CASE
# Status check file
status.file=./port_switcher_status
Can you try this :
java -jar -Dspring.profiles.active=prd ./build/libs/port_switcher-0.0.1-SNAPSHOT.jar

Intellij, Spring dev tools remote, Docker, error Unexpected 404 response uploading class files

Im trying to use Spring Boot Dev tools (Spring Remote), and automatically upload recompiled files to my docker container.
I keep receiving
Unexpected 404 response uploading class files
This is my docker file:
FROM java:8
WORKDIR /first
ADD ./build/libs/first.jar /first/first.jar
EXPOSE 8080
RUN bash -c 'touch /first/first.jar'
ENTRYPOINT ["java","-Dspring.data.mongodb.uri=mongodb://mongodb/micros", "-Djava.security.egd", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005","-jar", "first.jar"]
This is my configuration and the configuration
And this is the error I'm receiving:
As of Spring Boot 1.5.0, devtools defaults were changed to exclude the devtools from fat jars.
If you want to include them, you have to set the excludeDevtools flag to false.
However, the devtools documentation doesn't explain how to do this. The necessary documentation is actually in the spring-boot-gradle-plugin documentation.
To do it, you can put this snippet of code in your build.gradle file:
bootRepackage {
excludeDevtools = false
}
Unfortunately, this was buggy at first and had no effect as of Spring Boot 1.5.0. The workaround was to do this instead:
springBoot {
excludeDevtools = false
}
However, I have verified that the bootRepackage approach works for Spring Boot 1.5.8 .
I got the same issues as yours while using docker-compose to compose my application ( a web service + redis server + mongo server ).
As the Spring developer tools document point out "Developer tools are automatically disabled when running a fully packaged application. If your application is launched using java -jar or if it’s started using a special classloader, then it is considered a “production application”."
I think when we running Spring Web Application inside Docker container, the developer tool is disabled then we cant remotely restart it.
Currently, I'm running my web application on the host machine and set the redis server, mongo server inside containers so I can restart the web app quickly when the code is changing in development process.
In my case I had to put the application context on the argument of the IDE RemoteSpringApplication configuration.
For example, my application root context was /virtue so I had to configure it like so:

Issue deploying Spring GS Rest Service to Cloud Foundry

I imported the "Spring Getting Started - Rest Service" as a new project into Spring Tools. Works fine locally. After building the JAR with mvn clean package and editing the manifest.yml to correctly point to the JAR location I've tried to deploy this project to Cloud Foundry. The project deploys fine but fails shortly after starting with the following error.
Instance (index 0) failed to start accepting connections
App instance exited with guid 96f2fbd0-aaa3-48aa-9181-55abf624c626 payload:
{
"cc_partition"=>"default",
"droplet"=>"96f2fbd0-aaa3-48aa-9181-55abf624c626",
"version"=>"9ee684a6-7d62-4f45-9481-97d4e87c3895",
"instance"=>"db08e1b5fba44d938f4904ae4c921878",
"index"=>0,
"reason"=>"CRASHED",
"exit_status"=>-1,
"exit_description"=>"failed to accept connections within health check timeout",
"crash_timestamp"=>1439875540
}
Try to:
increase timeout by calling cf push -t 180
set server port to 8080 in cloud profile
or change health-check-type inside the manifest.yml:
---
applications:
- name: ...
health-check-type: process

Resources