Traefik 2.2 Gateway timeout issue - spring-boot

I have been trying to setup traefik v2.2 using the basic official guide. I have a spring boot service which I have containerized and is working properly.
Here's docker compose of my spring boot service :
version: "3"
services:
spring-boot-traefik-app:
image: spring-boot-traefik-example:latest
labels:
- "traefik.http.routers.spring-boot-traefik-app.rule=Host(`springboot.traefik.app`)"
and Here's my Traefik docker compose :
version: "3"
services:
reverse-proxy:
# The official v2 Traefik docker image
image: traefik:v2.2
# Enables the web UI and tells Traefik to listen to docker
command:
- "--api.insecure=true"
- "--providers.docker=true"
ports:
# The HTTP port
- "80:80"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
Now, I'm trying to do a curl request by :
curl -H Host:springboot.traefik.app http://127.0.0.1
As I'm just returning the service info on the context path "/", it should have returned me something. Service is working fine independently. But when I'm trying run behind the proxy it gives me Gateway Timeout error. I'm not sure if traefik is working properly. Am I missing something? The official guide uses whoami image which is what I'm trying to create with Spring boot. Also, traefik dashboard shows the details correctly.

Maybe you should define an entrypoint for your traefik configuration. You may not have a traefik.toml file (I prefer using this personally). Anyway, you should add the command --entryPoints.web.address=:80 for your traefik container and add the label traefik.http.routers.spring-boot-traefik-app.entrypoints=web in your springboot container. I hope it works !

Related

Testing a container against DynamoDB-Local

I wanted to test a container locally before pushing it to aws ecs.
I ran unit tests against a docker-compose stack including a dynamodb-local container using a Go (aws-sdk-go-v2) endpoint resolver with http://localhost:8000 as the url.
So I wanted to build and test container locally and realised I needed to attach it to the default network created by docker-compose. I struggled with this a bit so I build a stripped down trial. I created an endpoint resolver with a url of http://dynamo-local:8000 (named the container dynamo-local in d-c) and attached it to the default network within docker run.
Now that all works, I can perform the various table operations successfully, but one of the things that confuses me is that if I run aws cli:
aws --endpoint-url=http://localhost:8000 dynamodb list-tables
then the output shows no tables exist when there is definitely a table existing. I had assumed, naively, that as I can access port 8000 of the same container with different endpoints I should be able to access the same resources. Wrong.
Obviously a gap in my education. What am I missing ? I need to expand the trial to a proper test of the full app, so its important to me that I understand what is going on here.
Is there a way I can use the aws cli to access the table?
docker-compose file :
version: '3.5'
services:
localstack:
image: localstack/localstack:latest
container_name: localstack_test
ports:
- '4566:4566'
environment:
- SERVICES=s3,sns,sqs, lambda
- DEBUG=1
- DATA_DIR=
volumes:
- './.AWSServices:/tmp/AWSServices'
- '/var/run/docker.sock:/var/run/docker.sock'
nginx:
build:
context: .
dockerfile: Dockerfile
image: chanonry/urlfiles-nginx:latest
container_name: nginx
ports:
- '8080:80'
dynamodb:
image: amazon/dynamodb-local:1.13.6
container_name: dynamo-local
ports:
- '8000:8000'
networks:
default:
name: test-net

Can't connect to Spring Boot app running on Docker locally

I stuck with the problem that can't open my REST Spring Boot app on localhost:8091 in browser.
Here is my docker-compose.xml (everything is deployed locally on Docker Desktop):
version: '3.3'
services:
postgres:
build:
context: services/postgres
dockerfile: Dockerfile.development
command: postgres
ports:
- "5432:5432"
environment:
- POSTGRESS_USER=postgres
- POSTGRESS_DB=postgres
- POSTGRESS_PASSWORD=qqq
- POSTGRES_HOST_AUTH_METHOD=trust
volumes:
- "db-data:/var/lib/postgresql/data"
app:
build:
context: services/app
dockerfile: Dockerfile.development
command: java -jar ./app.jar
environment:
- PORT=8091
network_mode: host
image: 'my-java-app'
ports:
- 8091:8091
depends_on:
- postgres
angular:
build:
context: services/angularfrontend
dockerfile: Dockerfile.development
image: 'my-angular-app'
ports:
- 80:80
volumes:
db-data:
Spring Boot App starts normally on 8091 and connects to the database, but then I can't make calls to it's API from my local machine ("connection refused").
Angular app opens normally (on localhost:80), but can't make calls to localhost:8091 Spring Boot app.
The call from angular service container to localhost:8091 fails, right?
Try to override in your angular frontend container the call to the backend
use app:8091 (this is how the backend service is called) instead of localhost:8091.
In the 'angular' container localhost doesn't translate to 'app' container.
You can't get from a container into a different container using localhost.
localhost inside a container will translate to the ip of that container.
Try to make in your angular application the call to the backend configurable, after that override that configuration in docker-compose using environment.
Also do that for the springboot app application.
I don't see in the environment that you override the call to the postgress.
Expose that configuration in application.properties and override in docker-compose, after that remove network_mode: host
If you really want to use network_mode: host, you don't need to specify <source>:<dest> because the app is listening on 8091 directly on the host network:
...
app:
build:
context: services/app
dockerfile: Dockerfile.development
command: java -jar ./app.jar
environment:
- PORT=8091
network_mode: host
image: 'my-java-app'
depends_on:
- postgres
...
If you want to run the java app like the other containers, simply remove this line from the compose file and the network mode will default to bridge:
network_mode: host

