Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugger pin calls getuser(), which can fail inside Docker #1471

Closed
jaumebecks opened this issue Mar 12, 2019 · 4 comments

Comments

Projects
None yet
3 participants
@jaumebecks
Copy link

commented Mar 12, 2019

When launching an application with the Werkzeug debugger in Docker with a custom UID, the debugger fails while trying to construct a PIN.

Traceback (most recent call last):
  File "/usr/local/bin/flask", line 10, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 894, in main
    cli.main(args=args, prog_name=name)
  File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 557, in main
    return super(FlaskGroup, self).main(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/click/decorators.py", line 64, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 771, in run_command
    threaded=with_threads, ssl_context=cert)
  File "/usr/local/lib/python3.7/site-packages/werkzeug/serving.py", line 751, in run_simple
    application = DebuggedApplication(application, use_evalex)
  File "/usr/local/lib/python3.7/site-packages/werkzeug/debug/__init__.py", line 258, in __init__
    if self.pin is None:
  File "/usr/local/lib/python3.7/site-packages/werkzeug/debug/__init__.py", line 268, in _get_pin
    self._pin, self._pin_cookie = get_pin_and_cookie_name(self.app)
  File "/usr/local/lib/python3.7/site-packages/werkzeug/debug/__init__.py", line 148, in get_pin_and_cookie_name
    username = getpass.getuser()
  File "/usr/local/lib/python3.7/getpass.py", line 169, in getuser
    return pwd.getpwuid(os.getuid())[0]
KeyError: 'getpwuid(): uid not found: 1001'

username = getpass.getuser()

It seems that Werkzeug fails on this line when trying to get the user with $UID specified in docker-compose.yml.

Maybe a workaround could be create the user group and the user inside the docker instance, but it's not scalable.

docker-compose.yml:

image: local/imageTest
build:
    context: .
    dockerfile: dockerfiles/Dockerfile
    args:
      BUILD_ENV: dev
user: $UID
volumes:
    - ./:/code
env_file:
    - .env.sample
    - .env
environment:
    HOME: /code
    FLASK_APP: "test/web.py"
    FLASK_DEBUG: "1"
depends_on:
    - postgres
ports:
    - 5050:5000
command: ["flask", "run", "--host=0.0.0.0"]

Dockerfile:

FROM library/python:3.7.0

WORKDIR /code/

ARG BUILD_ENV=prod

RUN apt-get update \
 && apt-get install -y python3-dev python3-psycopg2 python3-gdal libgdal-dev \
 && rm -rf /var/lib/apt/lists/*

ADD requirements*.txt /code/
RUN pip3 install -U pip setuptools
RUN pip3 install -r requirements-${BUILD_ENV}.txt
ADD . /code/

ENV PYTHONPATH "/code"
@ThiefMaster

This comment has been minimized.

Copy link
Member

commented Mar 12, 2019

That's because your container provides a broken environment where your /etc/passwd has no entry for the UID. Run useradd with a fixed UID in your Dockerfile to create the user properly.

However, since this is just in the debugger, and we already skip the username e.g. on GAE, I think we could just catch KeyError here as well: https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/__init__.py#L165

@davidism

This comment has been minimized.

Copy link
Member

commented Mar 12, 2019

I just tried this with the python:3.7-alpine official image and did not have an issue calling getpass.getuser(), it returned 'root'. It sounds like an issue with the image you're using.

@davidism davidism changed the title Flask app crashes when run inside docker (debug mode) -> KeyError: 'getpwuid(): uid not found: 1001' Debugger pin calls getuser(), which can fail inside Docker Mar 12, 2019

@ThiefMaster

This comment has been minimized.

Copy link
Member

commented Mar 12, 2019

The problem is that he is using it for development so he's setting the container UID to his regular UID to avoid issues with files created from inside the container.

@jaumebecks

This comment has been minimized.

Copy link
Author

commented Mar 12, 2019

I just tried this with the python:3.7-alpine official image and did not have an issue calling getpass.getuser(), it returned 'root'. It sounds like an issue with the image you're using.

As ThiefMaster points here

The problem is that he is using it for development so he's setting the container UID to his regular UID to avoid issues with files created from inside the container.

The problem comes from docker-compose.yml in user: $UID. With root it works by default.

And finally:

That's because your container provides a broken environment where your /etc/passwd has no entry for the UID. Run useradd with a fixed UID in your Dockerfile to create the user properly.

However, since this is just in the debugger, and we already skip the username e.g. on GAE, I think we could just catch KeyError here as well: https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/__init__.py#L165

That's true, it's something like I mention here:

Maybe a workaround could be create the user group and the user inside the docker instance, but it's not scalable.

If I add the following to the image it would work, but it's a pity because I cannot manage N users.

RUN groupadd -g 1000 developer1000 && useradd -u 1000 -g 1000 developer1000 && \
    groupadd -g 1001 developer1001 && useradd -u 1001 -g 1001 developer1001

Thanks for your quick responses anyway ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.