Automation for nginx and uWSGI Emperor setup. Based on my pyweb tutorial and Ansible.
Version: 1.4 — changelog
The support list matches the tutorial:
- Ubuntu 16.04 LTS or newer
- Debian 8 (jessie) or newer
- Fedora 24 or newer (with SELinux enabled and disabled)
- CentOS 7 (with SELinux enabled and disabled)
- Arch Linux
Other operating systems are unsupported, because of packaging and default configuration differences.
Standard Ansible Playbooks procedure. Install Ansible, edit the applicable configuration in group_vars
, put hostnames in hosts
(the first line is [nginx-uwsgi]
and the following lines are hostnames
; default is to install on localhost) and run:
$ ansible-playbook nginx-uwsgi.yml -i hosts
To understand what the Playbook does, make sure to read the pyweb tutorial.
Configuration happens in three files: hosts
, group_vars/all
, and group_vars/os_<destination OS>
.
-
app_name
: the application name, used for configuration files (default:myapp
) -
app_package
,app_callable
: WSGI module to use (default:flaskapp
,app
)Framework Package Callable Resulting module name Package is… Callable is… Caveats Flask filename app filename:app module name (for a Python import) Flask object — Django project.wsgi application project.wsgi:application project
is name of your project (directory with settings.py);wsgi
is constantconstant add an environment variable for settings: env = DJANGO_SETTINGS_MODULE=project.settings
Bottle filename app filename:app module name (for a Python import) app = bottle.default_app()
— Pyramid filename app filename:app module name (for a Python import) app = config.make_wsgi_app()
make sure it’s not in an if __name__ == '__main__':
block — the demo app does that!) -
base_dir
: the base directory (and virtualenv) for the app (default:/srv/myapp
) -
appdata_dir
: the directory where app data files reside (default:{{ base_dir }}/appdata
) -
nginx_server_name
: hostnames the website is accessible under (default:localhost myapp.local
) -
nginx_http_port
: port to use when serving HTTP (default:80
) -
uwsgi_module
: WSGI module to use (constructed fromapp_package
,app_callable
— leave it as-is) -
uwsgi_processes
anduwsgi_threads
: control the resources devoted to this application. (default:1
and1
; should be more for bigger apps) -
uwsgi_env
: list of environment variables to pass to the app (in key=value format; default: empty) -
git_repo
: Git repository that contains app code (default:https://github.com/Kwpolska/flask-demo-app
) -
git_branch
: Git branch to pull from (default:master
) -
nginx_hostless_global_config
: Replace nginx.conf with one that does not have a default host. Destructive, see caveat below! (default:no
)
uid
: user used for files and socketsgid
: group used for files and socketsnginx_dir
: nginx sites directory (conf.d or sites-enabled)uwsgi_dir
: uWSGI vassals directoryuwsgi_plugins
: uWSGI plugins (python3,logfile
orpython
)uwsgi_service_name
: uWSGI systemd service name (uwsgi
oremperor.uwsgi
)
nginx_patch_confd_Archlinux
: patch/etc/nginx/nginx.conf
to useconf.d
(default:yes
; may fail)nginx_disable_default_site
: disable the default site by removing/etc/nginx/sites-enabled/default
(default:yes
; for Debian/Ubuntu)skip_selinux
: skip SELinux tasks (default:no
; for CentOS/Fedora)
Make sure you have the following packages installed first on the destination machine (Ansible dependencies):
- Debian/Ubuntu:
python
- Fedora:
python2 python2-dnf libselinux-python
- CentOS:
python libselinux-python
- Arch Linux:
python2
The default config of nginx creates some servers with default pages. Not everyone wants that. If you want this playbook to replace your nginx.conf file with one that has no servers (based on your OSes default nginx.conf
), set nginx_hostless_global_config
to yes
. You should not use it if you customized /etc/nginx/nginx.conf in any way, or if you have installed and configured nginx before. On Ubuntu and Debian, nginx_disable_default_site
is less destructive and enabled by default.
The nginx host config is rudimentary and does not include SSL/TLS support and custom error pages. For the former, see Remy van Elst’s guide.
By default, nginx on Arch Linux does not have any modular-include config directory. This playbook (and best practices) recommend having one for cleaner config. This playbook will try to patch your configuration file, but if you configured nginx in a way that makes the patch fail, you need to manually add this snippet to your server {}
block:
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*;
Afterwards, disable patching — set nginx_patch_confd_Archlinux
to no
. You should also disable this patch if you already used this playbook, or have a modular configuration directory already (you can change the path in config).
Copyright © 2016-2018, Chris Warrick. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.
-
Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution.
-
Neither the name of the author of this software nor the names of contributors to this software may be used to endorse or promote products derived from this software without specific prior written consent.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.