Skip to content

Commit

Permalink
✨ Add Python 3.8 (#83)
Browse files Browse the repository at this point in the history
* ⬆️ Upgrade Alpine Nginx installation

* 🔥 Remove older Alpine versions

* ✨ Add new Alpine latest 3.11 with latest Python 3.8

* ✨ Add new Python 3.8

* 👷 Add new Python 3.8 versions to CI, remove deprecated ones

* 📝 Update README with references to latest Python 3.8

* 🐛 Fix CI version for Python 3.8

* 🔧 Update test script to pass pytest vars

* 🐛 Fix removing new default Nginx config for Alpine

* ✅ Fix latest tag, point to Python 3.8
  • Loading branch information
tiangolo authored May 9, 2020
1 parent cafcb5d commit c1e6eb2
Show file tree
Hide file tree
Showing 14 changed files with 168 additions and 527 deletions.
18 changes: 5 additions & 13 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,17 @@ jobs:
matrix:
image:
- name: latest
python_version: "3.7"
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: python2.7
python_version: "2.7"
- name: python3.6-alpine3.9
python_version: "3.6"
- name: python3.6-alpine3.8
python_version: "3.6"
- name: python3.6-alpine3.7
python_version: "3.6"
- name: python2.7-alpine3.9
python_version: "2.7"
- name: python2.7-alpine3.8
python_version: "2.7"
- name: python2.7-alpine3.7
python_version: "2.7"
- name: python3.8-alpine
python_version: "3.8"
fail-fast: true
runs-on: ubuntu-18.04
steps:
Expand Down
18 changes: 5 additions & 13 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,17 @@ jobs:
matrix:
image:
- name: latest
python_version: "3.7"
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: python2.7
python_version: "2.7"
- name: python3.6-alpine3.9
python_version: "3.6"
- name: python3.6-alpine3.8
python_version: "3.6"
- name: python3.6-alpine3.7
python_version: "3.6"
- name: python2.7-alpine3.9
python_version: "2.7"
- name: python2.7-alpine3.8
python_version: "2.7"
- name: python2.7-alpine3.7
python_version: "2.7"
- name: python3.8-alpine
python_version: "3.8"
fail-fast: true
runs-on: ubuntu-18.04
steps:
Expand Down
111 changes: 51 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,14 @@

## Supported tags and respective `Dockerfile` links

* [`python3.7`, `latest` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python3.7.dockerfile)
* [`python3.8`, `latest` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python3.8.dockerfile)
* [`python3.7`, _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python3.7.dockerfile)
* [`python3.6` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python3.6.dockerfile)
* [`python2.7` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python2.7.dockerfile)
* [`python3.6-alpine3.9` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python3.6-alpine3.9.dockerfile)
* [`python3.6-alpine3.8` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python3.6-alpine3.8.dockerfile)
* [`python3.6-alpine3.7` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python3.6-alpine3.7.dockerfile)
* [`python2.7-alpine3.9` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python2.7-alpine3.9.dockerfile)
* [`python2.7-alpine3.8` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python2.7-alpine3.8.dockerfile)
* [`python2.7-alpine3.7` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python2.7-alpine3.7.dockerfile)
* [`python3.8-alpine` _(Dockerfile)_](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/docker-images/python3.8-alpine.dockerfile)

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

## Python 3.7 not supported in in Alpine

As uWSGI has not been released with Python 3.7 support for [Alpine 3.7](https://pkgs.alpinelinux.org/package/v3.7/main/x86/uwsgi-python3), [Alpine 3.8](https://pkgs.alpinelinux.org/package/v3.8/main/x86/uwsgi-python3), and [Alpine 3.9](https://pkgs.alpinelinux.org/package/v3.9/main/x86/uwsgi-python3), it is still not supported.

It doesn't depend on this image but on uWSGI releases for Alpine.

# uwsgi-nginx

**Docker** image with **uWSGI** and **Nginx** for web applications in **Python 3.6** and above, and **Python 2.7** (as **Flask**) in a single container. Optionally with Alpine Linux.
Expand Down Expand Up @@ -65,7 +55,7 @@ If you need to use an older WSGI-based framework like Flask or Django (instead o
* You shouldn't have to clone the GitHub repo. You should use it as a base image for other images, using this in your `Dockerfile`:

```Dockerfile
FROM tiangolo/uwsgi-nginx:python3.7
FROM tiangolo/uwsgi-nginx:python3.8

# Your Dockerfile code...
```
Expand All @@ -82,12 +72,12 @@ If you are building a **Flask** web application you should use instead [**tiango

### Custom app directory

If you need to use a directory for your app different than `/app`, you can override the uWSGI config file path with an environment variable `UWSGI_INI`, and put your custom `uwsgi.ini` file there.
If you need to use a directory for your app different than `/app`, you can override the uWSGI config file path with an environment variable `UWSGI_INI`, and put your custom `uwsgi.ini` file there.

For example, if you needed to have your application directory in `/application` instead of `/app`, your `Dockerfile` would look like:

```Dockerfile
FROM tiangolo/uwsgi-nginx:python3.7
FROM tiangolo/uwsgi-nginx:python3.8

ENV UWSGI_INI /application/uwsgi.ini

Expand Down Expand Up @@ -119,7 +109,7 @@ Have in mind that `UWSGI_CHEAPER` must be lower than `UWSGI_PROCESSES`.
So, if, for example, you need to start with 4 processes and grow to a maximum of 64, your `Dockerfile` could look like:

```Dockerfile
FROM tiangolo/uwsgi-nginx:python3.7
FROM tiangolo/uwsgi-nginx:python3.8

ENV UWSGI_CHEAPER 4
ENV UWSGI_PROCESSES 64
Expand All @@ -138,7 +128,7 @@ For example, if you wanted to set the maximum upload file size to 1 MB (the defa
So, your `Dockerfile` would look something like:

```Dockerfile
FROM tiangolo/uwsgi-nginx:python3.7
FROM tiangolo/uwsgi-nginx:python3.8

ENV NGINX_MAX_UPLOAD 1m

Expand All @@ -156,7 +146,7 @@ You might also need to create the respective `EXPOSE` Docker instruction.
You can do that in your `Dockerfile`, it would look something like:

```Dockerfile
FROM tiangolo/uwsgi-nginx:python3.7
FROM tiangolo/uwsgi-nginx:python3.8

ENV LISTEN_PORT 8080

Expand Down Expand Up @@ -210,7 +200,7 @@ or you can set it to the keyword `auto` and it will try to autodetect the number
For example, using `auto`, your Dockerfile could look like:

```Dockerfile
FROM tiangolo/uwsgi-nginx:python3.7
FROM tiangolo/uwsgi-nginx:python3.8

ENV NGINX_WORKER_PROCESSES auto

Expand Down Expand Up @@ -265,6 +255,46 @@ include /etc/nginx/conf.d/*.conf;

If you want to add a custom `/app/nginx.conf` file but don't know where to start from, you can use [the `nginx.conf` used for the tests](https://github.com/tiangolo/uwsgi-nginx-docker/blob/master/tests/test_02_app/custom_nginx_app/app/nginx.conf) and customize it or modify it further.

## Technical details

The combination of uWSGI with Nginx is a [common way to deploy Python web applications](http://flask.pocoo.org/docs/1.0/deploying/uwsgi/).

Roughly:

* **Nginx** is a web server, it takes care of the HTTP connections and also can serve static files directly and more efficiently.

* **uWSGI** is an application server, that's what runs your Python code and it talks with Nginx.

* **Your Python code** has the actual web application, and is run by uWSGI.

This image takes advantage of already slim and optimized existing Docker images (based on Debian as [recommended by Docker](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)) and implements Docker best practices.

It uses the official Python Docker image, installs uWSGI and on top of that, with the least amount of modifications, adds the official Nginx image (as of 2016-02-14).

And it controls all these processes with Supervisord.

---

There's the rule of thumb that you should have "one process per container".

That helps, for example, isolating an app and its database in different containers.

But if you want to have a "micro-services" approach you may want to [have more than one process in one container](https://valdhaus.co/writings/docker-misconceptions/) if they are all related to the same "service", and you may want to include your Flask code, uWSGI and Nginx in the same container (and maybe run another container with your database).

That's the approach taken in this image.

---

This image has a default sample "Hello World" app in the container's `/app` directory using the example in the [uWSGI documentation](http://uwsgi-docs.readthedocs.org/en/latest/WSGIquickstart.html).

You probably want to override it or delete it in your project.

It is there in case you run this image by itself and not as a base image for your own `Dockerfile`, so that you get a sample app without errors.

## Tests

All the image tags, configurations, environment variables and application options are tested.

## Release Notes

<!--
Expand Down Expand Up @@ -292,6 +322,7 @@ In the official Python image, there's a Stretch version only for Python 3.6. So,
* Debian Stretch (before upgrading to Buster).
* Python 3.5.
* Alpine 3.7, 3.8, 3.9 (before upgrading to Alpine 3.11).
* Alpine in older versions of Python, 2.7 and 3.6 (Before upgrading to Python 3.8).
* If you need any of those, make sure to use a tag for the build date `2020-05-04`.
* Refactor build set up:
* Re-use code and configs.
Expand Down Expand Up @@ -359,46 +390,6 @@ In the official Python image, there's a Stretch version only for Python 3.6. So,

* 2016-04-05: Nginx and uWSGI logs are now redirected to stdout, allowing to use `docker logs`.

## Technical details

The combination of uWSGI with Nginx is a [common way to deploy Python web applications](http://flask.pocoo.org/docs/1.0/deploying/uwsgi/).

Roughly:

* **Nginx** is a web server, it takes care of the HTTP connections and also can serve static files directly and more efficiently.

* **uWSGI** is an application server, that's what runs your Python code and it talks with Nginx.

* **Your Python code** has the actual web application, and is run by uWSGI.

This image takes advantage of already slim and optimized existing Docker images (based on Debian as [recommended by Docker](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)) and implements Docker best practices.

It uses the official Python Docker image, installs uWSGI and on top of that, with the least amount of modifications, adds the official Nginx image (as of 2016-02-14).

And it controls all these processes with Supervisord.

---

There's the rule of thumb that you should have "one process per container".

That helps, for example, isolating an app and its database in different containers.

But if you want to have a "micro-services" approach you may want to [have more than one process in one container](https://valdhaus.co/writings/docker-misconceptions/) if they are all related to the same "service", and you may want to include your Flask code, uWSGI and Nginx in the same container (and maybe run another container with your database).

That's the approach taken in this image.

---

This image has a default sample "Hello World" app in the container's `/app` directory using the example in the [uWSGI documentation](http://uwsgi-docs.readthedocs.org/en/latest/WSGIquickstart.html).

You probably want to override it or delete it in your project.

It is there in case you run this image by itself and not as a base image for your own `Dockerfile`, so that you get a sample app without errors.

## Tests

All the image tags, configurations, environment variables and application options are tested.

## License

This project is licensed under the terms of the Apache license.
3 changes: 3 additions & 0 deletions docker-images/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ else

# Generate Nginx config for maximum upload file size
printf "client_max_body_size $USE_NGINX_MAX_UPLOAD;\n" > /etc/nginx/conf.d/upload.conf

# Remove default Nginx config from Alpine
printf "" > /etc/nginx/conf.d/default.conf
fi

# For Alpine:
Expand Down
Loading

0 comments on commit c1e6eb2

Please sign in to comment.