Spring Boot in Docker - docker

I am learning how to use Docker with a Spring Boot app. I have run into a small snag and I hope someone can see the issue. My application relies heavily on #Value that are set in environment specific properties files. In my /src/main/resources I have three properties files
application.properties
application-local.properties
application-prod.properties
I normally start my app with:
java -jar -Dspring.profiles.active=local build/libs/finance-0.0.1-SNAPSHOT.jar
and that reads the "application-local.properties" and runs properly. However, I am using this src/main/docker/DockerFile:
FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD finance-0.0.1-SNAPSHOT.jar finance.jar
RUN sh -c 'touch /finance.jar'
EXPOSE 8081
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /finance.jar" ]
And then I start it as:
docker run -p 8081:80 username/reponame/finance
-Dspring.profiles.active=local
I get errors that my #Values are not found:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.driverClassName' in value "${spring.datasource.driverClassName}"
However, that value does exist in both *.local & *.prop properties files.
spring.datasource.driverClassName=org.postgresql.Driver
Do I need to do anything special for that to be picked up?
UPDATE:
Based upon feedback from M. Deinum I changing my startup to be:
docker run -p 8081:80 username/reponame/finance
-eSPRING_PROFILES_ACTIVE=local
but that didn't work UNTIL I realized order matter, so now running:
docker run -e"SPRING_PROFILES_ACTIVE=test" -p 8081:80 username/reponame/finance
works just fine.

You can use docker run Using Spring Profiles. Running your freshly minted Docker image with Spring profiles is as easy as passing an environment variable to the Docker run command
$ docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t springio/gs-spring-boot-docker
You can also debug the application in a Docker container. To debug the application JPDA Transport can can be used. So we’ll treat the container like a remote server. To enable this feature pass a java agent settings in JAVA_OPTS variable and map agent’s port to localhost during a container run.
$ docker run -e "JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n" -p 8080:8080 -p 5005:5005 -t springio/gs-spring-boot-docker
Resource Link:
Spring Boot with Docker
Using spring profile with docker for nightly and dev build:
Simply set the environment varialbe SPRING_PROFILES_ACTIVE when starting the container. This will switch the active of the Spring Application.
The following two lines will start the latest Planets dev build on port 8081 and the nightly build on port 8080.
docker run -d -p 8080:8080 -e \"SPRING_PROFILES_ACTIVE=nightly\" --name nightly-planets-server planets/server:nightly
docker run -d -p 8081:8080 -e \"SPRING_PROFILES_ACTIVE=dev\" --name dev-planets-server planets/server:latest
This can be done automatically from a CI system. The dev server contains the latest build and nightly will be deployed once a day...

There are 3 different ways to do this, as explained here
Passing Spring Profile in Dockerfile
Passing Spring Profile in Docker
run command
Passing Spring Profile in DockerCompose
Below an example for a spring boot project dockerfile
<pre>FROM java:8
ADD target/my-api.jar rest-api.jar
RUN bash -c 'touch /pegasus.jar'
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=dev","-jar","/rest-api.jar"]
</pre>
You can use the docker run command
docker run -d -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=dev" --name rest-api dockerImage:latest
If you intend to use the docker compose you can use something like this
version: "3"
services:
rest-api:
image: rest-api:0.0.1
ports:
- "8080:8080"
environment:
- "SPRING_PROFILES_ACTIVE=dev"
More description and examples can be found here

Related

How to properly expose/publish ports for a WebUI-based application in Docker?

