Search code examples
pythondockermatplotlibhuggingface

Matplotlib in huggingfaces space cases Permission Denied Error


I am trying to setup huggingface spaces. Here is my dockerfile

FROM python:3.9

WORKDIR /code

COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --prefer-binary -r /code/requirements.txt

RUN pip install --user matplotlib
COPY . .

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]

When I try to build it and start it it gives me the following error:

-->

===== Application Startup =====

Fetching model from: https://huggingface.co/facebook/wav2vec2-large-960h-lv60-self
Traceback (most recent call last):
  File "/usr/local/bin/uvicorn", line 8, in 
    sys.exit(main())
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  ......
  File "/code/./app.py", line 3, in 
    gr.Interface.load("models/facebook/wav2vec2-large-960h-lv60-self").launch()
  File "/usr/local/lib/python3.9/site-packages/gradio/interface.py", line 109, in load
    return super().load(name=name, src=src, api_key=api_key, alias=alias, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/gradio/blocks.py", line 1154, in load
    return external.load_blocks_from_repo(name, src, api_key, alias, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/gradio/external.py", line 58, in load_blocks_from_repo
    blocks: gradio.Blocks = factory_methods[src](name, api_key, alias, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/gradio/external.py", line 311, in from_model
    interface = gradio.Interface(**kwargs)
  File "/usr/local/lib/python3.9/site-packages/gradio/interface.py", line 424, in __init__
    self.flagging_callback.setup(
  File "/usr/local/lib/python3.9/site-packages/gradio/flagging.py", line 187, in setup
    os.makedirs(flagging_dir, exist_ok=True)
  File "/usr/local/lib/python3.9/os.py", line 225, in makedirs
    mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: 'flagged'

I tried creating folder giving it permission by adding RUN chown statement but it does not seem to work, how can I work around it?


Solution

  • What is happening?

    1. Gradio is trying to create the "flagged" subdirectory next to your app.
    2. The app lacks permissions to create that folder.

    Where to start:

    Things I tried based on internet recommendations when I encountered this issue, which did not work for me but might for you:

    • Try changing the permissions on the files before they get used by Docker, such as with chmod -R 777 . from your code directory. Docker will copy the permissions of the files when it copies the folder contents.
    • If that doesn't work (it didn't for me when I encountered this issue), you can try setting the USER in your Dockerfile and setting up a user space, as described on Huggingface here: https://huggingface.co/docs/hub/spaces-sdks-docker#permissions

    Completing the solution:

    Neither of the above by themselves worked for me, but what did work for me was to then:

    1. Set USER to root
    2. Add RUN chmod 777 ~/app/*

    For good practice I also set up a non-root user and switched back to that after setting the permissions.

    Here's the final Dockerfile that worked for my project, which started up a gradio app running on an image of Debian Buster Linux:

    FROM python:3.10-slim-buster
    
    ### Set up user with permissions
    # Set up a new user named "user" with user ID 1000
    RUN useradd -m -u 1000 user
    
    # Switch to the "user" user
    USER user
    
    # Set home to the user's home directory
    ENV HOME=/home/user \
        PATH=/home/user/.local/bin:$PATH
    
    # Set the working directory to the user's home directory
    WORKDIR $HOME/app
    
    # Copy the current directory contents into the container at $HOME/app setting the owner to the user
    COPY --chown=user . $HOME/app
    
    ### Set up app-specific content
    COPY requirements.txt requirements.txt
    RUN pip3 install -r requirements.txt
    
    COPY . .
    
    ### Update permissions for the app
    USER root
    RUN chmod 777 ~/app/*
    USER user
    
    EXPOSE 7860 7860
    
    ENTRYPOINT ["python3"]
    CMD ["gradio_app.py"]