Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker. Failed to establish a new connection: [Errno 111] Connection refused'

I want to send post request from one container to another, both are flask apps.

When i push send button in form my request cant be sended with error:

requests.exceptions.ConnectionError: HTTPConnectionPool(host='0.0.0.0', port=5000): Max 
retries exceeded with url: /users/ (Caused by 
NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fe0e5738ac0>: Failed to 
establish a new connection: [Errno 111] Connection refused'))

Im trying to run it just on localhost. When i use docker-compose up, everything is ok, until im trying send request.

app 1 code (app, that im trying to send request from):

from settings import app, db
from flask import jsonify, request
from models import User     

@app.route('/users/', methods=['POST'])
def users_post():
    if request.json:
        new_user = User(
            email=request.json['email'], 
            first_name=request.json['first_name'], 
            last_name=request.json['last_name'], 
            password=request.json['password'])

        db.session.add(new_user)
        db.session.commit()
        return jsonify({'msg': 'user succesfully added'})
    else:
        return jsonify({'msg': 'request should be in json format'})



if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0')

dockerfile container 1:

FROM python:3

COPY . ./app

WORKDIR /app

RUN pip3 install -r requirements.txt

EXPOSE 5000 5050

CMD ["python3", "app.py"]

app 2 code:

@app.route('/', methods=['GET', 'POST'])
def users_get():
    if request.method == 'POST':
        request.form['email']
        data = {
            'email':request.form['email'], 
            'first_name':request.form['first_name'], 
            'last_name':request.form['last_name'], 
            'password':request.form['password']
        }
        r = requests.post('http://0.0.0.0:5000/users/', data=data)
        print(r.text)
    return render_template('index.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5050)

dockerfile in app 2 is similar to first one.

docker-compose

version: '3'

services:
  web:
    build: ./core
    command: python3 app.py
    volumes:
      - .:/core
    ports:
      - "5000:5000"
    links:
      - new_app

  new_app:
    build: ./new_app
    command: python3 app.py
    volumes:
      - .:/new_app
    ports:
      - "5050:5050"

What did i missed?

like image 708
Andrej Vilenskij Avatar asked Apr 27 '20 19:04

Andrej Vilenskij


People also ask

Why is there a connection refused in a container?

Now it’s clear why there’s a connection refused: the server is listening on 127.0.0.1 inside the container’s network namespace. The browser is connecting to 127.0.0.1 in the main, default network namespace. But those are different interfaces, so no connection is made.

Why can't I connect to Docker-Compose from a self hosted runner?

Docker-compose seems unable to connect to the docker daemon. Currently we dont support service containers in self hosted runners as mentioned here in the limitations, which means we dont support docker in docker being available to your step for your docker-compose to execute against, this feature will be coming in a future release.

Why can't I use localhost as a hostname for Docker containers?

Localhost is probably the wrong hostname to use. When Docker networks containers you can communicate between containers by using the name of the containers. So say you named your elasticsearch container elasticsearch you would then want to establish a connection to ES using the name elasticsearch instead of localhost.

How to listen to external IP in a docker container?

You therefore need to listen on the external IP inside the container, and the easiest way to do that is by listening on all interfaces: 0.0.0.0. You need to start packaging your Python application with Docker, and you keep hitting errors, from connection refused to OCI runtime complaints, because you don't really understand how it all works.


1 Answers

  1. app1 is missing the port, you should add it:

    app.run(debug=True, host='0.0.0.0', port=5000)

  2. when calling to app1 from app2 you should use its host instead of 0.0.0.0:

    r = requests.post('http://web:5000/users/', data=data)

like image 142
ItayB Avatar answered Sep 21 '22 03:09

ItayB