I'm trying to port this webapp to Docker. I wrote the following Dockerfile:
FROM anapsix/alpine-java
MAINTAINER <name>
COPY aard2-web-0.7-java6.jar /home/aard2-web-0.7-java6.jar
COPY start.sh /home/start.sh
CMD ["bash", "/home/start.sh"]
EXPOSE 8013/tcp
Here are the contents of start.sh:
#!/bin/bash
java -Dslobber.browse=true -jar /home/aard2-web-0.7-java6.jar /home/dicts/*.slob
Then I built the image:
docker build -t aard2-docker .
And I used the following command to run the container:
docker run --name Aard2 -p 127.0.0.1:8013:8013 -v /home/<name>/dicts:/home/dicts aard2-docker
The app is running normally, prompting that it's listening at http://127.0.0.1:8013. However, I opened the address only to find that I couldn't connect to the app.
I tried using the EXPOSE command (as shown in the Dockerfile snippet above) and variants of the -p flag, such as -p 127.0.0.1:8013:8013, -p 8013:8013, -p 8013:8013/tcp, but none of them worked.
How can I expose/publish the port to 127.0.0.1 properly? Thanks!
Here's the response from the original author:
you need to tell the server to listen on all network interfaces instead of localhost - that is you are missing -Dslobber.host=0.0.0.0
this works for me:
FROM anapsix/alpine-java
COPY ./build/libs/aard2-web-0.7.jar /home/aard2-web-0.7.jar
CMD ["bash", "-c", "java -Dslobber.host=0.0.0.0 -jar /home/aard2-web-0.7.jar /dicts/*.slob"]
EXPOSE 8013/tcp
and then run like this:
docker run -v $HOME/Downloads:/dicts -p 8013:8013 --rm aard2-web
-Dslobber.browse=true opens default browser, I don't think this has any effect in docker so don't need that.
https://github.com/itkach/aard2-web/issues/12#issuecomment-895557949

Wildfly in domain mode not deploy my war file

Here is my Dockerfile, it won’t deploy in domain mode, after entering to wildfly web GUI, on deployment does not show my war file, but when I upload manually and deploy it work without any problem.
Dockerfile:
FROM jboss/wildfly
ADD your-awesome-app.war /opt/jboss/wildfly/domain/deployments/
docker run -it jboss/wildfly /opt/jboss/wildfly/bin/domain.sh -b 0.0.0.0 -bmanagement 0.0.0.0
Build and Run:
docker build --tag=jboss/wildfly .
Run it:
docker run -it -p 9990:9990 -p 8080:8080 jboss/wildfly
Any idea? Thanks.
The deployment scanner does not work in domain mode. You'd have to deploy using CLI or some other means of management.

Unable to connect to Rabbit MQ instance when running from docker container built by dockerfile

We are attempting to put an instance of rabbit mq into our Kubernetes environment. To do so, we have to implement it into our build and release process, which includes creating a docker container by Dockerfile.
During our original testing, we created the docker container manually with the following commands, and it worked correctly:
docker pull rabbitmq
docker run -p 5672:5672 -d --hostname my-rabbit --name some-rabbit rabbitmq:3
docker start some-rabbit
To create our docker file, we have tried various iterations, with the latest being:
FROM rabbitmq:3 AS rabbitmq
RUN rabbitmq-server -p 5672:5672 -d --hostname my-rabbit --name some-rabbit
EXPOSE 5672
We have also tried it with just the Run rabbitmq-server and not the additional parameters.
This does create a rabbit mq instance that we are able to ssh into and verify it is running, but when we try to connect to it, we receive an error: "ExtendedSocketException: An attempt was made to access a socket in a way forbidden by its access permission" (we are using rabbit's default of 5672).
I'm not sure what the differences could be between what we've done in the command line and what has been done in the Dockerfile.
Looks like you need to expose quite a few other ports.
I was able to generate the Dockerfile commands for rabbitmq:latest (rabbitmq:3 looks the same) using this:
ENV PATH=/usr/lib/rabbitmq/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV GOSU_VERSION=1.10
ENV RABBITMQ_LOGS=-
ENV RABBITMQ_SASL_LOGS=-
ENV RABBITMQ_GPG_KEY=0A9AF2115F4687BD29803A206B73A36E6026DFCA
ENV RABBITMQ_VERSION=3.7.8
ENV RABBITMQ_GITHUB_TAG=v3.7.8
ENV RABBITMQ_DEBIAN_VERSION=3.7.8-1
ENV LANG=C.UTF-8
ENV HOME=/var/lib/rabbitmq
EXPOSE 25672/tcp
EXPOSE 4369/tcp
EXPOSE 5671/tcp
EXPOSE 5672/tcp
VOLUME /var/lib/rabbitmq
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["rabbitmq-server"]
Dockerfile is used to build your own image, not to run a container. The question is - why do you need to build your own rabbitmq image? If you don't - then just use the official rabbitmq image (as you originally did).
I'm sure it already has all the necessary EXPOSE directives built-in
Also note command line arguments "-p 5672:5672 -d --hostname my-rabbit --name some-rabbit rabbitmq:3" are passed to docker daemon, not to the rabbitmq process.
If you want to make sure you're forwarding all the necessary ports - just run it with -P.

JHipster docker image from DockerHub is not working

I am trying to run the JHipster in docker container and followed the steps mentioned in https://jhipster.github.io/installation/.
> docker pull jhipster/jhipster
> mkdir ~/jhipster
> docker run --name jhipster -v ~/jhipster:/home/jhipster/app -v ~/.m2:/home/jhipster/.m2 -p 8080:8080 -p 9000:9000 -p 3001:3001 -i -t jhipster/jhipster
As I am running it in interactive mode it showing the JHIPSTER ASCII art and shows :: JHipster :: Running Spring Boot :: :: http://jhipster.github.io ::. Thats it.
When I docker ps:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f0015bd63658 jhipster/jhipster "tail -f /home/jhipst" 2 minutes ago Up 2 minutes 0.0.0.0:3001->3001/tcp, 0.0.0.0:8080->8080/tcp, 0.0.0.0:9000->9000/tcp jhipster
Now when I try to access localhost:8080 I am getting This page isn't working ERR_EMPTY_RESPONSE.
I checked in my ~/jhipster folder, there is nothing.
I logged into container with docker exec -it jhipster bash, there is nothing in app folder.
OS: MacOS
Docker Version: Docker version 1.12.5, build 7392c3b
docker-compose version 1.9.0, build 2585387
What am I missing?
When using the JHipster Docker image, all of the software requirements are installed but you still need to run the generator and choose your options.
Following along the installation documentation, you should log into the container, change to the app folder, and run jhipster:
docker container exec -it jhipster bash
cd /home/jhipster/app
jhipster
Once your application is created, you can run all the normal webpack/gulp and maven commands. For example, the following commands will start your backend and your frontend (run in separate terminals).
./mvnw
yarn start

Spring boot app runs fine standalone, errs in docker

I have a spring-boot based java application which runs fine from the command line (embedded tomcat standalone).
Problem
When I run the app in docker, it does not run correctly. The console shows the application starts up fine with no errors; however, the browser displays the following error page:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing
this as a fallback.
[I understand the message says no mapping for '/error' url. However I want to know the root cause ]
Additional Info/Context
Spring boot 1.4.2
docker plugin
Output is 'war' file which also runs standalone
I run docker image in 'host' networking mode (--net=host) so it can access the database (mysql running on my localhost)
build.gradle target
task buildDocker(type: Docker, dependsOn: build) {
push = false
applicationName = jar.baseName
dockerfile = file('src/main/docker/Dockerfile')
doFirst {
copy {
from war
into stageDir
}
}
}
dockerfile
FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD floss.war app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
Command to Run Docker
dockerImg=1248c47d9cfa
docker run \
-it \
--net=host \
-e SPRING_APPLICATION_JSON="$SPRING_APPLICATION_JSON" \
$dockerImg
I'm new to docker and would appreciate any suggestions.
thanks in advance!
Problems:
No exposed port in dockerfile
No port mapping with host.
Sol:
1. expose application port in dockerfile and build image
EXPOSE $application_port
2. then run
docker run -p 8080:8080 -d -e SPRING_APPLICATION_JSON="$SPRING_APPLICATION_JSON" $dockerImg
I had the same issue. You seem to be using the same Docker example for Spring Boot as I was. As you can see, the WAR file gets a .jar extension when it is placed into the Docker image, not .war.
I was able to solve the issue by calling the file "app.war" instead of "app.jar" and changing the Java startup parameters accordingly.
If you use the extension ".jar", the access to static resources works fine, but accessing all dynamic content (JSPs, ...) leads to a 404 error.
i suspect it is due to the missing -p option, can you try this. change the port if it is different.
docker run -p 8080:8080
-it \
--net=host \
-e SPRING_APPLICATION_JSON="$SPRING_APPLICATION_JSON" \
$dockerImg

Resources