Making an HTTP request within the same Docker network - docker

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.

Related

NetCore Docker Application with connection refused

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.

How to properly call another docker container via axios?

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.

Cannot reach docker network service but can reach from external IP

I have the following Docker Compose file where I declare 3 services: db, api, sdk-py-test
The service sdk-py-test creates a container craft-sdk-py-test which sends a bunch of http requests to the GraphQL API container craft-api created by the service named api.
The requests succeed when craft-sdk-py-test sends them on the external URL: http://172.30.0.3:5433/graphql
But when I try to send them via the Docker network internal URL: http://api:5433/graphql I get immediately an error message:
gql.transport.exceptions.TransportServerError: 502 Server Error: notresolvable for url: http://api:5433/graphql
How can I use the internal service name api to route the requests instead of the IP address?
Docker Compose File
version: "3.5"
services:
db:
container_name: craft-db
restart: always
image: craft-db
env_file:
- ./.env
ports:
- 5432:5432
api:
container_name: craft-api
restart: always
image: craft-api
env_file:
- ./.env
depends_on:
- db
ports:
- 5433:5433
sdk-py-test:
container_name: craft-sdk-py-test
image: craft-sdk-py-test
build:
context: ./
dockerfile: Dockerfile.test
env_file:
- ./.env
depends_on:
- api
volumes:
- ./tests:/tests/tests
- ./craft:/tests/craft
command: ["nose2", "-v"]

Why can't I connect to this docker compose service?

So I have this docker compose file
version: "2.1"
services:
nginx:
image: pottava/proxy
ports:
- 8080:80
environment:
- PROXY_URL=http://transmission-container:5080/
- BASIC_AUTH_USER=admin
- BASIC_AUTH_PASS=admin
- ACCESS_LOG=true
transmission:
image: linuxserver/transmission
container_name: transmission-container
ports:
- 5080:9091
restart: unless-stopped
I'm new to docker compose and trying it out for the first time. I need to be able to access the transmission service via http://localhost:8080 but nginx is returning a 502.
How should I change my compose file so that http://localhost:8080 will connect to the transmission service?
How can I make the transmission service not accessible via http://localhost:5080 and only accessible via http://localhost:8080 using docker compose?
I have tested the code below, it is working
version: "2.1"
services:
nginx:
image: pottava/proxy
ports:
- 8080:80
environment:
- PROXY_URL=http://transmission-container:9091/
- BASIC_AUTH_USER=admin
- BASIC_AUTH_PASS=admin
- ACCESS_LOG=true
transmission:
image: linuxserver/transmission
container_name: transmission-container
expose:
- "9091"
restart: unless-stopped
You no need to expose port 5080 to the host, the Nginx container can access directly the container port. The proxy URL needs to point to port 9091. Now you can't directly access the transmission service but need to go though the proxy server.
You should be able to access the other container using the service name and container port:
- PROXY_URL=http://transmission:9091/
If you do not want to access the transmission service from locahost, do not declare the host port:
ports:
- 9091

Docker mis-forwarding ports

I have several domains sharing one public IP (EC2 instance). My setup is like this:
/home/ubuntu contains docker-compose.yml:
version: '3'
services:
nginx-proxy:
image: "jwilder/nginx-proxy"
container_name: nginx-proxy
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
ports:
- "80:80"
restart: "always"
This creates a network named ubuntu_default which will allow other compose instances to join. The nginx-proxy image creates reverse proxies for these other compose instances so that you can visit example.com and be routed to the appropriate UI within the appropriate compose instance.
/home/ubuntu/example.com/project-1 contains a docker-compose.yml like:
version: '3'
services:
db:
build: "./db" # mongo
volumes:
- "./data:/data/db"
restart: "always"
api:
build: "./api" # a node backend
ports:
- "9005:9005"
restart: "always"
depends_on:
- db
ui:
build: "./ui" # a react front end
ports:
- "8005:8005"
restart: "always"
environment:
- VIRTUAL_HOST=project-1.example.com # this tells nginx-proxy which domain to proxy
- VIRTUAL_PORT=8005 # this tells nginx-proxy which port to proxy
networks:
default:
external:
name: ubuntu_default
/home/ubuntu/testing.com/project-2 contains a docker-compose.yml like:
version: '3'
services:
db:
build: "./db" # postgres
volumes:
- "./data:/var/lib/postgresql/data"
restart: "always"
api:
build: "./api" # a python backend
ports:
- "9000:9000"
restart: "always"
depends_on:
- db
ui:
build: "./ui" # a react front end
ports:
- "8000:8000"
restart: "always"
environment:
- VIRTUAL_HOST=testing.com,www.testing.com # tells nginx-proxy which domains to proxy
- VIRTUAL_PORT=8000 # tells nginx-proxy which port to proxy
networks:
default:
external:
name: ubuntu_default
So basically:
project-1.example.com:80 forwards to the UI running on :8005
project-1.example.com:80/api forwards to the API running on :9005
testing.com forwards to the UI running on :8000
testing.com/api forwards to the API running on :9000
...and that all works perfectly as long as I only run one at a time. The moment I start both Compose instances, the /api urls start clashing. I can sit on one of them and refresh repeatedly and sometimes I'll see the one for example.com/api and sometimes I'll see the one for testing.com/api.
I have no idea whats going on at this point. Maybe the premise I'm working against is fundamentally flawed but it seems like an intended use of Docker/Compose. I'm open to suggestions to accomplish the same otherwise.
Docker containers communicate using DNS lookups on their network. If multiple containers have the same alias on the same network, it will round robin load balance between the containers with each network connection. If you don't want containers to talk to each other, then you don't want them on the same docker network. The good news is you solve this by using more than one network, and not putting the api and db server on the frontend proxy network:
version: '3'
services:
db:
build: "./db" # postgres
volumes:
- "./data:/var/lib/postgresql/data"
restart: "always"
api:
build: "./api" # a python backend
ports:
- "9000:9000"
restart: "always"
depends_on:
- db
ui:
build: "./ui" # a react front end
ports:
- "8000:8000"
restart: "always"
networks:
- default
- proxy
environment:
- VIRTUAL_HOST=testing.com,www.testing.com # tells nginx-proxy which domains to proxy
- VIRTUAL_PORT=8000 # tells nginx-proxy which port to proxy
networks:
proxy:
external:
name: ubuntu_default
If you do not override the default network, docker will create one for your compose project and use it for any containers not assigned to another network.

Resources