gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
30.56k stars 2.27k forks source link

Broken IPv6 in Docker Container #8437

Open bival-pierre-grimme opened 3 weeks ago

bival-pierre-grimme commented 3 weeks ago

Describe the bug

Trying to set a dualstack network configuration via environment variables in docker compose

environment:
  - GRADIO_SERVER_PORT=7861
  - GRADIO_SERVER_NAME="[::]"

fails with:

OSError: Cannot find empty port in range: 7861-7960. You can specify a different port by setting the GRADIO_SERVER_PORT environment variable or passing the server_port parameter to launch()

not a suitable workaround:

import gradio as gr
import logging

logging.basicConfig(level=logging.DEBUG)

def greet(name, intensity):
    return "Hello, " + name + "!" * int(intensity)

demo = gr.Interface(
    fn=greet,
    inputs=["text", "slider"],
    outputs=["text"],
)

if __name__ == "__main__":
    demo.launch(debug=True, server_name="[::]")

because the docker container is not reachable from [::]:7861 from the host system. I verified it with a fastapi sample and the fastapi works dualstack no problem (access via [::1]:8080 in the browser).

Another interesting obversation is, the when GRADIO_SERVER_NAME=0.0.0.0 is set as a container environment variable, i am able to access it via http://[::1]:7860/ from my host system's browser ( keep an eye on my port mapping configuration in the docker compose)

My suggestion is to seperate IPv4 from IPv6. When you choose 0.0.0.0 it will only listen to IPv4 and if you choose :: it will listen to IPv4+IPv6.

Have you searched existing issues? 🔎

Reproduction

import gradio as gr
import logging

logging.basicConfig(level=logging.DEBUG)

def greet(name, intensity):
    return "Hello, " + name + "!" * int(intensity)

demo = gr.Interface(
    fn=greet,
    inputs=["text", "slider"],
    outputs=["text"],
)

if __name__ == "__main__":
    demo.launch(debug=True)
docker compose:

    ports:
      - "7860:7861"
    environment:
      - GRADIO_SERVER_PORT=7861
      - GRADIO_SERVER_NAME=0.0.0.0
    #  - GRADIO_SERVER_NAME='::'
    #  - GRADIO_SERVER_NAME="::"
    #  - GRADIO_SERVER_NAME="[::]"
FROM python:3.10-slim

WORKDIR /app

RUN pip install gradio --no-cache

COPY . .

CMD ["python", "test.py"]

Screenshot

No response

Logs

