0

I have a python flask web app that uses a python library which is under development that I want to dockerize. This library sends SPARQL queries to search for available books, collections of books obtained from the Gutenberg project. This data is stored as RDF format in a Fuseki server. The Fuseki server is run via docker separately and the SPARQL endpoint for the queries is the following: http://localhost:3030/gutenberg/sparql

The web app is dockerized using the following Docker file

FROM python:3.8-buster

RUN apt-get update
RUN apt-get install -y git

RUN apt-get install -y \
        apt-transport-https \
        ca-certificates \
        curl \
        gnupg2 \
        software-properties-common
COPY requirements.txt /app/requirements.txt
WORKDIR /app

RUN pip3 install -r requirements.txt

COPY . /app

CMD celery -A webapp.app.celery worker  --loglevel=DEBUG
CMD export FLASK_APP=wsgi.py

EXPOSE 80

ENTRYPOINT [ "python" ]

CMD [ "webapp/app.py" ]

with the following command: docker build -t wedh-dhtk-test .

Once the docker image is built, I run it using the following command: docker run --rm -p 80:80 wedh-dhtk-test

The problem that I have is that the docker container running the web app does not seem to be able to connect to the SPARQL endpoint and throws me the two following error messages:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/urllib/request.py", line 1354, in do_open
    h.request(req.get_method(), req.selector, req.data, headers,
  File "/usr/local/lib/python3.8/http/client.py", line 1252, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/lib/python3.8/http/client.py", line 1298, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.8/http/client.py", line 1247, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.8/http/client.py", line 1007, in _send_output
    self.send(msg)
  File "/usr/local/lib/python3.8/http/client.py", line 947, in send
    self.connect()
  File "/usr/local/lib/python3.8/http/client.py", line 918, in connect
    self.sock = self._create_connection(
  File "/usr/local/lib/python3.8/socket.py", line 808, in create_connection
    raise err
  File "/usr/local/lib/python3.8/socket.py", line 796, in create_connection
    sock.connect(sa)
OSError: [Errno 99] Cannot assign requested address

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "webapp/app.py", line 16, in <module>
    AUTHORS = gd.get(what="author", name="all")
  File "/usr/local/lib/python3.8/site-packages/dhtk/extensions/gutenberg/__init__.py", line 98, in get
    response = self.wrapper.all_authors()
  File "/usr/local/lib/python3.8/site-packages/dhtk/extensions/gutenberg/api/data.py", line 387, in all_authors
    return [result["author"] for result in self._get_query_results(query)]
  File "/usr/local/lib/python3.8/site-packages/dhtk/extensions/gutenberg/api/data.py", line 789, in _get_query_results
    query_results = sparql.queryAndConvert()
  File "/usr/local/lib/python3.8/site-packages/SPARQLWrapper/Wrapper.py", line 1114, in queryAndConvert
    res = self.query()
  File "/usr/local/lib/python3.8/site-packages/SPARQLWrapper/Wrapper.py", line 1107, in query
    return QueryResult(self._query())
  File "/usr/local/lib/python3.8/site-packages/SPARQLWrapper/Wrapper.py", line 1073, in _query
    response = urlopener(request)
  File "/usr/local/lib/python3.8/urllib/request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/local/lib/python3.8/urllib/request.py", line 525, in open
    response = self._open(req, data)
  File "/usr/local/lib/python3.8/urllib/request.py", line 542, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "/usr/local/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
  File "/usr/local/lib/python3.8/urllib/request.py", line 1383, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "/usr/local/lib/python3.8/urllib/request.py", line 1357, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 99] Cannot assign requested address>

When looking around, I found the following question who had the same error, namely socket.error:[errno 99] cannot assign requested address running a flask app inside docker container. The issue was solved setting flask IP address to

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

and configuring a port on the Docker file, which I did (recall line 22 of the Docker file EXPOSE 80).

My guess is that the docker container where I run my app is not accessible to other devices, namely the Fuseki server, but I do not find why and I have exhausted means of finding out.

daniel vito
  • 3
  • 1
  • 4
  • I wonder if [this](https://stackoverflow.com/questions/31324981/how-to-access-host-port-from-docker-container) will help. It looks like the problem is you are trying to access localhost:3000 from inside your docker - which thinks that the api is also inside your docker file. You need to access the api on your host. I think that link explians how to create the connection. – sur.la.route May 27 '21 at 13:55
  • @Christopher thanks a lot for your answer. I think you are right, I'll have a look at [it](https://stackoverflow.com/questions/31324981/how-to-access-host-port-from-docker-container). Wandering around I also found this [question](https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach) which is also related to the same problem to getting access to the localhost of a machine from inside of a Docker container. I hope that between the two I can find an answer to my problem. – daniel vito May 27 '21 at 14:48

1 Answers1

0

I found an answer to the issue. As @Christopher said, the trouble was that the container was trying to access my Fuseki server on the localhost:3000 from inside, whereas it was located on the host. To remediate this issue I added the following argument in the docker run command --net="host" and removed -p 80:80. The full docker run command is shown below

docker run --rm --net="host" wedh-dhtk-test

If I understood correctly, it allows my docker container to point to my docker host where the server is located. Anyway it solved my problem since the containerized app is now communicating with the Fuseki server as intended.

daniel vito
  • 3
  • 1
  • 4