Compare commits

..

1 Commits

14 changed files with 215 additions and 93 deletions

View File

@ -1,4 +1,4 @@
Ansible uwsgi-nginx-supervisor
Ansible nginx-uwsgi-supervisor
==============================
An Ansible role to setup and manage a UWSGI app via supervisor, and served up on a NGINX web server. The goal of this
@ -10,32 +10,29 @@ Requirements
- aptitude or python-apt (required by apt tasks)
- python > 2.5 (required by ini_file tasks)
- Ansible >= 2.0
This role is designed to work against a modern Ubuntu system. (Tested on Ubuntu 14.04 and 16.04) It should
This role is designed to work against a modern Ubuntu system. (Tested on Ubuntu 13.10 and 14.04) It should
theoretically work on older versions of Ubuntu or Debian based systems.
This role relies on the [nginx-supervisor base role](https://bitbucket.org/dorianpula/ansible-nginx-supervisor).
Example Playbook
----------------
The simplest way to include the role in your playbook is to copy the below configuration. Remember to modify the
uwsgi_app_name, uwsgi_app_nginx_hostname and uwsgi_app_executable parameters especially.
app_name, app_nginx_hostname and app_uwsgi_executable parameters especially.
- hosts: servers
sudo: yes
roles:
- { role: nginx-uwsgi-supervisor,
uwsgi_app_name: app,
uwsgi_app_nginx_hostname: app.domain.net,
uwsgi_app_port: 8080,
uwsgi_app_executable: "app.build:make_wsgi_app()" }
app_name: app,
app_nginx_hostname: app.domain.net,
app_uwsgi_port: 8080,
app_uwsgi_executable: "app.build:make_wsgi_app()" }
The role itself is very configurable. For exaple, if you prefer the location of the web application to refer to the
domain name rather than the default root path, then simply override the app_root_path variable with something like:
uwsgi_app_rooth_path: "{{ uwsgi_web_root_path }}/{{ uwsgi_app_nginx_hostname }}"
app_rooth_path: "{{ web_root_path }}/{{ app_nginx_hostname }}"
A comprehensive example can be found in the [Ansible rookeries role]
(https://bitbucket.org/dorianpula/ansible-rookeries) that uses this role as a base to deploy a Flask-based webapp.
@ -48,54 +45,54 @@ into sections and described below:
### App Settings
- uwsgi_app_name:
- app_name:
- The name of WSGI app to manage via this role.
- Used as a prefix through out the role.
- uwsgi_app_root_path:
- app_root_path:
- The path to the root folder of the app.
- Default: uwsgi_web_root_path/uwsgi_app_name_webapp
- Default: web_root_path/app_name_webapp
### NGINX
- uwsgi_app_nginx_hostname:
- app_nginx_hostname:
- The DNS hostname that the application serves.
- Default: localhost
- uwsgi_app_static_path:
- app_nginx_app_static:
- The path to the static elements of the site (templates, CSS, images, etc.)
- Default: uwsgi_app_root_path/uwsgi_app_name/static/
- Default: app_root_path/app_name/static/
### UWSGI
- uwsgi_app_port:
- app_uwsgi_port:
- The port number that the WSGI runs on and accepts requests forwarded from NGINX.
- Default: 8001
- uwsgi_app_executable:
- app_uwsgi_executable:
- The method executed by UWSGI to create a WSGI running app. Usually a WSGI factory method or module in the app.
- Default: app:make_wsgi_app()
- uwsgi_app_envs:
- app_uwsgi_envs:
- (Optional) A dictionary of environment variables to pass into an app.
- Default: empty dictionary
### Virtual Environments
On occasion it is necessary to change the setup of the virtual environments on a system.
**NEW** - On occassion it is necessary to change the setup of the virtual environments on a system.
- uwsgi_virtualenv_root_path:
- virtualenv_root_path:
- Path to where the virtual environments are installed
- Default: uwsgi_web_root_path/virtualenvs
- uwsgi_app_venv:
- Default: web_root_path/virtualenvs
- app_venv:
- Path to the application's virtualenv.
- Default: uwsgi_virtualenv_root_path/uwsgi_app_name
- Default: virtualenv_root_path/app_name
### General Web
These variables are not as crucial to configure. They do give good defaults for configuring the system in a consistent,
POSIX/LSB-friendly and user-friendly manner. See the section on Default File Structure for more details.
- uwsgi_web_root_path:
- web_root_path:
- The root of the entire web app structure include configuration and logging.
- Default: /srv/www
- uwsgi_web_server_group:
- web_server_group:
- The user group responsible for starting, stopping and managing the web and app servers on the target machine.
- Default: www-data
@ -113,7 +110,7 @@ By default the role will organize files in the following directory structure:
│   ├── nginx -> /var/log/nginx
│   ├── supervisor -> /var/log/supervisor
│   └── uwsgi
├── uwsgi_app_webapp
├── app_webapp
│   ├── requirements.txt
│   └── app
└── virtualenvs
@ -126,19 +123,25 @@ Internal Variables
The following variables are part of the internals of the role. However if you really want to, you can tweak them to
work with your setup:
- uwsgi_virtualenv_root_path:
- web_user:
- The non-root user who is allowed to control web + app servers on the target machine.
- Default: current user
- virtualenv_root_path:
- The common root directory of Python virtual environments associated with running the
UWSGI app + server.
- Default: /srv/www/virtualenvs/
- uwsgi_venv:
- The virtual environment where UWSGI is installed.
- Default: uwsgi_virtualenv_root/uwsgi
- uwsgi_app_venv:
- Default: virtualenv_root/uwsgi
- app_venv:
- The virtual environment where the dependencies of the WSGI app is installed.
- Default: uwsgi_virtualenv_root/uwsgi_app_name
- uwsgi_app_nginx_conf:
- Default: virtualenv_root/app_name
- nginx_app_conf:
- The filename of the NGINX configuration for the app.
- Default: uwsgi_app_name_nginx.conf
- Default: app_name_uwsgi_nginx.conf
- supervisor_app_config:
- The filename of the supervisor configuration for the app.
- Default: app_name_supervisor.conf
- uwsgi_config_path:
- The path to the UWSGI configurations.
- Default: /srv/www/config/uwsgi
@ -169,8 +172,7 @@ This role is a spin-off of the technology developed for the [Rookeries project]
Repositories
------------
- Main: https://bitbucket.org/dorianpula/ansible-uwsgi-nginx-supervisor
- Main: https://bitbucket.org/dorianpula/ansible-nginx-uwsgi-supervisor
- All development and issues are worked on this repo.
- Clone: https://github.com/dorianpula/ansible-nginx-uwsgi-supervisor
- A clone to work with Ansible Galaxy and Github
- nginx-supervisor base role: https://bitbucket.org/dorianpula/ansible-nginx-supervisor

View File

@ -2,21 +2,21 @@
# defaults file for ansible-nginx-uwsgi-supervisor
# Web root paths + app name + home
uwsgi_web_root_path: /srv/www
uwsgi_web_server_group: www-data
web_root_path: /srv/www
web_server_group: www-data
uwsgi_app_name: app
uwsgi_app_root_path: "{{ uwsgi_web_root_path }}/{{ uwsgi_app_name }}_webapp"
app_name: app
app_root_path: "{{ web_root_path }}/{{ app_name }}_webapp"
# NGINX
uwsgi_app_hostname: localhost
uwsgi_app_static_path: "{{ uwsgi_app_root_path }}/{{ uwsgi_app_name }}/static/"
app_nginx_hostname: localhost
app_nginx_static_path: "{{ app_root_path }}/{{ app_name }}/static/"
# UWSGI
uwsgi_app_port: 8000
uwsgi_app_executable: "app:make_wsgi_app()"
uwsgi_app_envs: {}
app_uwsgi_port: 8000
app_uwsgi_executable: "app:make_wsgi_app()"
app_uwsgi_envs: {}
# Virtualenvs
uwsgi_virtualenv_root_path: "{{ uwsgi_web_root_path }}/virtualenvs"
uwsgi_app_venv: "{{ uwsgi_virtualenv_root_path }}/{{ uwsgi_app_name }}"
virtualenv_root_path: "{{ web_root_path }}/virtualenvs"
app_venv: "{{ virtualenv_root_path }}/{{ app_name }}"

View File

@ -3,3 +3,19 @@
- name: restart uwsgi app
supervisorctl: name={{ uwsgi_app_service_name }} state=restarted config=/etc/supervisor/supervisord.conf
sudo: yes
- name: start supervisord
service: name=supervisor state=started
sudo: yes
- name: start supervisord
service: name=supervisor state=started
sudo: yes
- name: restart supervisord
service: name=supervisor state=restarted
sudo: yes
- name: restart nginx
service: name=nginx state=restarted
sudo: yes

View File

@ -4,23 +4,13 @@ galaxy_info:
description: An elegant NGINX, UWSGI and supervisor Ansible role
company: Amber Penguin Software
license: BSD
min_ansible_version: 2.0
min_ansible_version: 1.6
platforms:
- name: Ubuntu
versions:
- saucy
- trusty
- xenial
categories:
- development
- web
dependencies:
# - role: "git+https://bitbucket.org/dorianpula/ansible-nginx-supervisor,,nginx-supervisor"
- role: "nginx-supervisor"
nsbase_app_name: "{{ uwsgi_app_name }}"
nsbase_app_root_path: "{{ uwsgi_app_root_path }}"
nsbase_app_hostname: "{{ uwsgi_app_hostname }}"
nsbase_app_service_name: "{{ uwsgi_app_service_name }}"
nsbase_app_service_command: "{{ uwsgi_app_supervisor_command }}"
nsbase_app_service_stop_signal: QUIT
nsbase_app_nginx_config: "{{ uwsgi_app_nginx_config }}"
nsbase_app_static_path: "{{ uwsgi_app_static_path }}"
dependencies: []

View File

@ -1,4 +1,7 @@
---
# tasks file for ansible-nginx-uwsgi-supervisor
- include: python.yaml
- include: nginx.yaml
- include: supervisor.yaml
- include: web_data_folders.yaml
- include: uwsgi.yaml

37
tasks/nginx.yaml Normal file
View File

@ -0,0 +1,37 @@
---
- name: install nginx webserver
apt: pkg=nginx-full state=present
sudo: yes
- name: configure nginx
template: src=nginx/app_uwsgi_nginx.conf dest=/etc/nginx/sites-available/{{ nginx_app_config }}
sudo: yes
- name: link to enable nginx configuration
file: state=link
src=/etc/nginx/sites-available/{{ nginx_app_config }}
path=/etc/nginx/sites-enabled/{{ nginx_app_config }}
sudo: yes
- name: disable default configuration
file: state=absent path=/etc/nginx/sites-enabled/default
sudo: yes
notify: restart nginx
- name: set nginx directories permissions
file: path={{ item }} state=directory
group={{ web_server_group }} mode=0755
with_items:
- /var/log/nginx
- /etc/nginx
- /etc/nginx/sites-available
- /etc/nginx/sites-enabled
sudo: yes
- name: set nginx logs permissions
file: path=/var/log/nginx/{{ item }} state=file
owner={{ web_server_group }} group={{ web_server_group }} mode=0644
with_items:
- access.log
- error.log
sudo: yes

25
tasks/supervisor.yaml Normal file
View File

@ -0,0 +1,25 @@
---
- name: install supervisord
apt: name=supervisor state=present
sudo: yes
- name: set permissions on supervisor config and log directories
file: path={{ item }} group={{ web_server_group }} state=directory mode=0755
with_items:
- /etc/supervisor
- /etc/supervisor/conf.d
- /var/log/supervisor
sudo: yes
- name: modify supervisor configuration
ini_file: dest=/etc/supervisor/supervisord.conf section=unix_http_server
option={{ item.key }} value={{ item.value }}
with_dict:
chmod: "0770"
chown: root:{{ web_server_group }}
sudo: yes
- name: upload supervisor configuration to web server home
template: src=supervisor/app_supervisor.conf dest=/etc/supervisor/conf.d/{{ supervisor_app_config }}
sudo: yes
notify: start supervisord

View File

@ -4,17 +4,5 @@
sudo: yes
- name: configure app on uwsgi server
template: src=app_uwsgi.ini dest={{ uwsgi_config_path }}/{{ uwsgi_app_ini }}
template: src=uwsgi/app_uwsgi.ini dest={{ uwsgi_config_path }}/{{ uwsgi_app_ini }}
sudo: yes
notify: restart uwsgi app
- name: configure nginx app with uwsgi specific block.
blockinfile:
dest: /etc/nginx/sites-available/{{ uwsgi_app_nginx_config }}
insertafter: "# Include your setup to connect to the webapp setup here."
marker: "# -- {mark} UWSGI App config for {{ uwsgi_app_name }} --"
block: |
include uwsgi_params;
uwsgi_pass 127.0.0.1:{{ uwsgi_app_port }};
sudo: yes
notify: restart nginx

View File

@ -0,0 +1,31 @@
---
- name: setup webapp deployment folder with the correct permissions
file: path={{ web_root_path }} state=directory
owner={{ web_server_group }} group={{ web_server_group }} mode=0774
sudo: yes
- name: setup webapp deployment configuration + log folders with the correct permissions
file: path={{ web_root_path }}/{{ item }} state=directory
owner={{ web_server_group }} group={{ web_server_group }} mode=0774
with_items:
- config
- config/uwsgi
- logs
- virtualenvs
sudo: yes
- name: link remote folders with webapp home folder
file: state=link
path={{ web_root_path }}/{{ item.value }}
src={{ item.key }}
owner={{ web_server_group }} group={{ web_server_group }} mode=0774
with_dict:
/etc/nginx: config/nginx
/etc/supervisor: config/supervisor
/var/log/nginx: logs/nginx
/var/log/supervisor: logs/supervisor
sudo: yes
- name: add user to webserver group
user: name={{ web_user }} append=yes groups={{ web_server_group }}
sudo: yes

View File

@ -1,12 +0,0 @@
[uwsgi]
socket = :{{ uwsgi_app_port }}
master = true
processes = 8
chdir = {{ uwsgi_app_root_path }}
virtualenv = {{ uwsgi_app_venv }}
module = {{ uwsgi_app_executable }}
{% for env_var, env_value in uwsgi_app_envs.items() %}
env = {{ env_var | upper }}={{ env_value }}
{% endfor %}

View File

@ -0,0 +1,18 @@
server {
server_name {{ app_nginx_hostname }};
access_log {{ web_root_path }}/logs/nginx/{{ app_name }}-access.log;
error_log {{ web_root_path }}/logs/nginx/{{ app_name }}-error.log info;
location /static/ {
alias {{ app_nginx_static_path }};
}
location / {
try_files $uri @yourapplication;
}
location @yourapplication {
include uwsgi_params;
uwsgi_pass 127.0.0.1:{{ app_uwsgi_port }};
}
}

View File

@ -0,0 +1,9 @@
; UWSGI for {{ app_name }}
[program:{{ uwsgi_app_service_name }}]
user={{ web_server_group }}
command={{ uwsgi_venv }}/bin/uwsgi --ini {{ uwsgi_config_path }}/{{ uwsgi_app_ini }}
stopsignal=QUIT
stdout_logfile = {{ web_root_path }}/logs/supervisor/{{ app_name }}-application.log
stdout_logfile_backups = 5
stderr_logfile = {{ web_root_path }}/logs/supervisor/{{ app_name }}-error.log
stderr_logfile_backups = 5

View File

@ -0,0 +1,12 @@
[uwsgi]
socket = :{{ app_uwsgi_port }}
master = true
processes = 8
chdir = {{ app_root_path }}
virtualenv = {{ app_venv }}
module = {{ app_uwsgi_executable }}
{% for env_var, env_value in app_uwsgi_envs.items() %}
env = {{ env_var | upper }}={{ env_value }}
{% endfor %}

View File

@ -1,14 +1,17 @@
---
# vars file for ansible-nginx-uwsgi-supervisor
# User
web_user: "{{ ansible_env.SUDO_USER }}"
# NGINX
uwsgi_app_nginx_config: "{{ uwsgi_app_name }}_uwsgi_nginx.conf"
nginx_app_config: "{{ app_name }}_uwsgi_nginx.conf"
# Supervisor
supervisor_app_config: "{{ app_name }}_supervisor.conf"
# UWSGI
uwsgi_venv: "{{ uwsgi_virtualenv_root_path }}/uwsgi"
uwsgi_config_path: "{{ uwsgi_web_root_path }}/config/uwsgi"
uwsgi_app_ini: "{{ uwsgi_app_name }}_uwsgi.ini"
uwsgi_app_service_name: "{{ uwsgi_app_name }}_uwsgi"
# TODO: Document extracted variables
uwsgi_app_supervisor_command: "{{ uwsgi_venv }}/bin/uwsgi --ini {{ uwsgi_config_path }}/{{ uwsgi_app_ini }}"
uwsgi_venv: "{{ virtualenv_root_path }}/uwsgi"
uwsgi_config_path: "{{ web_root_path }}/config/uwsgi"
uwsgi_app_ini: "{{ app_name }}_uwsgi.ini"
uwsgi_app_service_name: "{{ app_name }}_uwsgi"