1

I have 3 docker containers, one is a Node-Express app, one is a Python Fast-API app, and one is an opencpu container.

The node-express app can communicate with the opencpu container through the service name. I can use curl and get data back. But the node-express container cannot send get/post requests to the python container.

I can access the python app from my browser at localhost:9000
I can ping the python container from the node-express container using service name and get replies.
but I cannot send get/post requests to the python container from node-express container.

I get this error: curl: (7) Failed to connect to pythonapi port 80: Connection refused

So I'm unsure why I can reach the opencpu container from the node-express container but not the python container, even though I confirmed the python container works through my browser. Everything is in one docker-compose.yml so I believe I should be able to reach the python container with service name. And I can, I can ping it, so why cant I curl?

NPM-Express dockerfile:

FROM node:12-slim
WORKDIR /starter
ENV NODE_ENV development
COPY package.json /starter/package.jso
RUN npm install 
RUN apt-get update && apt install nano
COPY .env.example /starter/.env.example
COPY . /starter
CMD ["ls"]
CMD ["npm", "run", "start"]

Opencpu dockerfile:

from opencpu/ubuntu-18.04

Python dockerfile:

FROM python:3.9

WORKDIR /this-app
RUN mkdir app
# COPY ./app ./app
COPY ./app/requirements.txt ./app
WORKDIR /this-app/app
RUN pip install -r requirements.txt

WORKDIR ../
COPY ./app/models ./models
COPY ./app/controllers.py .
COPY ./app/main.py .

CMD ["python", "./main.py"]

EXPOSE 8000

Docker compose file:

version: '3'

services:
  web:
    build: ./web
    ports:
     - "8012:8080"

  opencpu:
    image: opencpu
    container_name: opencpu
    build:
      context: ./R
      dockerfile: dockerfile
    ports: 
      - 8014:8004

  python-api
    image: python-api
    build:
      context: ./python
      dockerfile: dockerfile
    ports: 
      - 9000:8000

Edit

For some reason it works when I specify the port (8000) in the curl command.

This is strange to me since in the docker-compose.yml I specify port mapping of 9000 outside the container to 8000 inside the container.

When I use the browser instead of curl, I go to the domain at port 9000 and the python api works. Yet from inside a different docker container I can only reach the api with port 8000. So inside the docker container the port mapping is not working.

Also curl to opencpu does not need the port specified. So why does the python api need the port specified??

1 Answer 1

3

When launching services using docker-compose, the default network configuration launches all the docker containers in the same network (using bridge mode). This means that all the containers can see each other by pointing to their service-name and their exposed port/s (specified in the Dockerfile).

NOTE THAT the service-name is not the container name, but the name you gave to the service in the docker-compose (python-api, opencpu, web, ..)

When mapping ports in the docker-compose file, you're indicating which port in your HOST is mapped to a container's port.

So:

  1. From any container's point of view, you can see other containers by pointing to the service_name:exposed_port (e.g the python-api container is reachable from any other container at python-api:8000)
  2. From the HOST's point of view (this is what happens when you access python-api from the browser), you'll be able to reach the container by pointing to localhost:<mapped_port> (e.g the python-api container is reachable at localhost:9000)

Within the docker network, the mapped ports are "ignored".

When no port is specified using curl, default ports are used. For this reason, when you try to access the python-api service using curl python-api, internally curl is trying to reach python-api:80. The command fails, as indicated in the error message you posted,

I get this error: curl: (7) Failed to connect to pythonapi port 80: Connection refused

since the python-api app is running on port 8000. Note that the hostname in the previous error message does not coincide with the service name either!! I supposed when you reached python-api:8000, you spelled the service name correctly

The opencpu image is based on opencpu/ubuntu-18.04. All the ports exposed in opencpu/ubuntu-18.04 are inherited as exposed in your local image. Probably, there's something listening on port 80/443 in the opencpu/ubuntu-18.04 image, so this is why, when doing curl from another container to this service without specifying the port, it works

I hope this solved your doubts :)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! The opencpu curl-working part really threw me off but it makes sense now!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.