Make a request to a spring api running in a docker container from windows host

So, I searched around for an answer on this matter but either people don't address the issue or they say there's no problem doing this on their computer (mac or linux). It seems like this might be a windows problem.
I have a spring api running on a docker container (linux container). I use docker desktop on windows and I'm trying to make a request (in insomnia/postman/wtv) to that api.
If I run the api locally making the following request works perfectly:
http://localhost:8080/api/task/
This will list multiples task elements.
I've containerized this application like so:
Dockerfile
FROM openjdk:11.0.7
COPY ./target/spring-api-0.0.1-SNAPSHOT.jar /usr/app/
WORKDIR /usr/app
RUN sh -c 'touch spring-api-0.0.1-SNAPSHOT.jar'
ENTRYPOINT ["java", "-jar", "spring-api-0.0.1-SNAPSHOT.jar"]
docker-compose.yml
version: '3.8'
services:
api:
build: .
depends_on:
- mysql
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/test?createDatabaseIfNotExist=true
ports:
- "8080:80"
mysql:
image: mysql
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_USER=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=test
If I do docker-compose up this works without issue:
The problem is, if I try to call the same endpoint as before from localhost I don't get any response.
Insomnia returns an error saying: Error: Server returned nothing (no headers, no data)
I've also tried connecting to the container's ip (got it from docker inspect) but no luck.
Ports are exposed in docker-compose.yml. What am I missing?
Thanks in advance.
Port mapping is incorrect.Spring boot application started at 8080 (from the image I see) inside container and it should be mapped to 8080 inside the container.
It should be like below:
ports:
- "8080:8080"

Docker image with Spring boot fails to connect to CloudSQL

I want to create web services with Spring boot, add it to docker image, connect to cloud sql and then run on Compute Engine.
I am using docker compose to combine the image for project and cloud sql proxy image. However, no matter what jdbc URL I give it fails to connect. Right now, I am trying all of this locally
I have tried following URLs:
1. spring.datasource.url=jdbc:mysql:///cloudsql/myinstancename/${MYSQL_DATABASE}
2. spring.datasource.url=jdbc:mysql://cloudsql/myinstancename/${MYSQL_DATABASE}
3. spring.datasource.url=jdbc:mysql://127.0.0.1:3306/${MYSQL_DATABASE}
docker-compose.yml
version: '3'
services:
app:
image: appname
volumes:
- cloudsql:/cloudsql
depends_on:
- sql_proxy
ports:
- 8080:8080
# SQL proxy is built correctly, says
# Listening on /cloudsql/myinstancename for myinstancename
# sql_proxy_1 | Ready for new connections
sql_proxy:
environment:
- MYSQL_ROOT_PASSWORD=password!#
- MYSQL_DATABASE=appname
- MYSQL_USER=root
image: gcr.io/cloudsql-docker/gce-proxy:1.12
command:
/cloud_sql_proxy
-dir=/cloudsql
-instances=myinstancename # (I have added this correctly)
-credential_file=/root/keys/keyfile.json
volumes:
- E:\mykey.json:/root/keys/keyfile.json:ro
- cloudsql:/cloudsql
ports:
- 3306:3306
volumes:
# This empty property initializes a named volume.
cloudsql:
application.properties:
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql:///cloudsql/myinstancename/${MYSQL_DATABASE}
spring.datasource.username=${MYSQL_USER}
spring.datasource.password=${MYSQL_ROOT_PASSWORD}
spring.security.enabled=false
security.ignored=/**
Currently, you are using the Cloud SQL proxy in a sidecar pattern that is mounting a unix socket in /cloudsql/<INSTANCE_CONNECTION_NAME> that can be used to connect to your Cloud SQL instance. Unfortunately, most Java JDBC drivers don't support unix sockets. You can switch the Cloud SQL Proxy to provide a tcp socket instead with something like the following: "-instances=<INSTANCE_CONNECTION_NAME>=tcp:3306".
Alternatively, you can use the Cloud SQL JDBC Socket Factory. This is a Java library that allows you to create authenticated connections to a Cloud SQL instance, but doesn't require using the proxy.

Docker-compose links container but Application throws "no route found"

I have a web application with database and rabbitMQ services. I am using docker-compose to build and run images.
rabbitmq:
image : rabbitmq:3-management
container_name: rabbitmq
hostname: rabbitmq
ports:
- "15672:15672"
expose:
- "5672"
- "4369"
- "25672"
coredb:
container_name: coredb
build: ./mongodb/
core:
container_name: core
build: ./core/
ports:
- "80:8080"
- "5683/udp:5683/udp"
- "5684/udp:5684/udp"
links:
- rabbitmq
- coredb
After running
docker-compose up
All the services get started properly. I can ping rabbitmq and codedb from core's shell. In the SpringBoot application code, I am using
CachingConnectionFactory(hostname)
to connect to rabbitMQ. The hostname i am giving is "rabbitmq". In the logs during event publishing, the error I see is "No route found". Core service can connect to database properly but cannot connect to rabbitMQ.
You can use docker inspect <container name> to inspect the config of the "core" service to make sure the link was setup. You can also check the hostname using docker exec -ti <container name> cat /etc/hosts (which I think you did already).
If it looks like it's properly linked up, the issue is probably that the core service is trying to connect to it before the rabbitmq service has actually started.
You can have the "core" service retry a few times (with a short delay) to try and setup the conenction.

Resources