jib-maven spring boot profile
Asked Answered
D

3

4

In my springboot project, there are three configuration files

application.yml --> used in local development
application-test.yml --> running in a test environment
application-prod.yml --> running in a production environment

pom.xml

...

<properties>
    <docker-repository>self-ip:port</docker-repository>
</properties>

...

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>

        <plugin>
            <groupId>com.google.cloud.tools</groupId>
            <artifactId>jib-maven-plugin</artifactId>
            <version>1.7.0</version>
            <configuration>
                <allowInsecureRegistries>true</allowInsecureRegistries>
                <from>
                    <image>openjdk:8-jre-alpine</image>
                </from>
                <to>
                    <image>${docker-repository}/${project.groupId}/${project.artifactId}</image>
                </to>
                <container>
                    <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
                    <jvmFlags>
                        <jvmFlag>$JAVA_OPTS</jvmFlag>
                        <jvmFlag>-Dfile.encoding=UTF-8</jvmFlag>
                        <jvmFlag>-XX:+UseG1GC</jvmFlag>
                        <jvmFlag>-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/var/log/gc.log</jvmFlag>
                        <jvmFlag>-Djava.security.egd=file:/dev/./urandom</jvmFlag>
                    </jvmFlags>
                </container>
            </configuration>
        </plugin>
    </plugins>
</build>

And then push to my self private docker repository, It's OK

mvn -DsendCredentialsOverHttp=true jib:build

Running on different machines

# On my test machine, I want to run like this
docker run --name test-xxx -d \
    -p 8080:8080 -p 9080:9080 \
    -e JAVA_OPTS="-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" \
    -v ~/logs:/logs \
    self-ip:port/xxx/yyy

# on my production machine, I want to run like this
docker run --name prod-xxx -d \
    -p 8080:8080 \
    -e JAVA_OPTS="-server -Xms1G -Xmx1G -Dspring.profiles.active=prod" \
    -v /mnt/logs:/logs \
    self-ip:port/xxx/yyy

When I running on test machine, It's fail

docker container ls -al
CONTAINER ID    IMAGE   COMMAND                  CREATED         STATUS                     PORTS    NAMES
XXXXXXXXXXXX    xxx     "java $JAVA_OPTS -Df…"   3 seconds ago   Exited (1) 2 seconds ago            test-xxx

My expectation is this

