Added Docker Compose support for production (#183)

* Added Docker Compose support for production

* Added rate limiting to nginx
This commit is contained in:
Alexandre Boucey 2016-07-07 14:23:59 +02:00 committed by Paul Hallett
parent c4b2d52682
commit d771c293df
8 changed files with 197 additions and 1 deletions

View file

@ -138,6 +138,42 @@ Run the container on host port 8000
docker run -d -p 8000:8000 pokeapi
```
## Docker Compose
There is also a multi-container setup, managed by [Docker Compose](https://docs.docker.com/compose/). This setup allow you to deploy a production-like environment, with separate containers for each services.
Create data volumes for Redis and Postgres
```
docker volume create --name=redis_data
docker volume create --name=pg_data
```
Start the process using
```
docker-compose up
```
You can specify the ```-d``` switch to start in detached mode.
This will bind port 80 and 443. Unfortunately, unlike the ```docker``` command, there is no command line arguments to specify ports. If you want to change them, edit the ```docker-compose.yml``` file.
After that, start the migration process
```
docker-compose exec app python manage.py migrate
```
And then, import the data using the shell
```
docker-compose exec app python manage.py shell
```
You can use the ```build_all()``` method, or individuals data building functions (See _V2 Database setup_)
```
from data.v2.build import build_all
build_all()
```
For the moment, this setup doesn't allow you to use the ```scale``` command.
## Contributing
All contributions are welcome: bug fixes, data contributions, recommendations.

View file

@ -0,0 +1,16 @@
FROM python:2.7
ENV PYTHONUNBUFFERED 1
ENV DJANGO_SETTINGS_MODULE 'config.docker-compose'
ENV PYTHONHASHSEED 'random'
RUN mkdir /code
WORKDIR /code
VOLUME /code
ADD requirements.txt /code/
RUN pip install --no-cache-dir -r requirements.txt
ADD . /code/
CMD gunicorn config.wsgi:application -c gunicorn.py.ini
EXPOSE 8000

View file

@ -0,0 +1,2 @@
FROM nginx:alpine
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf

View file

@ -0,0 +1,68 @@
worker_processes 1;
events {
worker_connections 1024;
accept_mutex off;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 5;
upstream pokeapi_upstream {
# 'app' is the Django container name in Docker
# DO NOT EDIT IT ALONE or it'll break docker-compose
server app:8000 fail_timeout=0;
}
limit_req_zone $binary_remote_addr zone=api:10m rate=2r/s;
server {
listen 80 deferred;
server_name _;
client_body_timeout 5s;
client_header_timeout 5s;
root /code;
location /media/ {
root /code;
autoindex off;
}
location /static/ {
alias /code/assets/;
autoindex off;
}
location /api/ {
limit_req zone=api burst=10;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://pokeapi_upstream;
}
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://pokeapi_upstream;
}
}
}

27
config/docker-compose.py Normal file
View file

@ -0,0 +1,27 @@
# Docker settings
from .settings import * # NOQA
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'pokeapi',
'USER': 'ash',
'PASSWORD': 'pokemon',
'HOST': 'db',
'PORT': 5432,
}
}
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://cache:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
DEBUG = False
TASTYPIE_FULL_DEBUG = False

43
docker-compose.yml Normal file
View file

@ -0,0 +1,43 @@
version: '2'
services:
cache:
image: redis:alpine
volumes:
- redis_data:/data
db:
image: postgres
environment:
POSTGRES_PASSWORD: 'pokemon'
POSTGRES_USER: 'ash'
POSTGRES_DB: 'pokeapi'
volumes:
- pg_data:/var/lib/postgresql/data
app:
build:
context: .
dockerfile: ./Resources/docker/app/Dockerfile
volumes:
- /code
links:
- db
- cache
web:
build:
context: ./Resources
dockerfile: ./docker/web/Dockerfile
ports:
- "80:80"
- "443:443"
volumes_from:
- app:ro
links:
- app
volumes:
pg_data:
external: true
redis_data:
external: true

4
gunicorn.py.ini Normal file
View file

@ -0,0 +1,4 @@
from multiprocessing import cpu_count
bind = '0.0.0.0:8000'
workers = cpu_count() * 2 + 1

View file

@ -13,7 +13,7 @@ django-tastypie==0.12.1
django-markdown-deux==1.0.5
djangorestframework>=3.1.0
drf-ujson==1.2.0
gunicorn==0.17.0
gunicorn==19.4.5
markdown2==2.3.0
mimeparse==0.1.3
pilkit==1.1.12