2024-06-03 12:36:34 DEBUG:httpx:load_ssl_context verify=True cert=None trust_env=True http2=False
2024-06-03 12:36:34 DEBUG:httpx:load_ssl_context verify=True cert=None trust_env=True http2=False
2024-06-03 12:36:34 DEBUG:asyncio:Using selector: EpollSelector
2024-06-03 12:36:34 DEBUG:httpx:load_verify_locations cafile='/usr/local/lib/python3.10/site-packages/certifi/cacert.pem'
2024-06-03 12:36:34 DEBUG:httpx:load_verify_locations cafile='/usr/local/lib/python3.10/site-packages/certifi/cacert.pem'
2024-06-03 12:36:34 DEBUG:httpcore.connection:connect_tcp.started host='api.gradio.app' port=443 local_address=None timeout=3 socket_options=None
2024-06-03 12:36:34 DEBUG:httpcore.connection:connect_tcp.started host='checkip.amazonaws.com' port=443 local_address=None timeout=3 socket_options=None
2024-06-03 12:36:34 Traceback (most recent call last):
2024-06-03 12:36:34   File "/app/./frontend/test.py", line 16, in <module>
2024-06-03 12:36:34     demo.launch(debug=True)
2024-06-03 12:36:34   File "/usr/local/lib/python3.10/site-packages/gradio/blocks.py", line 2321, in launch
2024-06-03 12:36:34     ) = http_server.start_server(
2024-06-03 12:36:34   File "/usr/local/lib/python3.10/site-packages/gradio/http_server.py", line 154, in start_server
2024-06-03 12:36:34     raise OSError(
2024-06-03 12:36:34 OSError: Cannot find empty port in range: 7861-7960. You can specify a different port by setting the GRADIO_SERVER_PORT environment variable or passing the `server_port` parameter to `launch()`.
2024-06-03 12:36:34 DEBUG:httpcore.connection:connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x7f03bbf69810>
2024-06-03 12:36:34 DEBUG:httpcore.connection:start_tls.started ssl_context=<ssl.SSLContext object at 0x7f03c08f3140> server_hostname='checkip.amazonaws.com' timeout=3
2024-06-03 12:36:34 DEBUG:httpcore.connection:connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x7f03bbf2ac80>
2024-06-03 12:36:34 DEBUG:httpcore.connection:start_tls.started ssl_context=<ssl.SSLContext object at 0x7f03c08f3340> server_hostname='api.gradio.app' timeout=3
2024-06-03 12:36:34 DEBUG:httpcore.connection:start_tls.complete return_value=<httpcore._backends.sync.SyncStream object at 0x7f03bbf697e0>
2024-06-03 12:36:34 DEBUG:httpcore.http11:send_request_headers.started request=<Request [b'GET']>
2024-06-03 12:36:34 DEBUG:httpcore.http11:send_request_headers.complete
2024-06-03 12:36:34 DEBUG:httpcore.http11:send_request_body.started request=<Request [b'GET']>
2024-06-03 12:36:34 DEBUG:httpcore.http11:send_request_body.complete
2024-06-03 12:36:34 DEBUG:httpcore.http11:receive_response_headers.started request=<Request [b'GET']>
2024-06-03 12:36:34 DEBUG:httpcore.http11:receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'', [(b'Date', b'Mon, 03 Jun 2024 10:36:35 GMT'), (b'Content-Type', b'text/plain;charset=UTF-8'), (b'Content-Length', b'12'), (b'Connection', b'keep-alive'), (b'Server', b'nginx'), (b'Vary', b'Origin'), (b'Vary', b'Access-Control-Request-Method'), (b'Vary', b'Access-Control-Request-Headers')])
2024-06-03 12:36:34 INFO:httpx:HTTP Request: GET https://checkip.amazonaws.com/ "HTTP/1.1 200 "
2024-06-03 12:36:34 DEBUG:httpcore.http11:receive_response_body.started request=<Request [b'GET']>
2024-06-03 12:36:34 DEBUG:httpcore.http11:receive_response_body.complete
2024-06-03 12:36:34 DEBUG:httpcore.http11:response_closed.started
2024-06-03 12:36:34 DEBUG:httpcore.http11:response_closed.complete
2024-06-03 12:36:34 DEBUG:httpcore.connection:close.started
2024-06-03 12:36:34 DEBUG:httpcore.connection:close.complete
2024-06-03 12:36:34 DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): huggingface.co:443
2024-06-03 12:36:35 DEBUG:urllib3.connectionpool:https://huggingface.co:443 "HEAD /api/telemetry/gradio/initiated HTTP/1.1" 200 0
2024-06-03 12:36:35 DEBUG:httpcore.connection:start_tls.complete return_value=<httpcore._backends.sync.SyncStream object at 0x7f03bbf2ac50>
2024-06-03 12:36:35 DEBUG:httpcore.http11:send_request_headers.started request=<Request [b'GET']>
2024-06-03 12:36:35 DEBUG:httpcore.http11:send_request_headers.complete
2024-06-03 12:36:35 DEBUG:httpcore.http11:send_request_body.started request=<Request [b'GET']>
2024-06-03 12:36:35 DEBUG:httpcore.http11:send_request_body.complete
2024-06-03 12:36:35 DEBUG:httpcore.http11:receive_response_headers.started request=<Request [b'GET']>
2024-06-03 12:36:35 DEBUG:httpcore.http11:receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Date', b'Mon, 03 Jun 2024 10:36:36 GMT'), (b'Content-Type', b'application/json'), (b'Content-Length', b'21'), (b'Connection', b'keep-alive'), (b'Server', b'nginx/1.18.0'), (b'Access-Control-Allow-Origin', b'*')])
2024-06-03 12:36:35 INFO:httpx:HTTP Request: GET https://api.gradio.app/pkg-version "HTTP/1.1 200 OK"
2024-06-03 12:36:35 DEBUG:httpcore.http11:receive_response_body.started request=<Request [b'GET']>
2024-06-03 12:36:35 DEBUG:httpcore.http11:receive_response_body.complete
2024-06-03 12:36:35 DEBUG:httpcore.http11:response_closed.started
2024-06-03 12:36:35 DEBUG:httpcore.http11:response_closed.complete
2024-06-03 12:36:35 DEBUG:httpcore.connection:close.started
2024-06-03 12:36:35 DEBUG:httpcore.connection:close.complete

System Info

docker v4.30.0
--------------
Gradio Environment Information:
------------------------------
Operating System: Linux
gradio version: 4.32.2
gradio_client version: 0.17.0

------------------------------------------------
gradio dependencies in your environment:

aiofiles: 23.2.1
altair: 5.3.0
fastapi: 0.111.0
ffmpy: 0.3.2
gradio-client==0.17.0 is not installed.
httpx: 0.27.0
huggingface-hub: 0.23.2
importlib-resources: 6.4.0
jinja2: 3.1.4
markupsafe: 2.1.5
matplotlib: 3.9.0
numpy: 1.26.4
orjson: 3.10.3
packaging: 24.0
pandas: 2.2.2
pillow: 10.3.0
pydantic: 2.7.2
pydub: 0.25.1
python-multipart: 0.0.9
pyyaml: 6.0.1
ruff: 0.4.7
semantic-version: 2.10.0
tomlkit==0.12.0 is not installed.
typer: 0.12.3
typing-extensions: 4.12.1
urllib3: 2.2.1
uvicorn: 0.30.1
authlib; extra == 'oauth' is not installed.
itsdangerous; extra == 'oauth' is not installed.

gradio_client dependencies in your environment:

fsspec: 2024.5.0
httpx: 0.27.0
huggingface-hub: 0.23.2
packaging: 24.0
typing-extensions: 4.12.1
websockets: 11.0.3

Severity

I can work around it