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

Add gunicorn to web server #9

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
FROM python:3.5.1

# System packages
RUN apt-key update && apt-get update
#Supervisor for running application in production
RUN apt-get install supervisor -y
# Clean up package manager
RUN apt-get autoremove -y
RUN rm -rvf /var/cache/apt

# Environment variables
ENV PYTHONUNBUFFERED 1

# Directories
RUN mkdir /code
WORKDIR /code
ADD . /code/
RUN pip install -r requirements.txt

# Default entrypoint
ENTRYPOINT "/code/scripts/run_prod.sh"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Sometimes the postgres image takes a while to load on first run and the Django s

The code in the repository is also mounted as a volume in the task-service container. This means you can edit code on your host machine, using your favorite editor, and the django server will automatically restart to reflect the code changes.

The server should start up at http://localhost:8080/, see the [API docs](https://github.com/cognoma/task-service/blob/master/doc/api.md).
The server should start up at http://localhost:8001/, see the [API docs](https://github.com/cognoma/task-service/blob/master/doc/api.md).

## Running tests locally

Expand Down
29 changes: 29 additions & 0 deletions config/prod/gunicorn.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# For full details, see:
# http://docs.gunicorn.org/en/stable/settings.html

# Address
bind = '0.0.0.0:8001'

# Worker configuration
# http://docs.gunicorn.org/en/stable/design.html#async-workers
worker_class = 'eventlet'

# Rule of thumb for workers is (2 * ncpus) + 1
# http://docs.gunicorn.org/en/stable/design.html#how-many-workers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gunicorn also supports supplying a Python file for configuration, here's an example from one of my projects. One benefit of this is you can dynamically compute the worker count when Gunicorn starts regardless of server, by using Python's multiprocessing.cpu_count

workers = 2
threads = 8
worker_connections = 10

# Restart of worker after certain number of requests to avoid memory leaks
max_requests = 1000
max_requests_jitter = 100

# Timeout settings
graceful_timeout = 300
timeout = 300

# Logging
loglevel = 'info'

# Daemonization
daemon = False
19 changes: 19 additions & 0 deletions config/prod/supervisord.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[supervisord]
; Don't want supervisord to be daemonised, as otherwise when running under
; Docker it will assume that the command has completed, whereas we want
; supervisord to stay up as long as the application is running
nodaemon=true


[program:core_service]
command=/usr/local/bin/gunicorn task_service.wsgi:application -c /code/config/prod/gunicorn.conf
directory=/code
; User account with minimal privileges
user=nobody
Copy link
Member

@dcgoss dcgoss Apr 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the nobody user need to be created in the Dockerfile (something like: RUN useradd nobody), or is that not needed?

numprocs=1
autostart=true
autorestart=true
; Redirect all logging to Docker stdout
redirect_stderr=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
image: postgres
task:
build: .
command: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8001"
entrypoint: ./scripts/run_dev.sh
volumes:
- .:/code
ports:
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ pyasn1==0.1.9
pycparser==2.16
PyJWT==1.4.2
six==1.10.0
gunicorn==19.6.0
eventlet==0.20.1
4 changes: 4 additions & 0 deletions scripts/run_dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash -x

manage.py migrate -v3 --no-input
Copy link
Member

@dcgoss dcgoss Apr 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does -v3 do? Also, this command must be prefaced with python, like line 4

python manage.py runserver 0.0.0.0:8001
5 changes: 5 additions & 0 deletions scripts/run_prod.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash -x

# Application is configured to run under Supervisord, which in turn monitors
# the Gunicorn web server
supervisord -c /code/config/prod/supervisord.conf
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an idea, we could add a -n here to make supervisord run in the foreground since it is a container. Might make it easier to debug startup problems.