Giter VIP home page Giter VIP logo

tiangolo / uvicorn-gunicorn-starlette-docker Goto Github PK

View Code? Open in Web Editor NEW
164.0 164.0 12.0 141 KB

Docker image with Uvicorn managed by Gunicorn for high-performance Starlette web applications in Python with performance auto-tuning.

License: MIT License

Dockerfile 24.02% Python 68.11% Shell 7.87%
asgi async debian docker docker-image dockerfile framework gunicorn http python starlette uvicorn uvicorn-gunicorn web websockets

uvicorn-gunicorn-starlette-docker's Introduction

Hey! I'm @tiangolo (Sebastián Ramírez) 👋

I'm a software developer from Colombia. 🇨🇴

I currently live in Berlin, Germany. 🇩🇪

I have been building APIs and tools for Machine Learning and data systems, in Latin America, the Middle East, and now Europe, with different teams and organizations. 🌎

I created FastAPI, Typer and a bunch of other open source tools. 🚀

I like to build things with Deep Learning/Machine Learning, distributed systems, SQL and NoSQL databases, Docker, Python, TypeScript (and JavaScript), modern backend APIs, and modern frontend frameworks. 🤖

I'm currently dedicating a high percentage of my time to FastAPI, Typer, and my other open source projects. At the same time, I'm also helping a limited number of teams and organizations as an external consultant. If you would like to have my help with your team and product, feel free to contact me. 🤓

If my open source projects are useful for your product/company you can also sponsor my work on them. ☕

You can find me on:

uvicorn-gunicorn-starlette-docker's People

Contributors

alejsdev avatar dependabot[bot] avatar tiangolo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

uvicorn-gunicorn-starlette-docker's Issues

Add image for python 3.9

It's been a while since python3.9 has been released so it would be nice if the docker container was updated to use python3.9 and the latest starlette and uvicorn libraries

Access logging not working as expected

Hi There

I recently started looking at this image after using your nginx flask image on a number of projects. One thing we have noticed is that the access logs, as defined in the gunicorn config file, dont ever seem to be written anywhere for some reason.

Initially thought it might be something we are doing, but it seems that even with the quickstart example that stdout access logs are never sent/generated. Is this an issue with this image or perhaps gunicorn conf?

Here is the debug output from the container as it starts

config: /app/gunicorn_conf.py
bind: ['0.0.0.0:80']
backlog: 2048
workers: 12
worker_class: uvicorn.workers.UvicornWorker
threads: 1
worker_connections: 1000
max_requests: 0
max_requests_jitter: 0
timeout: 30
graceful_timeout: 30
keepalive: 120
limit_request_line: 4094
limit_request_fields: 100
limit_request_field_size: 8190
reload: False
reload_engine: auto
reload_extra_files: []
spew: False
check_config: False
preload_app: False
sendfile: None
reuse_port: False
chdir: /app
daemon: False
raw_env: []
pidfile: None
worker_tmp_dir: None
user: 0
group: 0
umask: 0
initgroups: False
tmp_upload_dir: None
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
forwarded_allow_ips: ['127.0.0.1']
accesslog: -
disable_redirect_access_to_syslog: True
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
errorlog: -
loglevel: debug
capture_output: True
logger_class: gunicorn.glogging.Logger
logconfig: None
logconfig_dict: {}
syslog_addr: udp://localhost:514
syslog: False
syslog_prefix: None
syslog_facility: user
enable_stdio_inheritance: False
statsd_host: None
statsd_prefix: 
proc_name: None
default_proc_name: main:app
pythonpath: None
paste: None
on_starting: <function OnStarting.on_starting at 0x7eff33dc4620>
on_reload: <function OnReload.on_reload at 0x7eff33dc4730>
when_ready: <function WhenReady.when_ready at 0x7eff33dc4840>
pre_fork: <function Prefork.pre_fork at 0x7eff33dc4950>
post_fork: <function Postfork.post_fork at 0x7eff33dc4a60>
post_worker_init: <function PostWorkerInit.post_worker_init at 0x7eff33dc4b70>
worker_int: <function WorkerInt.worker_int at 0x7eff33dc4c80>
worker_abort: <function WorkerAbort.worker_abort at 0x7eff33dc4d90>
pre_exec: <function PreExec.pre_exec at 0x7eff33dc4ea0>
pre_request: <function PreRequest.pre_request at 0x7eff33b37048>
post_request: <function PostRequest.post_request at 0x7eff33b370d0>
child_exit: <function ChildExit.child_exit at 0x7eff33b371e0>
worker_exit: <function WorkerExit.worker_exit at 0x7eff33b372f0>
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7eff33b37400>
on_exit: <function OnExit.on_exit at 0x7eff33b37510>
proxy_protocol: False
proxy_allow_ips: ['127.0.0.1']
keyfile: None
certfile: None
ssl_version: 2
cert_reqs: 0
ca_certs: None
suppress_ragged_eofs: True
do_handshake_on_connect: False
ciphers: TLSv1

