From 2936ea4ccc44ccf71f53f5bc6255a2b9af88424b Mon Sep 17 00:00:00 2001 From: Greg Thole Date: Mon, 30 May 2016 14:41:05 -0400 Subject: [PATCH] Add nginx server container --- README.md | 4 +-- docker-compose.yml | 11 ++++++- gedgo-web.conf | 26 ++++++++++++++++ gedgo/views/util.py | 72 +++++++++++++++++++++------------------------ settings.py | 3 +- 5 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 gedgo-web.conf diff --git a/README.md b/README.md index 719a103..f40f83c 100644 --- a/README.md +++ b/README.md @@ -89,14 +89,14 @@ Start up the web server and worker with $ docker-compose up ``` -If you're running a Mac you can go to [http://gedgo.local:8000](http://gedgo.local:8000). Otherwise find out the local ip address of the gedgo docker machine and visit it. For example: +If you're running a Mac you can go to [http://gedgo.local](http://gedgo.local). Otherwise find out the local ip address of the gedgo docker machine and visit it. For example: ```bash $ docker-machine ip gedgo 192.168.99.101 ``` -And you would go to [http://192.168.99.101:8000](http://192.168.99.101:8000). +And you would go to [http://192.168.99.101](http://192.168.99.101). #### Updating Gedcoms To update your gedcom, you can either use the manage.py command, passing it diff --git a/docker-compose.yml b/docker-compose.yml index 48d1b35..c5794cf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,6 @@ avahi: image: 'enernoclabs/avahi:latest' net: 'host' log_driver: 'none' - restart: 'on-failure' db: container_name: 'db' image: 'mysql' @@ -34,6 +33,16 @@ app: links: - 'db' - 'redis' +web: + image: 'nginx' + command: 'nginx -g "daemon off;"' + volumes: + - './gedgo-web.conf:/etc/nginx/conf.d/gedgo-web.conf:ro' + - './files:/src/files:ro' + ports: + - '80:80' + links: + - 'app' worker: container_name: 'gedgo_worker' image: 'gedgo_app' diff --git a/gedgo-web.conf b/gedgo-web.conf new file mode 100644 index 0000000..410c799 --- /dev/null +++ b/gedgo-web.conf @@ -0,0 +1,26 @@ +upstream app_server { + server app:8000 fail_timeout=0; +} + +server { + listen 80; + # listen [::]:80 default ipv6only=on; + server_name gedgo.local default; + sendfile on; + + location / { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_redirect off; + + if (!-f $request_filename) { + proxy_pass http://app_server; + break; + } + } + + location /protected/ { + internal; + alias /src/files/default/; + } +} diff --git a/gedgo/views/util.py b/gedgo/views/util.py index 3edb2f8..4601bf6 100644 --- a/gedgo/views/util.py +++ b/gedgo/views/util.py @@ -1,4 +1,3 @@ -from wsgiref.util import FileWrapper from django.http import HttpResponse, HttpResponseRedirect from django.core.files.storage import default_storage from django.contrib.auth.decorators import login_required @@ -39,36 +38,35 @@ def process_comments(request, noun): Returns a tuple of (form, redirect_response) depending on whether a new comment has been posted or not. """ - if request.POST: - form = CommentForm(request.POST) - if form.is_valid(): - # Store file uploads - file_names = [] - if getattr(settings, 'GEDGO_ALLOW_FILE_UPLOADS', True) is True: - for file_ in request.FILES.getlist('uploads'): - upload_path = 'uploaded/%s/%s/%s' % ( - request.user.username, - request.path.strip('/').replace('gedgo/', ''), - file_.name - ) - default_storage.save(upload_path, file_) - file_names.append(upload_path) - # Email the comment to the site owners. - form.email_comment(request.user, noun, file_names) - messages.success( - request, - 'Your comment has ben sent. Thank you!' - ) - else: - # Shouldn't happen, since there's almost no server-side validation - messages.error( - request, - "We're sorry, your comment was not sent." - ) - return None, redirect(request.path) + if not request.POST: + return CommentForm(), None + + form = CommentForm(request.POST) + if form.is_valid(): + # Store file uploads + file_names = [] + if getattr(settings, 'GEDGO_ALLOW_FILE_UPLOADS', True) is True: + for file_ in request.FILES.getlist('uploads'): + upload_path = 'uploaded/%s/%s/%s' % ( + request.user.username, + request.path.strip('/').replace('gedgo/', ''), + file_.name + ) + default_storage.save(upload_path, file_) + file_names.append(upload_path) + # Email the comment to the site owners. + form.email_comment(request.user, noun, file_names) + messages.success( + request, + 'Your comment has ben sent. Thank you!' + ) else: - form = CommentForm() - return form, None + # Shouldn't happen, since there's almost no server-side validation + messages.error( + request, + "We're sorry, your comment was not sent." + ) + return None, redirect(request.path) def render(request, template, context): @@ -117,14 +115,12 @@ def serve_content(storage, name): if not storage.__class__.__name__ == 'FileSystemStorage': return HttpResponseRedirect(storage.url(name)) - # If behind a real server, use send-file - if settings.GEDGO_SENDFILE_HEADER: - response = HttpResponse() - response[settings.GEDGO_SENDFILE_HEADER] = default_storage.path(name) - # Otherwise, serve it ourselves, which should only happen in DEBUG mode - else: - wrapper = FileWrapper(storage.open(name)) - response = HttpResponse(wrapper) + # Otherwise we use sendfile + response = HttpResponse() + response[settings.GEDGO_SENDFILE_HEADER] = '%s%s' % ( + settings.GEDGO_SENDFILE_PREFIX, + name + ) # Set various file headers and return base = path.basename(name) diff --git a/settings.py b/settings.py index d29fb3f..c5e114e 100644 --- a/settings.py +++ b/settings.py @@ -99,7 +99,8 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' SERVER_EMAIL = ['noreply@example.com'] -GEDGO_SENDFILE_HEADER = None +GEDGO_SENDFILE_HEADER = 'X-Accel-Redirect' +GEDGO_SENDFILE_PREFIX = '/protected/' GEDGO_SITE_TITLE = 'My Genealogy Site' GEDGO_REDIS_SERVER = 'redis' GEDGO_RESEARCH_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'