Docker: Start Tomcat after running Oracle and scripts executed - java

I am really new to Docker and enjoy it, however, I found some problems with running my application. I want to run my application which consists of 2 services:
I would like to start Oracle and run some DDL and DATA scripts which should take above 30 seconds
I would like to start Tomcat and launch my war file after the first step is finished as it won't start without it.
I've already read about: docker-wait and this is not what am i exactly waiting for as I should execute some scripts after my db would be available on specified port.
As I understand, the right way to start multiservises application is to use docker compose.
Here is my docker-compose.yml for now:
version: '2'
services:
web:
build: Server
ports:
- "8080:8080"
depends_on:
- oracle
oracle:
build: Oracle
ports:
- "1521:1521"
depends_on just lets me to order start of apps and nothing more.
For both Tomcat and Oracle I am using most popular images from Docker Hub.
How could I get the right way to start Tomcat after Oracle has started and scripts are executed?

depends_on only checks that the container is running, not that the service inside it is ready to accept requests. What you want is for your web service to start only when your oracle service is ready. You can use a script like wait-for-it to do this. Eg:
version: '2'
services:
web:
build: Server
ports:
- "8080:8080"
depends_on:
- oracle
command: wait-for-it.sh oracle:1521 --timeout=8 -s -q -- myservercmd
oracle:
build: Oracle
ports:
- "1521:1521"

Related

HTTP Status 404 - Not Found in pages when deploying war of Spring application in dockerized payara

I am trying to deploy a spring web application (*.war packaging) in a payara docker container. When I run the app localy in payara, the url http://localhost/my_application/test works fine but when I deploy my app on dockerized payara I get HTTP Status 404 - Not Found. In payara administration panel I can see that the app has been deployed and when I run asadmin list-applications in cli I can see that the app has benn deployed. I cannot find any logical explaination why this could happen. My Dockerfile is
FROM payara/server-full:5.2022.2-jdk11
USER root
ENV http_proxy ${my_hhtp_proxy}
ENV https_proxy ${my_https_proxy}
RUN apt update
RUN apt install -y openjdk-17-jdk
RUN update-java-alternatives -s /usr/lib/jvm/java-1.17.0-openjdk-amd64
COPY .docker/payara/lib $PAYARA_DIR/glassfish/domains/domain1/lib
and my docker-compose.yml is
version: "3.8"
services:
springApp:
build:
context: .
dockerfile: Dockerfile
container_name: springApp
volumes:
- "./target:/opt/payara/deployments"
ports:
- "4848:4848"
- "8080:8080"
- "8181:8181"
Updated
I can see in the administration panel that when I run the application on docker dispatcherServlet and messageDispatcherServlet are not loaded but when I run the app locally the servlets are loaded. Here is a screenshot of the admin panel. on the left is the local and on the right is the docker administration panel
There is nothing wrong with your files. It is a confirmed bug. Payara's team is working to determine the root causes and provide a solution. You may stay up to date (or participate) by following the relevant thread of their GitHub repository.

Run selenium tests in docker container from JAR file

I currently have a docker-compose file with 3 services:
selenium-hub
chrome-node
a container containing my selenium JUnit tests.
I want to selenium-test (w/ JUnit) my JAR file (containing these tests) with a command in the container's Dockerfile. I thought about using the selenium-server.jar but I can't seem to figure out what the exec command should be (in the Dockerfile).
Anyone can help me out?
My docker-compose.yml:
version: "3"
services:
chrome:
image: selenium/node-chrome:4.1.4-20220427
shm_size: 2gb
container_name: chrome
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
selenium-hub:
image: selenium/hub:4.1.4-20220427
container_name: selenium-hub
ports:
- "4442:4442"
- "4443:4443"
- "4444:4444"
application:
build: .
container_name: application
ports:
- "4447:4447"
depends_on:
- chrome
And my Dockerfile:
#
# Build stage
#
FROM maven:3.6.0-jdk-11-slim AS build
COPY src .
COPY pom.xml .
RUN mvn -f pom.xml jar:test-jar
#
# Package stage
#
FROM openjdk:11-jre-slim
COPY --from=build target/playground-project-selenium-1.0-SNAPSHOT-tests.jar /usr/local/lib/demo.jar
ADD selenium-server.jar .
ENTRYPOINT exec java -jar selenium-server.jar --ext /usr/local/lib/demo.jar:selenium/node-chrome standalone --port 4447
EXPOSE 4447
After some sessions of trial-and-error, I've managed to answer my own question. I created a so-called Fat-JAR (using the maven assembly plugin) containing all tests, resources and dependencies and I used JUnit 4 with the org.junit.runner.JUnitCore class to run a test suite.
Now, my selenium UI tests are fully running in a Docker container using selenium hub and chrome driver in separate containers.

Docker files to docker compose