And here is an example of the log output from docker showing that example request access logs arnt being generated:

[2019-01-27 13:24:34 +0000] [8] [INFO] Starting gunicorn 19.9.0
[2019-01-27 13:24:34 +0000] [8] [DEBUG] Arbiter booted
[2019-01-27 13:24:34 +0000] [8] [INFO] Listening at: http://0.0.0.0:80 (8)
[2019-01-27 13:24:34 +0000] [8] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2019-01-27 13:24:34 +0000] [11] [INFO] Booting worker with pid: 11
[2019-01-27 13:24:34 +0000] [12] [INFO] Booting worker with pid: 12
[2019-01-27 13:24:34 +0000] [13] [INFO] Booting worker with pid: 13
[2019-01-27 13:24:34 +0000] [14] [INFO] Booting worker with pid: 14
[2019-01-27 13:24:34 +0000] [15] [INFO] Booting worker with pid: 15
[2019-01-27 13:24:34 +0000] [16] [INFO] Booting worker with pid: 16
[2019-01-27 13:24:34 +0000] [17] [INFO] Booting worker with pid: 17
[2019-01-27 13:24:34 +0000] [18] [INFO] Booting worker with pid: 18
[2019-01-27 13:24:34 +0000] [19] [INFO] Booting worker with pid: 19
[2019-01-27 13:24:34 +0000] [20] [INFO] Booting worker with pid: 20
[2019-01-27 13:24:35 +0000] [21] [INFO] Booting worker with pid: 21
[2019-01-27 13:24:35 +0000] [22] [INFO] Booting worker with pid: 22
[2019-01-27 13:24:35 +0000] [8] [DEBUG] 12 workers
[2019-01-27 13:24:40 +0000] [22] [DEBUG] ('172.17.0.1', 59002) - Connected
[2019-01-27 13:24:40 +0000] [22] [INFO] ('172.17.0.1', 59002) - "GET / HTTP/1.1" 200
[2019-01-27 13:24:40 +0000] [22] [DEBUG] ('172.17.0.1', 59002) - Disconnected
[2019-01-27 13:24:41 +0000] [22] [DEBUG] ('172.17.0.1', 59004) - Connected
[2019-01-27 13:24:41 +0000] [22] [INFO] ('172.17.0.1', 59004) - "GET / HTTP/1.1" 200
[2019-01-27 13:24:41 +0000] [22] [DEBUG] ('172.17.0.1', 59004) - Disconnected

Have tried changing settings including setting the access log to a file but to this also ends up empty, and changing the value of settings like 'capture_output' and 'disable_redirect_access_to_syslog' but with no success.

Any help much appreciated.

Problem with StaticFiles ...

If I include this in my main.py

app.mount('/static', StaticFiles(directory='static')) 

Where static is a child folder of app locally, the following fails:

docker run -d --name myimage_c -p 3000:5000 -e PORT="5000" myimage

Even more interesting ... if I remove that line all together, static assents (images, javascript, css) get served from my /static folder just fine.

Any advice on what I should be doing to correctly setup my static files location with the docker image?

Thanks

Timeout loading large model

Thanks for the Docker images.

I'm loading a large machine learning model when my app starts up.

When I run uvicorn from the command line, no problems:
uvicorn main:app

If I create a Docker image and then try to run it, I get timeout errors:
[2019-12-12 21:51:10 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:999)
[2019-12-12 21:51:10 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:1000)
[2019-12-12 21:51:10 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:1006)
[2019-12-12 21:51:10 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:1012)
[2019-12-12 21:51:10 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:1013)
[2019-12-12 21:51:10 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:1014)
[2019-12-12 21:51:10 +0000] [1066] [INFO] Booting worker with pid: 1066
[2019-12-12 21:51:10 +0000] [1072] [INFO] Booting worker with pid: 1072
[2019-12-12 21:51:10 +0000] [1073] [INFO] Booting worker with pid: 1073
[2019-12-12 21:51:10 +0000] [1074] [INFO] Booting worker with pid: 1074
[2019-12-12 21:51:11 +0000] [1075] [INFO] Booting worker with pid: 1075
[2019-12-12 21:51:11 +0000] [1096] [INFO] Booting worker with pid: 1096

Is there a way to change the --timeout parameter for gunicorn?

Thanks,
jJ

What is the role of each component in the proposed stack ?

My question may be a little bit out of the topic, but this project looks interesting. I would like to understand it a little better.