# test machine
java -Xms256m -Xmx256m -Dspring.profiles.active=test \
    -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080 \
    -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc \
    -XX:+PrintGCDetails -XX:+PrintGCDateStamps \
    -XX:+PrintGCTimeStamps -Xloggc:/logs/gc.log \
    -Djava.security.egd=file:/dev/./urandom \
    -cp /app/resources:/app/classes:/app/libs/* \
    xxx.yyy.MainClass

# production machine
java -server -Xms1G -Xmx1G -Dspring.profiles.active=prod \
    -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc \
    -XX:+PrintGCDetails -XX:+PrintGCDateStamps \
    -XX:+PrintGCTimeStamps -Xloggc:/logs/gc.log \
    -Djava.security.egd=file:/dev/./urandom \
    -cp /app/resources:/app/classes:/app/libs/* \
    xxx.yyy.MainClass

How should I configure it? container --> environment or dockerClient --> environment?
I have not found any relevant examples in the documentation, They are all just a sentence


update 1

Hi @Haran I modified <jvmFlag>$JAVA_OPTS</jvmFlag> to JAVA_TOOL_OPTS and repush

and run on test

docker container rm test-xxx
docker run --name test-xxx -d \
    -p 8080:8080 \
    -e "JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" \
    ip:port/xx/yy

It's also running fail

$ docker container ls -al
CONTAINER ID    IMAGE   COMMAND                       CREATED         STATUS                     PORTS    NAMES
XXXXXXXXXXXX    xxx     "java $JAVA_TOOL_OPTS -Df…"   3 seconds ago   Exited (1) 2 seconds ago            test-xxx

and then I remove $JAVA_TOOL_OPTS and repeat the above repush and docker rm & run, running succesfull, but no customize enviroment

$ docker exec -it test-xxx ps auxf
PID   USER     TIME  COMMAND
    1 root      0:05 java -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc -XX:+P
   59 root      0:00 ps auxf


$ docker ps --no-trunc
CONTAINER ID    IMAGE  COMMAND                                                                                                                                                                                                                                              CREATED             STATUS              PORTS                    NAMES
xx              yy     "java -Dfile.encoding=UTF-8 -XX:+UseG1GC '-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/logs/gc.log' -Djava.security.egd=file:/dev/./urandom -cp /app/resources:/app/classes:/app/libs/* xx.yy.MainClass"   34 seconds ago      Up 34 seconds       0.0.0.0:8080->8080/tcp   test-xxx

update 2

The quotation mark for the docker -e ... command is no different between inside and outside.

$ docker run --name test-xxx -d -p 8080:8080 \
    -e JAVA_TOOL_OPTIONS="-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" \
    ip:port/xx/yy
xxxxx

$ docker exec -it test-xxx env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin
HOSTNAME=4a7c5045109b
TERM=xterm
JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080
JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk/jre
JAVA_VERSION=8u212
JAVA_ALPINE_VERSION=8.212.04-r0
LANG=C.UTF-8
HOME=/root


$ docker run --name test-xxx1 -d -p 8081:8080 \
    -e "JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" \
    ip:port/xx/yy
xxxx

$ docker exec -it test-xxx1 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin
HOSTNAME=ae333ad8836f
TERM=xterm
JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080
JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk/jre
JAVA_VERSION=8u212
JAVA_ALPINE_VERSION=8.212.04-r0
LANG=C.UTF-8
HOME=/root


$ docker ps --no-trunc         
CONTAINER ID    IMAGE           COMMAND                                                                                                                                                                                                                                               CREATED             STATUS              PORTS                    NAMES
xxx             ip:port/xx/yy   "java -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/var/log/gc.log -Djava.security.egd=file:/dev/./urandom -cp /app/resources:/app/classes:/app/libs/* xx.yy.MainClass"   3 minutes ago       Up 3 minutes        0.0.0.0:8081->8080/tcp   test-xxx1
xx              ip:port/xx/yy   "java -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/var/log/gc.log -Djava.security.egd=file:/dev/./urandom -cp /app/resources:/app/classes:/app/libs/* xx.yy.MainClass"   3 minutes ago       Up 3 minutes        0.0.0.0:8080->8080/tcp   test-xxx
Doralia answered 5/11, 2019 at 2:9 Comment(6)
Try JAVA_TOOL_OPTIONS, docker run -e "JAVA_TOOL_OPTIONS=<JVM flags>" <image name>. For more information refer: github.com/GoogleContainerTools/jib/blob/master/docs/faq.md Also, try passing the Env variable within quotes. something like: docker run -e "JAVA_OPTS=-server -Xms1G -Xmx1G -Dspring.profiles.active=prod" imagenameSepal
@Sepal Tried, there is still a problem, See my long reply below.Doralia
Could you try another thing: Keep the JAVA_TOOL_OPTIONS within quotes(") -e "JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080"Sepal
Oh, sorry, my fault... The command is docker run --name test-xxx -d -p 8080:8080 -p 9080:9080 -e "JAVA_TOOL_OPTIONS=-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" ip:port/xx/yy, java_tool_options is enclosed in double quotes, running succesfull, but no customize enviromentDoralia
Just set a docker environment variable named SPRING_PROFILES_ACTIVE, Spring Boot will pick that up. You don't need to pass it as a system variable. You can override all defined variables that way. I.e. SPRING_DATASOURCE_URL would be taken as value for spring.datasource.url etc.Katy
It's not just the global variables that spring will use. For example, I hope that the test environment will open a port for remote debugging and the memory is allocated low enough, while the production environment has more memory. Just relying on spring's runtime reading, this just moves one problem to another and doesn't really handle the problem.Doralia
C
1

For setting JVM parameters, simply set JAVA_TOOL_OPTIONS at runtime. Actually, I can see from your update that you already tried this.

$ docker run ... -e "JAVA_TOOL_OPTIONS=..."

Most JVMs will automatically pick up the JAVA_TOOL_OPTIONS environment variable, so you don't need to pass what's inside in JAVA_TOOL_OPTIONS as command-line arguments to the java binary. You can verify this behavior locally on your machine (either inside or outside a container):

$ JAVA_TOOL_OPTIONS=-Xmx256m java ABCD # no need to pass extra arguments
Picked up JAVA_TOOL_OPTIONS: -Xmx256m
Error: Could not find or load main class ABCD
$ docker run -e "JAVA_TOOL_OPTIONS=-Xmx256m" --entrypoint java openjdk:11 ABCD
Picked up JAVA_TOOL_OPTIONS: -Xmx256m
Error: Could not find or load main class ABCD
Caused by: java.lang.ClassNotFoundException: ABCD

So, just define JAVA_TOOL_OPTIONS at runtime (and you already did it with docker run -e), and don't define <jvmFlags> or modify <entrypoint>.

Lastly, it is JAVA_TOOL_OPTIONS, not JAVA_TOOL_OPTS.

Condorcet answered 5/11, 2019 at 15:57 Comment(1)
Thanks for reminding My own problem, several times when I read the docker logs test-xxx log information, I saw the message Picked up JAVA_TOOL_OPTIONS: ...(plus the -server option, Information: Unrecognized option: -server), then test the test command for a while and then test the production command. After a long time, the whole person is lost.Doralia
D
0

JAVA_TOOL_OPTIONS has valid, Now I just need to do this.

<properties>
    <docker-repository>self-ip:port</docker-repository>
</properties>

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>1.7.0</version>
    <configuration>
        <allowInsecureRegistries>true</allowInsecureRegistries>
        <from>
            <image>openjdk:8-jre-alpine</image>
        </from>
        <to>
            <image>${docker-repository}/${project.groupId}/${project.artifactId}</image>
        </to>
        <container>
            <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
            <jvmFlags>
                <!-- global java option -->
                <jvmFlag>-Dfile.encoding=UTF-8</jvmFlag>
                <jvmFlag>-XX:+UseG1GC</jvmFlag>
                <jvmFlag>-verbose:gc</jvmFlag>
                <jvmFlag>-XX:+PrintGCDetails</jvmFlag>
                <jvmFlag>-XX:+PrintGCDateStamps</jvmFlag>
                <jvmFlag>-XX:+PrintGCTimeStamps</jvmFlag>
                <jvmFlag>-Xloggc:/var/log/gc.log</jvmFlag>
                <jvmFlag>-Djava.security.egd=file:/dev/./urandom</jvmFlag>
            </jvmFlags>
        </container>
    </configuration>
</plugin>
# on test machine
docker run --name test-xxx -d \
    -p 8080:8080 -p 9080:9080 \
    -e JAVA_TOOL_OPTIONS="-Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080" \
    -v ~/logs:/var/log \
    self-ip:port/xxx/yyy

# on production machine
docker run --name prod-xxx -d \
    -p 8080:8080 \
    -e JAVA_TOOL_OPTIONS="-Xms1G -Xmx1G -Dspring.profiles.active=prod" \
    -v /mnt/logs:/var/log \
    self-ip:port/xxx/yyy

PS: Cann't add -client -server options using in JAVA_TOOL_OPTIONS: https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/envvars002.html

for test

$ docker top test-xxx         
UID     PID      PPID     C     STIME    TTY    TIME        CMD
root    32157    32138    15    11:05    ?      00:00:05    java -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/var/log/gc.log -Djava.security.egd=file:/dev/./urandom -cp /app/resources:/app/classes:/app/libs/* xx.yy.MainClass

$ docker logs test-xxx 
Picked up JAVA_TOOL_OPTIONS: -Xms256m -Xmx256m -Dspring.profiles.active=test -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9080
Listening for transport dt_socket at address: 9080

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (...)

for prod

$ docker top prod-xxx
UID     PID      PPID     C    STIME    TTY    TIME        CMD
root    13989    13970    8    11:09    ?      00:00:05    java -Dfile.encoding=UTF-8 -XX:+UseG1GC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/var/log/gc.log -Djava.security.egd=file:/dev/./urandom -cp /app/resources:/app/classes:/app/libs/* xx.yy.MainClass

$ docker logs prod-xxx           
Picked up JAVA_TOOL_OPTIONS: -Xms1G -Xmx1G -Dspring.profiles.active=prod

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (...)

only the parameters are not attached to the command line options, but they are valid.

Doralia answered 5/11, 2019 at 10:18 Comment(0)
E
0

Option 1: Java System Properties (VM Arguments)

It's important that the -D parameters are before your application.jar otherwise they are not recognized.

java -jar -Dspring.profiles.active=prod application.jar

Option 2: Program arguments

java -jar application.jar --spring.profiles.active=prod --spring.config.location=c:\config

When using jib as maven plugin - to change the loading of spring config file location : then entryPoint to be passed inside container, but seems jib plugin didn't pick that up . so below changes needs to be done in pom for the argument access for the location :

  <plugin>
        <groupId>com.google.cloud.tools</groupId>
        <artifactId>jib-maven-plugin</artifactId>
        <version>2.2.0</version>
        <configuration>
            <to>
                <image>image-url</image>
            </to>
            <container>
                <creationTime>${​​​​​​maven.build.timestamp}​​​​​​</creationTime>
                <mainClass>com.package.SpringBootMainClass</mainClass>
                <args>
                    <arg>--spring.config.location=/demo/location/application.yml</arg>
                </args>
            </container>
        </configuration>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>build</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
Enate answered 14/1, 2021 at 7:34 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.