How to deploy Spring Boot RESTful Web Service Docker img to EC2? - spring

What I'm trying to do is simple, deploy a Spring Boot RESTful Web Service to EC2 so it's accessible publicly.
For this I need to do the following:
Write Spring Boot web service, containerize and test locally - done
Here is my Dockerfile:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
When I docker run this locally on 8080 it works fine (returns static json).
Push to Dockerhub - done
Launch an Amazon Linux AMI on aws and make it http accessible (port 80) - done
Install apache (httpd) and start - done
Here is where I need some help
I run docker image from dockerhub like so
docker run --rm -p 80:8080 kaspartr/demo
It doesn't allow cause of course the port is taken by apache. And if I stop it and run it is deployed but I cannot access it online.
Can someone please explain how do you deploy docker image into the apache?
Do I need to change the Dockerfile or something else?
Thank you!!

Typically I run application on separate port and do docker forward:
Add yo you application.properties
server.port=9001
And add to docker-compose.yml:
version: '1'
services:
your-service:
build: .
ports:
- '9001:9001'
environment:
SERVICE_URL: http://service:9001/path

Since Apache has already taken port 80, you cannot make your container runs on port 80 too.
My guess is that you are planning to use Apache as a reverse proxy to your container. Try publishing your container to another port, and proxying port 80 to the container using Apache.

Related

How to network 2 separate docker containers to communicate with eachother?

I'm pretty new to docker, and I've tried searching about networking but haven't found a solution that's worked.
I have a Laravel app that is using Laradock.
I also have an external 3rd party API that runs in its own docker container.
I basically want to specify the container name of the api inside my laravel .env file, and have it dynamically resolve the container ip so I can make API calls from my Laravel app. I can already do this with services that are already part of laradock like mariadb/mysql, but since my API is located in an external container, it can't connect to it.
I tried making a network and attaching them with;
docker network create my-network
Then inside my docker-compose.yml files for each of the containers, I specified;
networks:
my-network:
name: "my-network"
But if I try and ping them with;
docker exec -ti laradock-workspace-1 ping my-api
I can't connect and can't really figure out why. Was hoping someone familiar with docker might be able to explain why since I'm sure it's something very obvious I'm missing. Thanks!
By default Docker Compose uses a bridge network to provision inter-container communication. Read this article for more info about inter-container networking.
What matters for you, is that by default Docker Compose creates a hostname that equals the service name in the docker-compose.yml file.
Consider the following docker-compose.yml:
version: '3.9'
services:
server:
image: node:16.9.0
container_name: server
tty: true
stdin_open: true
depends_on:
- mongo
command: bash
mongo:
image: mongo
environment:
MONGO_INITDB_DATABASE: my-database
When you run docker-compose up, Docker will create a default network and assigns the service name as hostname for both mongo and server.
You can now access the backend container via:
docker exec -it server bash
And now you can ping the mongo container using Dockers internal network (default on port 27017 in this case):
curl -v http://mongo:27017/my-database
That's it. The same applies for your setup.

can't access to a spring boot API based in remote docker

I'm trying to get a connection to a Spring Boot application containerized in a old docker:
My docker version is 1.12.2
Spring Boot 2.5.1
here is my Dockerfile:
FROM openjdk:8-alpine
ADD manager.jar manager.jar
EXPOSE 8443
ENTRYPOINT ["java","-Dspring.profiles.active=dev","-jar","manager.jar"]
I've build the image inside docker with this simple command:
docker build -t manager .
and then run the container:
docker run -p 8443:8443 -t manager manager
But when I'm trying to have a connection by typing the adress:
https://SERVERNAME:8443
...timeout.
Did I make a mistake somewhere?
So like I said in my last post, after remove the TLS properties from the application.properties, everything is solved. It's a server configuration problem.

How to connect my spring boot app to redis container on docker?

