I have 3 containers and the main container - con_a - should make requests to others. When con_a makes an HTTP request, the other container's response is "502 Timeout". The details of containers and requests are below. When I try to make a request with curl in the console, there is no problem and the request is working.
Docker-compose.yml
version: "3"
services:
con_a:
networks:
- my_net
con_b:
container_name: con_b
hostname: con_b
ports:
- "9200:9200"
- "9300:9300"
networks:
- my_net
con_c:
container_name: con_c
image: con_c
hostname: con_c
build: ./con_c
ports:
- "1337:1337"
networks:
- my_net
networks:
my_net:
driver: bridge
The request in the con_a
response = requests.get("http://con_c:1337/health_check")
The request is normally just return "success".
The response
'<HEAD><TITLE>Connection timed out</TITLE></HEAD>\n<BODY BGCOLOR="white" FGCOLOR="black"><H1>Connection timed out</H1><HR>\n<FONT FACE="Helvetica,Arial"><B>\nDescription: Connection timed out</B></FONT>\n<HR>\n<!-- default "Connection timed out" response (502) -->\n</BODY>\n'
Python request problem
I thought the problem is about the docker networking problem, but the problem was python's automation. The request contains more settings than my settings and before the get request, I add a trust environment settings like the other post. I found the solution in this post: python request problem
Related
I have my app (REST Service) connecting to Keycloak for Auth purposes, and both of them are started using the same docker compose file (default Network). Keycloak and App come up and work absolutely fine when API is invoked.
When the application is left unused for some time and again same API is invoked I get the below error.
iam | {"timestamp":"2022-11-18T12:25:47.055+0000","message":"fail to generate token","logger_name":"com.xxxxx.xxx.xxxxxxxxxxx.AuthController","thread_name":"http-nio-8081-exec-9","level":"ERROR","level_value":40000,"stack_trace":"javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: org.apache.http.conn.HttpHostConnectException: Connect to host.docker.internal:8085 [host.docker.internal/192.168.65.2] failed: Operation timed out (Connection timed out)\n\tat org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:341)\n\tat org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:464)\n\tat org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invokeSync(ClientInvoker.java:152)\n\tat org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:115)\n\tat org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76)\n\tat
However, after timeout happens... successive invoke of API Works.
Not sure why do I get above error if Application is left idle (May be Token Expired but that should not result is Connection Timeout)
Well, I Could not figure out the root cause but doing following changes has solved the problem.
Adding network element as below and
Assigning IP to each service
Pointing to the correct IP of Keycloak in my App Service Definition.
keycloak:
image: xxxx
container_name: keycloak
networks:
my-network:
ipv4_address: 172.29.1.2
ports:
- 8085:8080
app:
image: xxxx
container_name: app
environment:
KEYCLOAK_HOST: http://172.29.1.2:8080
networks:
my-network:
ipv4_address: 172.29.1.3
ports:
- 8081:8081
networks:
my-network:
ipam:
driver: default
config:
- subnet: 172.29.0.0/16
I have two containers (both .net-core), a Web Application and a Web API, the Web Application can be accessed from the host machine using http://localhost:51217, however I can't access the Web API using http://localhost:51218, I got the connection refused, in order to access the Web API, I had to change the Kerstel URL configuration from ASPNETCORE_URLS=http://localhost to ASPNETCORE_URLS=http://0.0.0.0, so webserver listen all IP's.
Any clue why the localhost works for the Web App but not for the Web API, although both have different port mapping.
See below my docker-compose working fine, if I change the API to ASPNETCORE_URLS=http://localhost, I will get connection refused. The docker files exposes port 80.
version: '3.5'
services:
documentuploaderAPI:
image: ${DOCKER_REGISTRY-}documentuploader
container_name: DocumentUpoaderAPI
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0
networks:
- doc_manager
ports:
- "51217:80"
volumes:
- ${APPDATA}/Microsoft/UserSecrets/:/root/.microsoft/usersecrets
- ${APPDATA}/ASP.NET/Https/:/root/.aspnet/https/
- c:\azurite:/root/.unistad/
build:
context: .
dockerfile: DocumentUploader/Dockerfile
documentmanagerAPP:
image: ${DOCKER_REGISTRY-}documentmanager
container_name: DocumentManagerApp
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://localhost;http://localhost
networks:
- doc_manager
ports:
- "51218:80"
volumes:
- ${APPDATA}/Microsoft/UserSecrets/:/root/.microsoft/usersecrets
- ${APPDATA}/ASP.NET/Https/:/root/.aspnet/https/
build:
context: .
dockerfile: Document Manager/Dockerfile
networks:
doc_manager:
name: doc_manager
driver: bridge
Any idea why localhost doesn't work for the API? Any suggestion also how can I trace or sniff the communication from browser until the web server in the container?
You can find below the docker networking design, which may help on my question.
So I'm currently building a docker setup with a REST API and a separate frontend. My backend consists of Symfony 5.2.6 as REST API and my frontend is a simple Vue application.
When I try to call my API from the vue application via localhost or 127.0.0.1, I get a "Connection refused" error. When I try to call the API via the external IP of my server, I run into CORS issues. This is my first setup like this, so I'm kind of at a loss.
This is my docker setup:
version: "3.8"
services:
# VUE-JS Instance
client:
build: client
restart: always
logging:
driver: none
volumes:
- ./client:/app
- /app/node_modules
environment:
- CHOKIDAR_USEPOLLING=true
- NODE_ENV=development
ports:
- 8080:8080
# SERVER
php:
build: php-fpm
restart: always
ports:
- "9002:9000"
volumes:
- ./server:/var/www/:cached
- ./logs/symfony:/var/www/var/logs:cached
# WEBSERVER
nginx:
build: nginx
restart: always
ports:
- "80:80"
volumes_from:
- php
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./logs/nginx/:/var/log/nginx:cached
So what is the correct way to establish the connection between those two containers?
The client app runs on port 8080 but nginx on 80 is a different URL and it should be a CORS error.
To avoid it, in the PHP app, you have to add response header:
Access-Control-Allow-Origin: http://localhost:8080 or
Access-Control-Allow-Origin: *.
Another solution is to configure all in one domain on this same port.
I have a few services running in different docker containers, as per my docker-compose:
version: '3'
services:
rest:
build:
context: './service/'
image: persian_rest:latest
container_name: persian_rest
ports:
- 8080:8080
networks:
- persian_net
volumes:
- persian_volume:/data
scheduler:
build:
context: './scheduler/'
image: persian_scheduler:latest
container_name: persian_scheduler
networks:
- persian_net
ui:
build:
context: './ui/'
image: persian_ui:latest
container_name: persian_ui
ports:
- 5000:5000
networks:
- persian_net
database:
image: 'mongo:latest'
container_name: 'persian_database'
networks:
- persian_net
environment:
- MONGO_INITDB_ROOT_USERNAME=persian_admin
- MONGO_INITDB_ROOT_PASSWORD=123456
ports:
- 27017:27017
volumes:
- persian_volume:/data
volumes:
persian_volume:
networks:
persian_net:
driver: bridge
I have my UI persian_ui service making HTTP request to the REST service persian_rest. I thought that since they were in the same network, I would just make a request to http://persian_rest:8080/api
However, when I do make that request, it fails to find that resource:
Does anyone know why my containers joined by the same network are not able to perform requests?
Currently you are looking at a webpage at localhost:5000. You requested the webpage from the server localhost:5000 and it complied and sent you a webpage which is now sitting on your computer.
If you now want to access an API on the same server as the webpage, you can make another request to localhost but this time port 8080. localhost:8080/api.
The webpage in the browser is on the client-side, and the names you've given your containers are for reference inside the server. From outside the server, currently the reference is localhost.
I have seen several possibilities how to communicate between docker containers. I tried the most of them except proxying which i cant translate to my scenario.
I have a vue-frontend, java-backend- container.
In the frontend i use axios to make http request.
I want to make a http request axios.get(http:localhost:7080/ping), which gives me status 200 but I dont get an response and some CORS problem.(Which is very strange, because the cors header are present if i use postman for the request)
If i use axios.get(http:container_name:7080/ping) I get some other error
net::ERR_NAME_NOT_RESOLVED.
Other solutions (using nginx) using reverse proxy. Do I need something like this or do I have some other misconfiguration?
My docker-compose looks like this:
services:
backend:
container_name: backend
build: ./backend
volumes:
- xxx
ports:
- 7048:7048
- 7080:7080
- 7009:9009
frontend:
container_name: frontend
build:
context: ../frontend
dockerfile: ./Dockerfile
volumes:
- ../xxx
ports:
- 8080:8080
#- 8001:8001
depends_on:
- backend
environment:
- NODE_ENV=development
# - CHOKIDAR_USEPOLLING=true