tiangolo / uwsgi-nginx-flask-docker

Docker image with uWSGI and Nginx for Flask applications in Python running in a single container.
https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/
Apache License 2.0
2.99k stars 607 forks source link

Permission error on port 80 #62

Closed peerchemist closed 6 years ago

peerchemist commented 6 years ago

@tiangolo any ideas on what could be causing this error:

papi_1       |   File "main.py", line 8, in <module>
papi_1       |     app.run(host='0.0.0.0', debug=True, port=80)
papi_1       |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 841, in run
papi_1       |     run_simple(host, port, self, **options)
papi_1       |   File "/usr/local/lib/python3.6/site-packages/werkzeug/serving.py", line 795, in run_simple
papi_1       |     s.bind(get_sockaddr(hostname, port, address_family))
papi_1       | PermissionError: [Errno 13] Permission denied

Flask should always be listening on the port 80, right?

tiangolo commented 6 years ago

Are you changing the name of the user by any chance?

For debugging purposes, try using a "non-privileged" port, like 8080, and see if that works. That would hint that there are issues with onwership of the file, root access, etc.

peerchemist commented 6 years ago

For debugging purposes, try using a "non-privileged" port, like 8080, and see if that works.

Yes, that works.

The container in question runs as a non-root user.

tiangolo commented 6 years ago

I see, are you on a Mac?

If you are on a Mac, try starting the same stack, using port 80, but using sudo to run it as root, in privileged mode. That way the macOS will let the stack bind to the machine port 80.

If you're not, let me know.

peerchemist commented 6 years ago

Not Mac, Ubuntu 18.04.

Ok so I've just made the app container run as root, it starts using port 80 properly. However it does not seem to expose port 5555 I've set it to? So it answers on port 80 still with apache landing page greeting me.

FROM tiangolo/uwsgi-nginx-flask:python3.6-alpine3.7

ENV APP_DIRECTORY=/app

#RUN 
   #addgroup -S ${USERNAME} \
   # && adduser -D -H -S -s /bin/false -u 1000 -G ${USERNAME} ${USERNAME} \
RUN apk --update --no-cache add build-base \
    && apk add postgresql-dev \
    && python3 -m pip install psycopg2 --no-cache-dir \
    && apk --purge del build-base \
    && rm -rf /var/cache/apk/*

WORKDIR ${APP_DIRECTORY}

COPY requirements.txt ${APP_DIRECTORY}/

RUN pip install --no-cache-dir -r requirements.txt

COPY ./app ${APP_DIRECTORY}/

#RUN chown -R ${USERNAME}:${USERNAME} ${APP_DIRECTORY}

#USER ${USERNAME}

ENV APP_ENV=docker

ENV LISTEN_PORT 5555

EXPOSE 5555

ENTRYPOINT ["python3", "main.py"]
if __name__ == '__main__':
    init_pa()
    app.run(host='0.0.0.0', port=80)
tiangolo commented 6 years ago

I see, you can change and improve several things.


To summarize:

FROM tiangolo/uwsgi-nginx-flask:python3.6-alpine3.7

RUN apk --update --no-cache add build-base \
    && python3 -m pip install psycopg2 --no-cache-dir \
    && apk --purge del build-base \
    && rm -rf /var/cache/apk/*

COPY requirements.txt /app

RUN pip install --no-cache-dir -r requirements.txt

COPY ./app /app

Also, read the QuickStart, it's like 2 paragraphs: https://github.com/tiangolo/uwsgi-nginx-flask-docker#quickstart

And also, if you want to see a full project configured to use PosgreSQL with everything set up (and several more features), check: https://github.com/tiangolo/full-stack

peerchemist commented 6 years ago

Okay but how to get the container properly listen at port other than 80? This will be running behind host nginx and I do not wish to map it to host:80 as main nginx.

tiangolo commented 6 years ago

Read the Docker getting started guide: https://docs.docker.com/get-started/part2/#define-a-container-with-dockerfile

It should help clarify several things.

If you listen on port 80 inside the container doesn't mean that it will be listening on port 80 outside. For it to listen outside you have to map the ports with something like "5555:80", that would make your host listen on port 5555 and send the communication to the port 80 inside the container.