I have created a spring app and i want to connect it to redis server which is deployed on docker-compose i put the needed properties as follow :
spring.redis.host=redis
spring.redis.port=6379
But i keep getting a ConnexionException so how can i Know on which host redis is running and how to connect to it.
Here is my docker-compose file :
version: '2'
services:
redis:
image: 'bitnami/redis:5.0'
environment:
# ALLOW_EMPTY_PASSWORD is recommended only for development.
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL
ports:
- '6379:6379'
volumes:
- 'redis_data:/bitnami/redis/data'
volumes:
redis_data:
driver: local
From docker compose documentation
By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name
If you want to access redis by container name ('redis' in this case), the Spring boot application has also be deployed as a docker compose service, but it doesn't appear in the docker-compose file that you've provided in the question, so please add it.
Alternatively If you're trying to run the spring boot application on host machine, use 'localhost' instead of 'redis' in order to access the redis container.
Another approach you can use is "docker network" , Below are the steps to follow :
Create a docker network for redis
docker network create redis-docker
Spin up redis container is redis-docker network.
docker run -d --net redis-docker --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
Inspect the redis-docker container
docker network inspect redis-docker
Copy the "IPv4Address" IP and paster in application.yml
Now build , start your application.

Dockerized Spring boot app connect to database docker image

I have a basic spring boot application with gradle which makes calls to an Oracle database and the database properties are specified in an application.properties file.
I created a Docker image of the spring boot application with the plugin "com.google.cloud.tools.jib" and using the following command:
./gradlew jibDockerBuild --image=app1
I have a docker-compose file in which i specify the image as an service and i want the application to start when i run the command: "docker-compose up"
The docker-compose file is the following:
version: '3'
services:
app1:
image: "app1"
ports:
- "8731:8731"
But when I hit the run the "docker-compose up" command in CMD I recieve the following exception:
java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection
More informations:
My Oracle database is a docker container with the name : "ORA12201_1" and port 3769
Inside the application.properties the database properties specified are correct since I am amble to start the application from IntelliJ
you can connect from IntelliJ without problem as the container exposes the port (3769) to the host (your PC), but now you are trying to connect from one Docker container to another.
The containers do not share the network (isolation) so you need to connect them.
One of the recommended approach is User-defined networks
Create first a network
docker network create --driver bridge my_network
Run the applications
docker run -p 5432:5432 --network my_network -d --name=postgres postgres
docker run -p 5050:80 --network my_network -d --name=pgadmin dpage/pgadmin4
You can verify they are effectively running on the same network with
docker network inspect my_network
Spring Boot config
You can now connect from one to another using host.docker.internal as hostname, for example in your Spring Boot application.properties
spring.datasource.url=jdbc:postgresql://host.docker.internal:5432/postgres

How to enable https on bluemix with docker-compose

I created a simple application consisting of nginx and python flask made up of two containers, which I can deploy to bluemix using docker-compose.
The docker compose file is docker-compose-bluemix.yml
flask:
image: registry.ng.bluemix.net/namespace/simple.flask
restart: always
expose:
- "8000"
command: /usr/local/bin/gunicorn -w 2 -b :8000 app:app
nginx:
image: registry.ng.bluemix.net/namespace/simple.nginx
restart: always
ports:
- "80:80"
links:
- flask:flask
Once I assign an ip to the nginx container it works, in that I can access it like so,
curl http://ip/flask-api/v0.01/hello
and the correct response is returned
{"status": "hello"}
How do I enable https for this app? Must it be done by providing the nginx container self signed certs, or can I leverage bluemix to give me a https://xxx.mybluemix.net address for the containers? If so, how?
If you want Bluemix to assign a route like https://xxx.mybluemix.net then you need to deploy a Scalable Group instead of a Single Container. Scalable Groups can be assigned routes which will allow SSL (https://) access.
I don't believe that you can do this with Docker Compose because Docker is not aware of the container group capabilities in Bluemix. You could use the IBM Container extensions to the Cloud Foundry CLI to do this from the command line or from your DevOps pipeline tool of choice with the following commands:
cf ic group create --name simple-flask -m 64 -p 8000 --min 1 --max 3 --desired 2 registry.ng.bluemix.net/namespace/simple-flask:latest
cf ic route map -n simple-flask -d mybluemix.net simple-flask
At that point you don't need nginx because Bluemix will put a load balancer in front of your container group for you to direct traffic to the containers within it. You can then get to it via:
https://simple-flask.mybluemix.net/flask-api/v0.01/hello
This should give you what you were looking for.
~jr

Resources