Im new at docker. I am making a java sockets music server and i have 2 files. Client.java and Server.java. Both are in separate containers. To mention, i run both services in command line
Docker files
FROM java:8
COPY Server.java /
RUN javac Server.java
EXPOSE 25000
ENTRYPOINT ["java"]
CMD ["Server"]
FROM java:8
COPY Client.java /
RUN javac Client.java
EXPOSE 25000
ENTRYPOINT ["java"]
CMD ["Client"]
i create also a network for these two to communicate.
docker network create client_server_network
and i run the images as follows:
docker run --env SERVER_HOST_ENV=server --network-alias server --network client_server_network -it server
docker run --network client_server_network -it clientimage
Now i want to create a docker compose file with those two Dockerfiles and the network. This is what i have done so far:
version:'3'
services:
client:
image: java:8
ports:
-25000:25000
network:
default:
name: client_server_network
server:
image: java:8
ports:
-25000:25000
environment:
-SERVER_HOST_ENV=server
network:
My question is how to add the common network in both services. Also is the way i write my docker compose file correct?
Below is the code, by default both container is added to network named net and it must provide in the last line also
version:'3'
services:
client:
image: java:8
ports:
- 25000:25000
networks:
- client_server_network
server:
image: java:8
ports:
- 25000:25000
environment:
- "SERVER_HOST_ENV=server"
networks:
- client_server_network
networks:
client_server_network:
Note that the network should be specified commonly at last in the same level of services and version. As indenting is a main factor in docker-compose. if it is incorrectly indent may shows error.
Delete all of the networks: blocks in the entire file. client and server will be usable as host names by these two containers.
This behavior is described further in Networking in Compose in the Docker documentation. If you don't declare top-level networks:, Compose creates a network called default, and if you don't declare networks: on a given service, Compose attaches it to that default network.
A functional translation of your two docker run commands would look like:
version: '3.8'
# Compose creates `networks: { default: }` on its own; you do not need
# top-level `networks:`
services:
server: # <-- this name is usable as a host name
image: server
environment:
- SERVER_HOST_ENV=server
# Automatically on `networks: [default]`
client:
image: clientimage

Make image by docker compose to start automatically Spring Boot and Cassandra

I'm trying to create docker image by docker-compose. How I can do that?
I can start my project (spring boot + cassandra) by docker-compose up. And everything works great. But in next step I want to make from this project image, push to docker hub and pull it from docker hub to test on other computer. Im tried 'docker-compose build', 'docker-compose push' and then 'docker-compose pull'. After pull I can see information that cassandra and spring-boot-app is downloaded. But then, when I want to run this image by 'docker run' but it runs only springboot, without cassandra.
This is my docker-compose.yaml file:
version: '3'
services:
cassandra:
build:
context: ../
dockerfile: docker/cassandra/Dockerfile
ports:
- "9042:9042"
container_name: cassandra
spring-boot-cassandra:
build:
context: ../
dockerfile: docker/springbootsample/Dockerfile
links:
- cassandra
ports:
- "8080:8080"
environment:
SPRING_DATA_CASSANDRA_CONTACT_POINTS: cassandra
container_name: springboot
entrypoint: /wait-for-it.sh cassandra:9042 -- java -Djava.security.egd=file:/dev/./urandom -jar app.jar
depends_on:
- "cassandra"
image: myrepo/springbootsample
networks:
default:
driver: bridge
docker-compose is used to handle multiple images. I guess you are thinking it will merge two images into one, which will not happen.
docker run is used to run only one image at a time, this was the limitation because of that docker-compose was introduced.
docker-compose up does docker run, docker network create/add etc. commands to create you an environment. For use,
docker-compose build will build all your images present in the docker-compose.yml file.
docker-compose push will push all your images to the hub.
docker-compose pull will download those images from the hub if present.
and finally, if you want to run those images, use docker-compose up. If the images are not present it will download those images first from the hub.

Docker-Compose - Control docker-compose execution order

I need to control the order of Docker containers instantiation, the problem is that I want to build a Jar file with the Docker maven container then pass that jar to an OpenJDK Docker container in order to build an image and then instantiate a MongoDB container and a Java-App container with the OpenJDK image generated before that communicates between them via docker-compose.
The problem is the Build always fails because some of the Unit tests talk to the database before it's initialized and since the tests fail the build also fails.
This is my dockerfile:
FROM maven:3.5-alpine
COPY ./ /app
RUN cd /app && mvn package
FROM openjdk:8
COPY spring-rest-iw-exam.jar /tmp/spring-rest-iw-exam.jar
EXPOSE 8087
ENTRYPOINT ["java", "-jar", "/tmp/spring-rest-iw-exam.jar"]
This is my Docker-Compose:
version: '2'
services:
mongodb:
image: mongo
container_name: iw_exam_mongo
restart: always
ports:
- "27017:27017"
environment:
- MONGO_INITDB_DATABASE=fizz_buzz_collection
volumes:
- /opt/iw-exam/data:/data/db
spring-app:
container_name: iw_exam_java_rest_api
build: ./
restart: always
ports:
- "8087:8087"
depends_on:
- mongodb
I tried with depends_on and did some other tests with a tool call dockerize but none of it works, the maven build always starts before docker-compose even start to instantiate mongodb.
This is the github repository of the proyect:
https://github.com/dsalasboscan/exam
I need to instantiate Mongodb first and THEN start with the maven build and java image generation.
I came across similar problem before, and would like to share my experience.
Basically, we need to wait for a while to make sure mongodb is completely boot up, here is the tool that you can leverage. It's fairly easy to use.

Categories