Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Starting Spring Boot as a foreground process from within a bash script

I package my Spring Boot war with embedded Tomcat servlet container. And deploy it as a regular java application using java -jar server.war <Spring Args>. I wrote a bash script that would take care of deploying the server as a background/foreground process:

start_foreground() {
    cmd="$JAVACMD ${JVM_OPTS} -jar ${WAR_FILE} ${SPRING_OPTS}"
    echo "\"${cmd}\""
    eval ${cmd}
    print_log "Server is stopped."
}

start_background() {
    SPRING_OPTS="--spring.pid.file=${PID_FILE} ${SPRING_OPTS}"
    cmd="nohup $JAVACMD ${JVM_OPTS} -jar ${WAR_FILE} ${SPRING_OPTS} &>${LOG_PATH}/console.log &"
    echo "\"${cmd}\""
    eval ${cmd}
    PID=$!
    print_log "Server is started with pid \"${PID}\""
}

As you can see, for background process start I use nohup. Everything is working fine, it sends STDOUT and STDERR to my ${LOG_PATH}/console.log. console.log reports that my server is up and running on preconfigured port (using Spring profiles). I have a profile dev-https that configured with port 8443:

spring:
  profiles.active: dev-https
...
---

spring:
    profiles: dev-https
server:
  port: 8443
  ssl:
    enabled: true
    protocol: TLS
    enabled-protocols: TLSv1.2
    key-store: <path>
    key-store-password: <password>

However, when I try to start the server as a foreground process, I get unexpected behavior. Whenever I deploy the server using start_foreground(), it starts fine, but the port resets to default 8080.

If I attach a debugger, and try to get values using environment.getProperty("server.port"), it will return empty string (however, if a property is not defined, it usually returns null). Moreover, all other properties return expected values:

environment.getProperty("spring.profiles.active")=dev-https

environment.getProperty("server.ssl.enabled")=true

etc.

I tried to replace eval with exec and even run ${cmd} by itself inside start_foreground() bash function, but the port always resets to 8080, and server.port returns empty string.

The weirdest part is that if I execute ${cmd} in my console (not from within the script), everything works flawlessly (right profile, and right port get used).

Has anyone encountered such weird problem?

like image 899
yeralin Avatar asked Jan 18 '18 15:01

yeralin


2 Answers

It looks like you are using the configuration(like port number etc... only for background and not used for foreground. You have not declared the variable (you missed this line)

`SPRING_OPTS="--spring.pid.file=${PID_FILE} ${SPRING_OPTS}"` 

for foreground.

like image 126
Kiran Kumar Avatar answered Nov 14 '22 02:11

Kiran Kumar


I tried to reproduce this problem with a new instance of Spring Boot. Wrote a quick bash script, and everything went fine!

Then, I started playing around with my original script, and found out that I was using SERVER_PORT variable (because I had an optional argument --port <num> for the user).

Apparently, this environment variable is also used by Spring Framework: https://www.concretepage.com/spring-boot/spring-boot-change-default-server-port#server_port

My mistake was exporting SERVER_PORT var (however, I needed it for other reasons).

Solution would be to either remove export from export SERVER_PORT="" or rename variable to something else (which I ended up doing).

like image 1
yeralin Avatar answered Nov 14 '22 02:11

yeralin