Skip to content

Commit e21432f

Browse files
author
Craig
committed
updated Readme and added variables
1 parent f250736 commit e21432f

File tree

5 files changed

+204
-22
lines changed

5 files changed

+204
-22
lines changed

README.md

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,152 @@
11
# Docker Python Waitress
22

3-
Docker container to run a WSGI Python app using Waitress.
3+
Docker container to run a WSGI Python app using
4+
[Waitress](https://docs.pylonsproject.org/projects/waitress/en/stable/index.html). Images support python 3.6+ and are
5+
based on the official python-slim containers.
6+
7+
[Pull from Docker Hub](https://hub.docker.com/r/tecktron/python-waitress/)
8+
9+
[View on GitHub](https://github.com/Tecktron/docker-python-waitress)
10+
11+
12+
## How to use
13+
14+
* You don't need to clone the GitHub repo. You can use this image as a base image for other images, using this in your `Dockerfile`:
15+
16+
```Dockerfile
17+
FROM tecktron/python-waitress:latest
18+
19+
COPY ./ /app
20+
```
21+
22+
It will expect a file at `/app/app/wsgi.py`.
23+
24+
Or otherwise a file at `/app/wsgi.py`.
25+
26+
And will expect it to contain a variable `application` with your "WSGI" application.
27+
28+
Then you can build your image from the directory that has your `Dockerfile`, e.g:
29+
30+
```bash
31+
docker build -t myimage ./
32+
```
33+
34+
## Options
35+
36+
All options can be set using environment variables. These can be passed either in a wrapper dockerfile, passing in a .env file or passing them with the
37+
-e flag to the docker call.
38+
39+
### Prestart Script
40+
If you need to run any startup commands before waitress runs (an example might be running migrations) you can override the `prestart.sh` script. This script should live within the `/app` directory in the container. The image will automatically detect and run it before starting waitress.
41+
42+
43+
### Variables
44+
45+
#### `MODULE_NAME`
46+
47+
The Python "module" (file) to be imported by Gunicorn, this module would contain the actual application in a variable.
48+
49+
By default:
50+
51+
* `app.wsgi` if there's a file `/app/app/main.py` or
52+
* `wsgi` if there's a file `/app/wsgi.py`
53+
54+
For example, if your main file was at `/app/custom_app/custom_script.py`, you could set it like:
55+
56+
```bash
57+
docker run -d -p 80:80 -e MODULE_NAME="custom_app.custom_script" myimage
58+
```
59+
60+
#### `VARIABLE_NAME`
61+
62+
The variable inside of the Python module that contains the WSGI application.
63+
64+
By default:
65+
66+
* `application`
67+
68+
For example, if your main Python file has something like:
69+
70+
```Python
71+
from flask import Flask
72+
api = Flask(__name__)
73+
74+
@api.route("/")
75+
def hello():
76+
return "Hello World from Flask"
77+
```
78+
79+
In this case `api` would be the variable with the "WSGI application". You could set it like:
80+
81+
```bash
82+
docker run -d -p 80:80 -e VARIABLE_NAME="api" myimage
83+
```
84+
85+
#### `APP_MODULE`
86+
87+
The string with the Python module and the variable name passed to Gunicorn.
88+
89+
By default, set based on the variables `MODULE_NAME` and `VARIABLE_NAME`:
90+
91+
* `app.wsgi:application` or
92+
* `wsgi:application`
93+
94+
You can set it like:
95+
96+
```bash
97+
docker run -d -p 80:80 -e APP_MODULE="custom_app.custom_script:api" myimage
98+
```
99+
100+
### Waitress Options
101+
102+
#### Host and Port
103+
By default, Waitress has been setup to server on all hostnames on port 80 using both IPv4 and IPv6. This translates to `--listen:*:80`. This works for most applications using the basic setups listed above.
104+
105+
You may have different needs so you can adjust and manipulate this by passing in environment variable to adjust the settings.
106+
107+
There are 2 options for doing this.
108+
1. Pass a comma separated list of `host:port,host:port` to the `WAITRESS_LISTEN` param
109+
2. Pass the host and port separately as `WAITRESS_HOST` and/or `WAITRESS_PORT`. If port is left out, it will default to 80.
110+
111+
The `WAITRESS_LISTEN` param takes precedence over `WAITRESS_HOST`/`WAITRESS_PORT` options, meaning if you include all 3, host and port settings will be ignored.
112+
113+
##### Some examples
114+
115+
To set waitress to use port 8080, sent the `WAITRESS_LISTEN` param like `-e WAITRESS_LISTEN=*:8080`
116+
117+
If you want only IPv4, you could use advanced param listed in the section below, but you could also use `-e WAITRESS_HOST=0.0.0.0 -e WAITRESS_PORT=80`
118+
119+
120+
#### Advanced Options
121+
122+
Many of the
123+
[supported options by waitress-serve](https://docs.pylonsproject.org/projects/waitress/en/stable/runner.html#invocation)
124+
are also supported by passing in environment variables. These params are only included in the call if they are included
125+
in the environment. The supported options are:
126+
127+
| Environment Variable | Waitress Param |
128+
|:---------------------------------|:---------------------------------|
129+
| WAITRESS_EXPOSE_TRACEBACKS | --expose-tracebacks |
130+
| WAITRESS_NO_EXPOSE_TRACEBACKS | --no-expose-tracebacks |
131+
| WAITRESS_NO_IPV6 | --no-ipv6 |
132+
| WAITRESS_NO_IPV4 | --no-ipv4 |
133+
| WAITRESS_THREADS | --threads=`$VAL` |
134+
| WAITRESS_IDENT | --ident=`$VAL` |
135+
| WAITRESS_OUTBUF_OVERFLOW | --outbuf_high_watermark=`$VAL` |
136+
| WAITRESS_INBUF_OVERFLOW | --inbuf_overflow=`$VAL` |
137+
| WAITRESS_CONNECTION_LIMIT | --connection_limit=`$VAL` |
138+
| WAITRESS_MAX_REQUEST_HEADER_SIZE | --max_request_header_size=`$VAL` |
139+
| WAITRESS_MAX_REQUEST_BODY_SIZE | --max_request_body_size=`$VAL` |
140+
| WAITRESS_ASYNCORE_LOOP_TIMEOUT | --asyncore_loop_timeout=`$VAL` |
141+
| WAITRESS_ASYNCORE_USE_POLL | --asyncore_use_poll=`$VAL` |
142+
143+
Where `$VAL` is the value passed into the environment.
144+
For example to pass in 5 threads, use `-e WAITRESS_THREADS=5`
145+
146+
For those without any value, simply pass a 1.
147+
For example to turn off IPv6, use `-e WAITRESS_NO_IPV6=1`
148+
149+
# Credits
150+
This dockerfile setup is based on https://github.com/tiangolo/meinheld-gunicorn-docker
151+
152+
Waitress is one of the Pylons projects: https://pylonsproject.org
File renamed without changes.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import sys
22

33

4-
def app(env, start_response):
4+
def application(env, start_response):
55
version = f"{sys.version_info.major}.{sys.version_info.minor}"
66
start_response("200 OK", [("Content-Type", "text/plain")])
7-
message = f"Waitress serving up Python {version} in a Docker container"
7+
message = f"Waitress serving up WSGI Python {version} in a Docker container"
88
return [message.encode("utf-8")]

scripts/entrypoint.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
set -e
44

5-
if [ -f /app/app/main.py ]; then
6-
DEFAULT_MODULE_NAME=app.main
7-
elif [ -f /app/main.py ]; then
8-
DEFAULT_MODULE_NAME=main
5+
if [ -f /app/app/wsgi.py ]; then
6+
DEFAULT_MODULE_NAME=wsgi
7+
elif [ -f /app/wsgi.py ]; then
8+
DEFAULT_MODULE_NAME=app.wsgi
99
fi
1010
MODULE_NAME=${MODULE_NAME:-$DEFAULT_MODULE_NAME}
11-
VARIABLE_NAME=${VARIABLE_NAME:-app}
11+
VARIABLE_NAME=${VARIABLE_NAME:-application}
1212
export APP_MODULE=${APP_MODULE:-"$MODULE_NAME:$VARIABLE_NAME"}
1313

1414
exec "$@"

scripts/run.sh

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,41 +12,74 @@ else
1212
echo "There is no script $PRE_START_PATH"
1313
fi
1414

15-
params="--listen=*:80"
15+
params=""
1616

17-
if [[ -v WAITRESS_THREADS ]]; then
17+
if [[ -v $WAITRESS_LISTEN ]]; then
18+
listeners=$(echo "$WAITRESS_LISTEN" | tr "," "\n")
19+
for listener in $listeners
20+
do
21+
if [[ -z $params ]]; then
22+
params="--listen=$listener"
23+
else
24+
params=" $params --listen=$listener"
25+
fi
26+
done
27+
else
28+
if [[ -v $WAITRESS_HOST ]]; then
29+
params="--host=$WAITRESS_HOST"
30+
if [[ -v $WAITRESS_PORT ]]; then
31+
params=" $params --port=$WAITRESS_PORT"
32+
else
33+
params=" $params --port=80"
34+
fi
35+
else
36+
params="--listen=*:80"
37+
fi
38+
fi
39+
40+
if [[ -v $WAITRESS_NO_IPV6 ]]; then
41+
params=" $params --no-ipv6"
42+
fi
43+
if [[ -v $WAITRESS_NO_IPV4 ]]; then
44+
params=" $params --no-ipv4"
45+
fi
46+
if [[ -v $WAITRESS_EXPOSE_TRACEBACKS ]]; then
47+
params=" $params --expose-tracebacks"
48+
fi
49+
if [[ -v $WAITRESS_NO_EXPOSE_TRACEBACKS ]]; then
50+
params=" $params --no-expose-tracebacks"
51+
fi
52+
if [[ -v $WAITRESS_THREADS ]]; then
1853
params=" $params --thread=$WAITRESS_THREADS"
1954
fi
20-
if [[ -v WAITRESS_IDENT ]]; then
55+
if [[ -v $WAITRESS_IDENT ]]; then
2156
params=" $params --ident=$WAITRESS_IDENT"
2257
fi
23-
if [[ -v WAITRESS_OUTBUF_OVERFLOW ]]; then
58+
if [[ -v $WAITRESS_OUTBUF_OVERFLOW ]]; then
2459
params=" $params --outbuf_overflow=$WAITRESS_OUTBUF_OVERFLOW"
2560
fi
26-
if [[ -v WAITRESS_OUTBUF_HIGH_WATERMARK ]]; then
61+
if [[ -v $WAITRESS_OUTBUF_HIGH_WATERMARK ]]; then
2762
params=" $params --outbuf_high_watermark=$WAITRESS_OUTBUF_HIGH_WATERMARK"
2863
fi
29-
if [[ -v WAITRESS_INBUF_OVERFLOW ]]; then
64+
if [[ -v $WAITRESS_INBUF_OVERFLOW ]]; then
3065
params=" $params --inbuf_overflow=$WAITRESS_INBUF_OVERFLOW"
3166
fi
32-
if [[ -v WAITRESS_CONNECTION_LIMIT ]]; then
67+
if [[ -v $WAITRESS_CONNECTION_LIMIT ]]; then
3368
params=" $params --connection_limit=$WAITRESS_CONNECTION_LIMIT"
3469
fi
35-
if [[ -v WAITRESS_MAX_REQUEST_HEADER_SIZE ]]; then
70+
if [[ -v $WAITRESS_MAX_REQUEST_HEADER_SIZE ]]; then
3671
params=" $params --max_request_header_size=$WAITRESS_MAX_REQUEST_HEADER_SIZE"
3772
fi
38-
if [[ -v WAITRESS_MAX_REQUEST_BODY_SIZE ]]; then
73+
if [[ -v $WAITRESS_MAX_REQUEST_BODY_SIZE ]]; then
3974
params=" $params --max_request_body_size=$WAITRESS_MAX_REQUEST_BODY_SIZE"
4075
fi
41-
if [[ -v WAITRESS_EXPOSE_TRACEBACKS ]]; then
42-
params=" $params --expose_tracebacks=$WAITRESS_EXPOSE_TRACEBACKS"
43-
fi
44-
if [[ -v WAITRESS_ASYNCORE_LOOP_TIMEOUT ]]; then
76+
if [[ -v $WAITRESS_ASYNCORE_LOOP_TIMEOUT ]]; then
4577
params=" $params --asyncore_loop_timeout=$WAITRESS_ASYNCORE_LOOP_TIMEOUT"
4678
fi
47-
if [[ -v WAITRESS_ASYNCORE_USE_POLL ]]; then
79+
if [[ -v $WAITRESS_ASYNCORE_USE_POLL ]]; then
4880
params=" $params --asyncore_use_poll=$WAITRESS_ASYNCORE_USE_POLL"
4981
fi
5082

5183
# Start Waitress
84+
echo "waitress-serve $params $APP_MODULE"
5285
exec waitress-serve $params $APP_MODULE

0 commit comments

Comments
 (0)