3

I have been trying to create a flask app inside a docker container. The app works perfectly when run through the Flask development server, including access to the web pages from other machines on the network.

I have been trying to build a Docker container for the app. The problem is that I cannot access any web pages. I get 500 errors.

Some of my setup:

run.py

#!flask_v1/bin/python3
from app import app
app.run(debug=True, host='0.0.0.0')

Where flask_v1 is the virtualenv directory.

dockerfile

FROM python:3.4
COPY . /site
workdir /site
RUN pip install -r requirements.txt
ENV NAME sitename
CMD ["python", "./run.py"]

I removed EXPOSE 5000 from this version, but the same issues occurred with it present. It was originally placed under the pip line.

requirements.txt

click==6.7
CouchDB==1.1
docutils==0.14
Flask==0.12.2
Flask-CouchDB==0.2.1
flask-dynamo==0.1.2
Flask-Login==0.4.0
Flask-WTF==0.14.2
itsdangerous==0.24
Jinja2==2.9.6
jmespath==0.9.3
MarkupSafe==1.0
python-dateutil==2.6.1
PyYAML==3.12
s3transfer==0.1.11
six==1.11.0
Werkzeug==0.12.2
WTForms==2.1

Then I ran the build command as follows (with dockername replaced by an actual name):

docker build -t dockername .

Build completes and I run the image as follows:

docker run -p 5000:5000 dockername

Attempting to connect to the app at localhost:5000/index (the 'home' for the app), or just localhost:5000, or 127.0.0.1:5000/index, or [host_ip]:5000/index, or [container_ip]:5000/index all produced the same error:

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.4/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 1610, in full_dispatch_request
    rv = self.preprocess_request()
  File "/usr/local/lib/python3.4/site-packages/flask/app.py", line 1831, in preprocess_request
    rv = func()
  File "/usr/local/lib/python3.4/site-packages/flaskext/couchdb.py", line 154, in request_start
    self.sync(current_app)
  File "/usr/local/lib/python3.4/site-packages/flaskext/couchdb.py", line 131, in sync
    if db_name not in server:
  File "/usr/local/lib/python3.4/site-packages/couchdb/client.py", line 96, in __contains__
    self.resource.head(name)
  File "/usr/local/lib/python3.4/site-packages/couchdb/http.py", line 549, in head
    return self._request('HEAD', path, headers=headers, **params)
  File "/usr/local/lib/python3.4/site-packages/couchdb/http.py", line 581, in _request
    credentials=self.credentials)
  File "/usr/local/lib/python3.4/site-packages/couchdb/http.py", line 289, in request
    conn = self.connection_pool.get(url)
  File "/usr/local/lib/python3.4/site-packages/couchdb/http.py", line 507, in get
    conn.connect()
  File "/usr/local/lib/python3.4/http/client.py", line 871, in connect
    self.timeout, self.source_address)
  File "/usr/local/lib/python3.4/socket.py", line 516, in create_connection
    raise err
  File "/usr/local/lib/python3.4/socket.py", line 507, in create_connection
    sock.connect(sa)
OSError: [Errno 99] Cannot assign requested address

After reading some other stackoverflow issues similar to this, I ran the container with the -d option and I accessed the container as follows:

docker exec -ti <container name> bash

Once inside, using curl and wget I attempted to access localhost:5000/index. Wget just threw 500 errors. Curl returns the Werkzeug page (see error dump above), including all of the html formatting. The directory structure looks fine

I know I must have something configured incorrectly. I just can't see what it is. The app works outside Docker and doesn't once in Docker. That I can't access the page from inside the container tells me something isn't right about the setup, but I'm either lacking the know how or having a "wood for the trees" moment. Please help a relative newbie.

Community
  • 1
  • 1
Brett
  • 43
  • 1
  • 5
  • In your Dockerfile you need to [`EXPOSE`](https://docs.docker.com/engine/reference/builder/#expose) the port, then map it to a local port. – blakev Oct 09 '17 at 22:58
  • 1
    @blakev `EXPOSE` is not required to map a port, it's more for documentation of the port the image will expose – Matt Oct 10 '17 at 02:26
  • Maybe it's because you can't connect to couchdb inside your container. Or maybe it's because your `app.run` parameters are in a weird order. `app.run('0.0.0.0', 5000, debug=True)` – blakev Oct 10 '17 at 02:29
  • The `Cannot assign requested address` looks like you are trying to bind the server to a specific IP that is not available in the container. Have you configured a listen IP or hostname in the app somewhere? – Matt Oct 10 '17 at 02:30
  • @Matt Yeah. I had expose in there and it there was no result change, so at least in this situation it seems to have no effect. As to the IP, all of the examples of docker and flask use 0.0.0.0, as a lot Flask examples without Docker do, as it allows the app to be accessed from beyond localhost. blakev I'll give reordering the parameters a try and see what happens. – Brett Oct 10 '17 at 13:14

1 Answers1

2

If you look at the error, first of all this is an application exception. This means your binding on host and inside the container are all working. And it has nothing to with exposed port.

If we have a second look at the exception stack trace

File "/usr/local/lib/python3.4/site-packages/couchdb/http.py", line 289, in request
    conn = self.connection_pool.get(url)
  File "/usr/local/lib/python3.4/site-packages/couchdb/http.py", line 507, in get
    conn.connect()
  File "/usr/local/lib/python3.4/http/client.py", line 871, in connect
    self.timeout, self.source_address)

You are connecting to couch DB and that address is not correct and that is what is throwing the error here. The error OSError: [Errno 99] Cannot assign requested address is a bit misleading, but it is because you are unable to connect to the Couch DB service which may be configured wrongly or not running at all

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • Thank you. I thought it might be related to that after Matt's comment as well, so I rebuilt the container after removing any calls to couch. I was using a local instance of couch, but I didn't build it into the container or give the container any instructions on how to reach it. – Brett Oct 10 '17 at 15:56
  • 1
    I have too low a rep to uprate your answer, but it is the correct one, so +1 in spirit – Brett Oct 10 '17 at 15:56