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

Refactor update from base image #16

Merged
merged 7 commits into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Deploy

on:
push:
branches:
- master

jobs:
build:
strategy:
matrix:
image:
- name: latest
python_version: "3.8"
- name: python3.8
python_version: "3.8"
- name: python3.7
python_version: "3.7"
- name: python3.6
python_version: "3.6"
- name: python3.8-alpine3.10
python_version: "3.8"
- name: python3.7-alpine3.8
python_version: "3.7"
- name: python3.6-alpine3.8
python_version: "3.6"
fail-fast: true
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: "3.7"
- name: Install Dependencies
run: python3.7 -m pip install docker pytest
- name: Deploy Image
run: bash scripts/build-push.sh
env:
NAME: ${{ matrix.image.name }}
DOCKERFILE: ${{ matrix.image.dockerfile }}
PYTHON_VERSION: ${{ matrix.image.python_version }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
21 changes: 21 additions & 0 deletions .github/workflows/issue-manager.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Issue Manager

on:
schedule:
- cron: "0 0 * * *"

jobs:
issue-manager:
runs-on: ubuntu-latest
steps:
- uses: tiangolo/issue-manager@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >
{
"answered": {
"users": ["tiangolo"],
"delay": 864000,
"message": "Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues."
}
}
42 changes: 42 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Test

on:
push:
pull_request:
types: [opened, synchronize]

jobs:
build:
strategy:
matrix:
image:
- name: latest
python_version: "3.8"
- name: python3.8
python_version: "3.8"
- name: python3.7
python_version: "3.7"
- name: python3.6
python_version: "3.6"
- name: python3.8-alpine3.10
python_version: "3.8"
- name: python3.7-alpine3.8
python_version: "3.7"
- name: python3.6-alpine3.8
python_version: "3.6"
fail-fast: true
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: "3.7"
- name: Install Dependencies
run: python3.7 -m pip install docker pytest
- name: Test Image
run: bash scripts/test.sh
env:
NAME: ${{ matrix.image.name }}
DOCKERFILE: ${{ matrix.image.dockerfile }}
PYTHON_VERSION: ${{ matrix.image.python_version }}
34 changes: 0 additions & 34 deletions .travis.yml

This file was deleted.

142 changes: 135 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
[![Build Status](https://travis-ci.com/tiangolo/uvicorn-gunicorn-starlette-docker.svg?branch=master)](https://travis-ci.com/tiangolo/uvicorn-gunicorn-starlette-docker)
[![Test](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/workflows/Test/badge.svg)](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/actions?query=workflow%3ATest) [![Deploy](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/workflows/Deploy/badge.svg)](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/actions?query=workflow%3ADeploy)

## Supported tags and respective `Dockerfile` links

* [`python3.7`, `latest` _(Dockerfile)_](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/blob/master/python3.7/Dockerfile)
* [`python3.6` _(Dockerfile)_](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/blob/master/python3.6/Dockerfile)
* [`python3.6-alpine3.8` _(Dockerfile)_](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/blob/master/python3.6-alpine3.8/Dockerfile)
* [`python3.7-alpine3.8` _(Dockerfile)_](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/blob/master/python3.7-alpine3.8/Dockerfile)
* [`python3.8`, `latest` _(Dockerfile)_](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/blob/master/docker-images/python3.8.dockerfile)
* [`python3.7`, _(Dockerfile)_](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/blob/master/docker-images/python3.7.dockerfile)
* [`python3.6` _(Dockerfile)_](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/blob/master/docker-images/python3.6.dockerfile)
* [`python3.8-alpine3.10` _(Dockerfile)_](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/blob/master/docker-images/python3.8-alpine3.10.dockerfile)
* [`python3.7-alpine3.8` _(Dockerfile)_](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/blob/master/docker-images/python3.7-alpine3.8.dockerfile)
* [`python3.6-alpine3.8` _(Dockerfile)_](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker/blob/master/docker-images/python3.6-alpine3.8.dockerfile)

**Note**: Note: There are [tags for each build date](https://hub.docker.com/r/tiangolo/uvicorn-gunicorn-starlette/tags). If you need to "pin" the Docker image version you use, you can select one of those tags. E.g. `tiangolo/uvicorn-gunicorn-starlette:python3.7-2019-10-15`.

# uvicorn-gunicorn-starlette

[**Docker**](https://www.docker.com/) image with [**Uvicorn**](https://www.uvicorn.org/) managed by [**Gunicorn**](https://gunicorn.org/) for high-performance [**Starlette**](https://www.starlette.io/) web applications in **[Python](https://www.python.org/) 3.7** and **3.6** with performance auto-tuning. Optionally with Alpine Linux.
[**Docker**](https://www.docker.com/) image with [**Uvicorn**](https://www.uvicorn.org/) managed by [**Gunicorn**](https://gunicorn.org/) for high-performance [**Starlette**](https://www.starlette.io/) web applications in **[Python](https://www.python.org/) 3.6 and above** with performance auto-tuning. Optionally with Alpine Linux.

**GitHub repo**: [https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker](https://github.com/tiangolo/uvicorn-gunicorn-starlette-docker)

Expand Down Expand Up @@ -229,6 +231,8 @@ You can set it like:
docker run -d -p 80:80 -e GUNICORN_CONF="/app/custom_gunicorn_conf.py" myimage
```

You can use the [config file from the base image](https://github.com/tiangolo/uvicorn-gunicorn-docker/blob/master/docker-images/gunicorn_conf.py) as a starting point for yours.

#### `WORKERS_PER_CORE`

This image will check how many CPU cores are available in the current server running your container.
Expand Down Expand Up @@ -259,6 +263,24 @@ In a server with 8 CPU cores, this would make it start only 4 worker processes.

**Note**: By default, if `WORKERS_PER_CORE` is `1` and the server has only 1 CPU core, instead of starting 1 single worker, it will start 2. This is to avoid bad performance and blocking applications (server application) on small machines (server machine/cloud/etc). This can be overridden using `WEB_CONCURRENCY`.

#### `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.

By default it's not set, meaning that it's unlimited.

You can set it like:

```bash
docker run -d -p 80:80 -e MAX_WORKERS="24" myimage
```

This would make the image start at most 24 workers, independent of how many CPU cores are available in the server.

#### `WEB_CONCURRENCY`

Override the automatic definition of number of workers.
Expand Down Expand Up @@ -343,6 +365,112 @@ You can set it like:
docker run -d -p 80:8080 -e LOG_LEVEL="warning" myimage
```

#### `WORKER_CLASS`

The class to be used by Gunicorn for the workers.

By default, set to `uvicorn.workers.UvicornWorker`.

The fact that it uses Uvicorn is what allows using ASGI frameworks like Starlette, and that is also what provides the maximum performance.

You probably shouldn't change it.

But if for some reason you need to use the alternative Uvicorn worker: `uvicorn.workers.UvicornH11Worker` you can set it with this environment variable.

You can set it like:

```bash
docker run -d -p 80:8080 -e WORKER_CLASS="uvicorn.workers.UvicornH11Worker" myimage
```

#### `TIMEOUT`

Workers silent for more than this many seconds are killed and restarted.

Read more about it in the [Gunicorn docs: timeout](https://docs.gunicorn.org/en/stable/settings.html#timeout).

By default, set to `120`.

Notice that Uvicorn and ASGI frameworks like Starlette are async, not sync. So it's probably safe to have higher timeouts than for sync workers.

You can set it like:

```bash
docker run -d -p 80:8080 -e TIMEOUT="20" myimage
```

#### `KEEP_ALIVE`

The number of seconds to wait for requests on a Keep-Alive connection.

Read more about it in the [Gunicorn docs: keepalive](https://docs.gunicorn.org/en/stable/settings.html#keepalive).

By default, set to `2`.

You can set it like:

```bash
docker run -d -p 80:8080 -e KEEP_ALIVE="20" myimage
```

#### `GRACEFUL_TIMEOUT`

Timeout for graceful workers restart.

Read more about it in the [Gunicorn docs: graceful-timeout](https://docs.gunicorn.org/en/stable/settings.html#graceful-timeout).

By default, set to `120`.

You can set it like:

```bash
docker run -d -p 80:8080 -e GRACEFUL_TIMEOUT="20" myimage
```

#### `ACCESS_LOG`

The access log file to write to.

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

If you want to disable `ACCESS_LOG`, set it to an empty value.

For example, you could disable it with:

```bash
docker run -d -p 80:8080 -e ACCESS_LOG= myimage
```

#### `ERROR_LOG`

The error log file to write to.

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

If you want to disable `ERROR_LOG`, set it to an empty value.

For example, you could disable it with:

```bash
docker run -d -p 80:8080 -e ERROR_LOG= myimage
```

#### `GUNICORN_CMD_ARGS`

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

Read more about it in the [Gunicorn docs: Settings](https://docs.gunicorn.org/en/stable/settings.html#settings).

These settings will have precedence over the other environment variables and any Gunicorn config file.

For example, if you have a custom TLS/SSL certificate that you want to use, you could copy them to the Docker image or mount them in the container, and set [`--keyfile` and `--certfile`](http://docs.gunicorn.org/en/latest/settings.html#ssl) to the location of the files, for example:

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

**Note**: instead of handling TLS/SSL yourself and configuring it in the container, it's recommended to use a "TLS Termination Proxy" like [Traefik](https://docs.traefik.io/). You can read more about it in the [FastAPI documentation about HTTPS](https://fastapi.tiangolo.com/deployment/#https).

#### `PRE_START_PATH`

The path where to find the pre-start script.
Expand Down Expand Up @@ -433,7 +561,7 @@ docker run -d -p 80:80 -v $(pwd):/app myimage /start-reload.sh
* `$(pwd)`: runs `pwd` ("print working directory") and puts it as part of the string.
* `/start-reload.sh`: adding something (like `/start-reload.sh`) at the end of the command, replaces the default "command" with this one. In this case, it replaces the default (`/start.sh`) with the development alternative `/start-reload.sh`.

#### Technical Details
#### Development live reload - Technical Details

As `/start-reload.sh` doesn't run with Gunicorn, any of the configurations you put in a `gunicorn_conf.py` file won't apply.

Expand Down
35 changes: 35 additions & 0 deletions backup.travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
dist: xenial

language: python

python:
- "3.7"

install:
- pip install docker pytest

services:
- docker

env:
- NAME='latest' PYTHON_VERSION='3.8'
- NAME='python3.8' PYTHON_VERSION='3.8'
- NAME='python3.7' PYTHON_VERSION='3.7'
- NAME='python3.6' PYTHON_VERSION='3.6'
- NAME='python3.8-alpine3.10' PYTHON_VERSION='3.8'
- NAME='python3.7-alpine3.8' PYTHON_VERSION='3.7'
- NAME='python3.6-alpine3.8' PYTHON_VERSION='3.6'

script:
- bash scripts/test.sh

jobs:
include:
- script: bash scripts/test.sh
- stage: deploy
script: skip
deploy:
provider: script
script: bash scripts/build-push-all.sh
on:
branch: master
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ FROM tiangolo/uvicorn-gunicorn:python3.6-alpine3.8

LABEL maintainer="Sebastian Ramirez <[email protected]>"

RUN pip --no-cache-dir install starlette
RUN pip install --no-cache-dir starlette

COPY ./app /app
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ FROM tiangolo/uvicorn-gunicorn:python3.6

LABEL maintainer="Sebastian Ramirez <[email protected]>"

RUN pip --no-cache-dir install starlette
RUN pip install --no-cache-dir starlette

COPY ./app /app
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ FROM tiangolo/uvicorn-gunicorn:python3.7-alpine3.8

LABEL maintainer="Sebastian Ramirez <[email protected]>"

RUN pip --no-cache-dir install starlette
RUN pip install --no-cache-dir starlette

COPY ./app /app
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ FROM tiangolo/uvicorn-gunicorn:python3.7

LABEL maintainer="Sebastian Ramirez <[email protected]>"

RUN pip --no-cache-dir install starlette
RUN pip install --no-cache-dir starlette

COPY ./app /app
Loading