I've been looking for some answers and clarifications about the integration among uvicorn/gunicorn/starlette and what is the role that each one play in the stack to delivery a high performance system.

May you please help on that, explaining what is the role of each component and how they help each other on a high performance stack ?

Best Regards.
Kleyson Rios.

Startup carries out a heavy import over again in each worker

I'm trying to use this docker image to provide a REST service that does some calculations based on word embeddings, so I have a module file analysis.py (beside main.py) that loads the rather large embeddings data file. Obviously I only want that in memory once, so I was trying to take advantage of way Python normally imports a module only once.

But when I run the docker image, it takes up a massive amount of memory because it is loading the data several times (once in each worker). Is there a way to prevent this?

Application doesnt start

Hi,

I suspect I am doing something stupid but I have tried both the sample app and converted one of my own apps to use Starlette and get the same result.

The docker image builds fine and seems to run but just sits with the message [Info] Waiting for Application startup

I am then unable to access my application

What am I doing wrong?!

Thanks

Nic

Image/pyenv issue

I am building an application, starlette backend with vue frontend. I have utilized this to get the backend up and running with Docker. All the configurations, as far as I can tell, are proper. I have successfully built the image (traefik, app, db), even using docker-compose build --no-cache to ensure it was building with my most up to date requirements.txt and dev.txt.

When I use docker-compose up, the db instance runs perfectly and the app does as well, except for an error that appears after it says the app is up and running on a localhost. It throws an error saying
File "./app/main.py", in line 6, in <module> from starlette.middleware.sessions import SessionMiddleware File "/usr/local/lib/python3.8/site-packages/starlette/middleware/sessions.py", line 5, in <module> import itsdangerous ModuleNotFoundError: No module named 'itsdangerous'

I have ensured that the path is in pythonpath (in a .env), checked that itsdangerous is in the requirements.txt file which is ran during docker-compose build. I am working in a pyenv virtualenv, however it is checking local packages for this (I imagine it is because Docker works locally for this instance (not extremely familiar with Docker at its core).

Do you know any other possible way I could resolve this issue?

Wrong URL for the dockerhub repository

Hello,

In the README.md, the link to the dockerhub image is broken; the correct URL should be

https://hub.docker.com/r/tiangolo/uvicorn-gunicorn-starlette

Instead of

https://hub.docker.com/r/tiangolo/uvicorn-starlette-gunicorn

(gunicorn and starlette are inverted)

FastText Client

When I try to use fasttext with this container i get the following error:

ImportError: libc.musl-x86_64.so.1: cannot open shared object file: No such file or directory

Dockerfile

FROM alpine:3.8 AS builder

ENV LANG C.UTF-8

# This is our runtime
RUN apk add --no-cache python3
RUN apk add --no-cache git
RUN ln -sf /usr/bin/pip3 /usr/bin/pip
RUN ln -sf /usr/bin/python3 /usr/bin/python

# This is dev runtime
RUN apk add --no-cache --virtual .build-deps build-base python3-dev
# Using latest versions, but pinning them
RUN pip install --upgrade pip==19.0.1
RUN pip install --upgrade setuptools==40.4.1
RUN pip install --upgrade pipenv

# This is where pip will install to
ENV PYROOT /pyroot
# A convenience to have console_scripts in PATH
ENV PATH $PYROOT/bin:$PATH
ENV PYTHONUSERBASE $PYROOT

# THE MAIN COURSE #

WORKDIR /build

# Install dependencies
COPY Pipfile Pipfile.lock ./
RUN PIP_USER=1 PIP_IGNORE_INSTALLED=1 pipenv install --system --deploy

#####################
## Production image #
#####################
FROM tiangolo/uvicorn-gunicorn-starlette:python3.6

ENV PYROOT /pyroot
ENV PATH $PYROOT/bin:$PATH
ENV PYTHONPATH $PYROOT/lib/python3.6:$PATH
# This is crucial for pkg_resources to work
ENV PYTHONUSERBASE $PYROOT

# Finally, copy artifacts
COPY --from=builder $PYROOT/lib/ $PYROOT/lib/
RUN mkdir -p /build/src/fasttext/python
COPY --from=builder /build/src/fasttext/python /build/src/fasttext/python

COPY ./app /app

Is it safe to use this image for production?

I have to setup the server for the production environment and I'm using the FastAPI framework. The documentation of the framework suggests to use this docker image because it's ready and customizabile. So what I'll do is to expose my application using Gunicorn using the Uvicorn workers.

Is it safe? Because I was reading some articles and they suggest to put NGINX as a Reverse Proxy in front of Gunicorn. In this case, the request is received by NGINX and then it decides where to route it. I can't understand the differences. Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.