Sign inSign up

ai975/gunicorn

By ai975

•Updated almost 3 years ago

Uvicorn and Gunicorn for high-performance web apps in Python 3.11 and Python 3.12 with auto-tuning.

Image
0

290

ai975/gunicorn repository overview

⁠Description

This Repository is modified from https://github.com/tiangolo/uvicorn-gunicorn-docker⁠

⁠uvicorn-gunicorn

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

Uvicorn: https://www.uvicorn.org/⁠

Gunicorn: https://gunicorn.org/⁠

⁠How to use

⁠Create your own Docker image

you could have a Dockerfile like this:

# Dockerfile
FROM ai975/gunicorn:python3.12-slim

COPY ./app /ai975_server

RUN pip install --no-cache-dir --upgrade -r /ai975_server/requirements.txt

Then you can build your image from the directory that has your Dockerfile, e.g:

docker build -t repo/image:tag .

Run a container based on your image:

docker run -d --name ai975-server -p 9080:80 repo/image:tag

⁠Using Poetry

Here's a small example of one of the ways you could install your dependencies making sure you have a pinned version for each package.

Let's say you have a project managed with Poetry, so, you have your package dependencies in a file pyproject.toml. And possibly a file poetry.lock.

Then you could have a Dockerfile using Docker multi-stage building with:

FROM python:3.12 as requirements-stage

WORKDIR /tmp

RUN pip install poetry

COPY ./pyproject.toml ./poetry.lock* /tmp/

RUN poetry export -f requirements.txt --output requirements.txt --without-hashes

FROM ai975/gunicorn:python3.12-slim

COPY --from=requirements-stage /tmp/requirements.txt /ai975_server/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /ai975_server/requirements.txt

COPY ./app /ai975_server

⁠Advanced usage

⁠Environment variables

These are the environment variables that you can set in the container to configure it and their default values:

⁠APP_MODULE

The string with the Python module and the variable name passed to Gunicorn.

By default:

  • main if there's a file /ai975_server/main.py or
  • custom_app.custom_main if there's a file /ai975_server/custom_app/custom_main.py

You can set it like:

docker run -d -p 80:80 -e APP_MODULE="custom_app.custom_main:app"  repo/image:tag

For example, if your main Python file has something like:

from fastapi import FastAPI

api = FastAPI()


@api.get("/")
def read_root():
    return {"Hello": "World"}

In this case api would be the variable with the FastAPI application. You could set it like:

You can set it like:

docker run -d -p 80:80 -e APP_MODULE="custom_app.custom_main:api"  repo/image:tag
⁠GUNICORN_CONF

The path to a Gunicorn Python configuration file.

By default:

  • /app/gunicorn_conf.py if it exists
  • /app/app/gunicorn_conf.py if it exists
  • /gunicorn_conf.py (the included default)
⁠MAX_WORKERS

Set the maximum number of workers to use.

You can use it to let the image compute the number of workers automatically but making sure it's limited to a maximum.

This can be useful, for example, if each worker uses a database connection and your database has a maximum limit of open connections.

⁠BIND

The actual host and port passed to Gunicorn.

So, if you didn't change anything, it will be set by default to:

  • 0.0.0.0:80
⁠LOG_LEVEL

The log level for Gunicorn.

One of:

  • debug
  • info
  • warning
  • error
  • critical

By default, set to info.

⁠ACCESS_LOG_FILE

The access log file to write to.

By default "-", which means stdout (print in the Docker logs).

⁠ERROR_LOG

The error log file to write to.

By default "-", which means stderr (print in the Docker logs).

⁠GUNICORN_CMD_ARGS

Any additional command line settings for Gunicorn can be passed in the GUNICORN_CMD_ARGS environment variable.

docker run -d -p 80:8080 -e GUNICORN_CMD_ARGS="--keyfile=/secrets/key.pem --certfile=/secrets/cert.pem" -e PORT=443 myimage
⁠PRE_START_PATH

The path where to find the pre-start script.

By default, set to /app/prestart.sh.

⁠Custom Gunicorn configuration file

The image includes a default Gunicorn Python config file at /gunicorn_conf.py.

It uses the environment variables declared above to set all the configurations.

You can override it by including a file in:

  • /app/gunicorn_conf.py
  • /app/app/gunicorn_conf.py
  • /gunicorn_conf.py
⁠Custom /app/prestart.sh

If you need to run anything before starting the app, you can add a file prestart.sh to the directory /app. The image will automatically detect and run it before starting everything.

For example, if you want to add Alembic SQL migrations (with SQLALchemy), you could create a ./app/prestart.sh file in your code directory (that will be copied by your Dockerfile) with:

#! /usr/bin/env bash

# Let the DB start
sleep 10;
# Run migrations
alembic upgrade head

and it would wait 10 seconds to give the database some time to start and then run that alembic command.

If you need to run a Python script before starting the app, you could make the /app/prestart.sh file run your Python script, with something like:

#! /usr/bin/env bash

# Run custom Python script before starting
python /app/my_custom_prestart_script.py

You can customize the location of the prestart script with the environment variable PRE_START_PATH described above.

⁠Docker Compose

version: '3.8'

services:
  ai975-server:
    container_name: ai975-server
    image: ai975/gunicorn:python3.12-slim
    restart: unless-stopped
    ports:
      - "8880:80"
    environment:
      TZ: ${TZ:-"Asia/Shanghai"}
      MAX_WORKERS: 4
      WORKERS: 2
      PYTHONPATH: "/local_app:/app"
      BIND: "0.0.0.0:80"      
      LOG_LEVEL: "info"
      ACCESS_LOG_FILE: "/app/access.log"
      ERROR_LOG_FILE: "/app/error.log"
      LOG_FORMAT: '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'      
      APP_MODULE: "main:app"
      # GUNICORN_CONF: "/gunicorn_conf.py"
      # PRE_START_PATH: "/prestart.sh"
    volumes:
      # 容器默认工程放置目录
      - /data/work/ai975_projects/ai975_server:/ai975_server

Tag summary

Content type

Image

Digest

sha256:9c63bb04d…

Size

149.7 MB

Last updated

almost 3 years ago

docker pull ai975/gunicorn:py3.12-slim-2023-11-24