Skip to content

Commit

Permalink
Merge pull request #73 from azavea/feature/unicorn-nginx
Browse files Browse the repository at this point in the history
Add support for Gunicorn/Nginx
  • Loading branch information
Steve Lamb committed Nov 13, 2014
2 parents 6febf22 + 807a238 commit a25e53f
Show file tree
Hide file tree
Showing 20 changed files with 170 additions and 48 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ Use the following command to bring up a local development environment:
$ vagrant up
```

After provisioning is complete, you can bring up the Django `runserver` from within the `app` virtual machine with the following commands:
After provisioning is complete, you can login to the application server to execute Django management commands:

```bash
$ vagrant ssh app
vagrant@app:~$ envdir /etc/nyc-trees.d/env /opt/app/manage.py runserver 0.0.0.0:8000
vagrant@app:~$ envdir /etc/nyc-trees.d/env /opt/app/manage.py test
```

**Note**: If you get an error that resembles the following, try logging into the `app` virtual machine again for the group permissions changes to take effect:
Expand Down
4 changes: 2 additions & 2 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
app.vm.synced_folder ".", "/vagrant", disabled: true
app.vm.synced_folder "src/nyc_trees", "/opt/app/"

# Django runserver
app.vm.network "forwarded_port", guest: 8000, host: ENV.fetch("NYC_TREES_PORT_8000", 8000)
# Django via Nginx/Gunicorn
app.vm.network "forwarded_port", guest: 80, host: 8000

app.vm.provision "ansible" do |ansible|
ansible.playbook = "deployment/ansible/app-servers.yml"
Expand Down
2 changes: 2 additions & 0 deletions deployment/ansible/group_vars/development
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
---
django_settings_module: "nyc_trees.settings.development"

redis_bind_address: "0.0.0.0"
redis_host: "33.33.33.30"

Expand Down
2 changes: 2 additions & 0 deletions deployment/ansible/group_vars/test
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
---
django_settings_module: "nyc_trees.settings.test"

redis_bind_address: "0.0.0.0"
redis_host: "33.33.33.30"

Expand Down
5 changes: 5 additions & 0 deletions deployment/ansible/roles/nyc-trees.app/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ app_config:
- { file: "NYC_TREES_DB_PASSWORD", content: "{{ postgresql_password }}" }
- { file: "NYC_TREES_DB_HOST", content: "{{ postgresql_host }}" }
- { file: "NYC_TREES_DB_PORT", content: "{{ postgresql_port }}" }
- { file: "DJANGO_SETTINGS_MODULE", content: "{{ django_settings_module }}" }

app_log: /var/log/nyc-trees-app.log
app_log_rotate_count: 5
app_log_rotate_interval: daily
3 changes: 3 additions & 0 deletions deployment/ansible/roles/nyc-trees.app/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
- name: Restart nyc-trees-app
service: name=nyc-trees-app state=restarted
1 change: 1 addition & 0 deletions deployment/ansible/roles/nyc-trees.app/meta/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ dependencies:
- { role: "azavea.pip" }
- { role: "azavea.postgresql-support" }
- { role: "azavea.daemontools" }
- { role: "azavea.nginx", nginx_delete_default_site: True }
29 changes: 29 additions & 0 deletions deployment/ansible/roles/nyc-trees.app/tasks/configuration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
- name: Create service account for application
user: name=nyc-trees
system=yes
createhome=no
shell=/bin/false
state=present

- name: Add Vagrant user to the nyc-trees group
user: name=vagrant
append=yes
group=nyc-trees
state=present
when: developing_or_testing

- name: Create configuration file directory
file: path={{ app_config_home }}
owner=root
group=nyc-trees
mode=0750
state=directory

- name: Configure application
copy: content={{ item.content }}
dest={{ app_config_home }}/{{ item.file }}
owner=root
group=nyc-trees
mode=0750
with_items: app_config
14 changes: 14 additions & 0 deletions deployment/ansible/roles/nyc-trees.app/tasks/dependencies.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
- name: Install Geospatial libraries
apt: pkg={{ item }} state=present
with_items:
- binutils=2.24-5ubuntu3
- libproj-dev=4.8.0-2ubuntu2
- gdal-bin=1.10.1+dfsg-5ubuntu1

- name: Install application dependencies for development and test
pip: chdir={{ app_home }}/requirements requirements={{ item }}.txt
with_items:
- development
- test
when: developing_or_testing
10 changes: 10 additions & 0 deletions deployment/ansible/roles/nyc-trees.app/tasks/log-rotation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
- name: Touch log file if it does not exist
command: touch {{ app_log }}
creates={{ app_log }}

- name: Set log file permissions
file: path={{ app_log }} owner=nyc-trees group=nyc-trees mode=0644

- name: Configure Gunicorn log rotation
template: src=logrotate-nyc-trees-app.j2 dest=/etc/logrotate.d/nyc-trees-app
46 changes: 4 additions & 42 deletions deployment/ansible/roles/nyc-trees.app/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,43 +1,5 @@
---
- name: Create service account for application
user: name=nyc-trees
system=yes
createhome=no
shell=/bin/false
state=present

- name: Add Vagrant user to the nyc-trees group
user: name=vagrant
append=yes
group=nyc-trees
state=present
when: developing_or_testing

- name: Create configuration file directory
file: path={{ app_config_home }}
owner=root
group=nyc-trees
mode=0750
state=directory

- name: Configure application
copy: content={{ item.content }}
dest={{ app_config_home }}/{{ item.file }}
owner=root
group=nyc-trees
mode=0750
with_items: app_config

- name: Install Geospatial libraries
apt: pkg={{ item }} state=present
with_items:
- binutils=2.24-5ubuntu3
- libproj-dev=4.8.0-2ubuntu2
- gdal-bin=1.10.1+dfsg-5ubuntu1

- name: Install application dependencies for development and test
pip: chdir={{ app_home }}/requirements requirements={{ item }}.txt
with_items:
- development
- test
when: developing_or_testing
- include: configuration.yml
- include: dependencies.yml
- include: reverse-proxy.yml
- include: log-rotation.yml
21 changes: 21 additions & 0 deletions deployment/ansible/roles/nyc-trees.app/tasks/reverse-proxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
- name: Configure gunicorn settings
template: src=gunicorn-nyc-trees.py.j2 dest=/etc/nyc-trees.d/gunicorn.py

- name: Configure service definition
template: src=upstart-nyc-trees-app.conf.j2 dest=/etc/init/nyc-trees-app.conf
notify:
- Restart nyc-trees-app

- name: Configure Nginx site
template: src=nginx-nyc-trees-app.conf.j2
dest=/etc/nginx/sites-available/nyc-trees-app.conf
notify:
- Restart Nginx

- name: Enable Nginx site
file: src=/etc/nginx/sites-available/nyc-trees-app.conf
dest=/etc/nginx/sites-enabled/nyc-trees-app
state=link
notify:
- Restart Nginx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
bind = "127.0.0.1:8000"

{% if developing_or_testing -%}
accesslog = "-"
errorlog = "-"
loglevel = 'debug'
preload_app = False
reload = True
timeout = 1800
workers = 1
{% else %}
accesslog = None
errorlog = "{{ app_log }}"
loglevel = 'info'
preload_app = True
reload = False
timeout = 60
workers = 2 * {{ ansible_processor_count }}
{% endif %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{ app_log }} {
rotate {{ app_log_rotate_count }}
{{ app_log_rotate_interval }}
compress
missingok
notifempty
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
server {
listen *:80;
server_name _;

root {{ app_home }}/collected_static;

log_format logstash_json '{ "@timestamp": "$time_iso8601", '
'"@fields": { '
'"remote_addr": "$remote_addr", '
'"remote_user": "$remote_user", '
'"body_bytes_sent": "$body_bytes_sent", '
'"request_time": "$request_time", '
'"status": "$status", '
'"request": "$request", '
'"request_method": "$request_method", '
'"http_referrer": "$http_referer", '
'"http_user_agent": "$http_user_agent" } }';

access_log /var/log/nginx/nyc-trees-app.access.log logstash_json;

location / {
try_files $uri @gunicorn_proxy;
}

location @gunicorn_proxy {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://127.0.0.1:8000;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description "nyc-trees-app"

start on ({{ "vagrant-mounted" if developing_or_testing else "local-filesystems and net-device-up IFACE!=lo" }})
stop on shutdown

respawn
setuid nyc-trees
chdir {{ app_home }}

exec envdir /etc/nyc-trees.d/env gunicorn --config /etc/nyc-trees.d/gunicorn.py nyc_trees.wsgi
7 changes: 7 additions & 0 deletions scripts/debugserver.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

set -e
set -x

vagrant ssh app -c "sudo service nyc-trees-app stop || /bin/true"
vagrant ssh app -c "cd /opt/app/ && envdir /etc/nyc-trees.d/env gunicorn --config /etc/nyc-trees.d/gunicorn.py nyc_trees.wsgi"
File renamed without changes.
1 change: 1 addition & 0 deletions src/nyc_trees/requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ ipython==2.3.0
psycopg2==2.5.4
Pillow==2.6.1
django-registration-redux==1.1
gunicorn==19.1.1
2 changes: 0 additions & 2 deletions src/nyc_trees/requirements/production.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
-r base.txt

gunicorn==19.1.1

0 comments on commit a25e53f

Please sign in to comment.