Changeset - 9fa438ee34c0
[Not reviewed]
0 4 2
Branko Majic (branko) - 9 years ago 2015-05-29 18:08:54
branko@majic.rs
MAR-5: Added another example to role reference for running PHP websites. Allow duplicates of roles php_website and wsgi_website. Use parameter in handler for restarting WSGI website (to have them website-specific). Updated test site to force handler execution in order to avoid being in undefined state.
6 files changed with 21 insertions and 7 deletions:
0 comments (0 inline, 0 general)
docs/rolereference.rst
Show inline comments
 
@@ -949,124 +949,131 @@ Parameters
 

	
 
**deny_files_regex** (list, optional)
 
  List of regular expressions for matching files/locations to which the web
 
  server should deny access. This is useful to block access to any sensitive
 
  files that should not be served directly by the web server. The format must be
 
  compatible with regular expressions used by ``nginx`` for ``location ~``
 
  syntax.
 

	
 
**fqdn** (string, mandatory)
 
  Fully-qualified domain name where the website is reachable. This value is used
 
  for calculating the user/group name for dedicated website user, as well as
 
  home directory of the website user (where data/code should be stored at).
 

	
 
**index** (string, optional)
 
  Space-separated list of files which should be treated as index files by the
 
  web server. The web server will attempt opening these index files, in
 
  succession, until the first match, or until it runs out of matches, when a
 
  client requests an URI pointing to directory. Default is ``index.php``.
 

	
 
**php_file_regex** (string, optional)
 
  Regular expression used for determining which file should be interepted via
 
  PHP. Default is ``\.php$``.
 

	
 
**php_rewrite_urls** (list, optional)
 
  A list of rewrite rules that are applied to incoming requests. These rewrite
 
  rules are specifically targetted at prettying-up the URLs used by the PHP
 
  scripts. Each element of the list should be a string value compatible with the
 
  format of ``nginx`` option ``rewrite``. The keyword ``rewrite`` itself should
 
  be omitted, as well as trailing semi-colon (``;``).
 

	
 
**rewrites** (list, optional)
 
  A list of rewrite rules that are applied to incoming requests. Each element of
 
  the list should be a string value compatible with the format of ``nginx``
 
  option ``rewrite``. The keyword ``rewrite`` itself should be omitted, as well
 
  as trailing semi-colon (``;``).
 

	
 
**packages** (list, optional)
 
  A list of additional packages to install for this particular PHP
 
  appliction. This is usually going to be different PHP extensions.
 

	
 
**uid** (integer, mandatory)
 
  UID/GID (they are set-up to be the same) of the dedicated website
 
  user/group.
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Here is an example configuration for setting-up a (base) PHP website (for running
 
``ownCloud`` application):
 
Here is an example configuration for setting-up two (base) PHP websites (for
 
running *ownCloud* and *The Bug Genie* applications):
 

	
 
.. code-block:: yaml
 

	
 
    ---
 

	
 
    - role: php_website
 
      fqdn: cloud.example.com
 
      uid: 2001
 
      admin: admin
 
      php_file_regex: \.php($|/)
 
      rewrites:
 
        - ^/\.well-known/host-meta /public.php?service=host-meta
 
        - ^/\.well-known/host-meta\.json /public.php?service=host-meta-json
 
        - ^/\.well-known/carddav /remote.php/carddav/ redirect
 
        - ^/\.well-known/caldav /remote.php/caldav/ redirect
 
        - ^/apps/calendar/caldav\.php /remote.php/caldav/
 
        - ^/apps/contacts/carddav\.php /remote.php/carddav/
 
        - ^/remote/(.*) /remote.php
 
      deny_files_regex:
 
        - ^(\.|autotest|occ|issue|indie|db_|console|build/|tests/|config/|lib/|3rdparty/|templates/).*
 
      packages:
 
        # For ownCloud
 
        - php5-gd
 
        - php5-json
 
        - php5-mysql
 
        - php5-curl
 
    - role: php_website
 
      admin: admin
 
      deny_files_regex:
 
        - ^\..*
 
      php_rewrite_urls:
 
        - ^(.*) /index.php?url=$1
 
      fqdn: tbg.example.com
 
      uid: 2007
 

	
 

	
 

	
 
WSGI Website
 
------------
 

	
 
The ``wsgi_website`` role can be used for setting-up a website powered by Python
 
on destination machine. The website needs to use the WSGI specification for
 
making the Python web application(s) available.
 

	
 
This role is normally not supposed to be used directly, but should instead serve
 
as the basis for writing website-specific roles. Therefore the role is written
 
in quite generic way, allowing the integrator to write his/her own logic for
 
deploying the necessary Python applications/packages, while still reusing a
 
common base and reducing the workload.
 

	
 
The role implements the following:
 

	
 
* Creates a dedicated user/group for running the WSGI application.
 
* Creates a base directory where the website-specific code and data should be
 
  stored at.
 
* Adds nginx to website's group, so nginx could read the necessary files.
 
* Adds website administrator to website's group, so administrator could manage
 
  the code and data.
 
* Installs additional packages required for running the role (as configured).
 
* Sets-up a dedicated Python virtual environment for website.
 
* Install Gunicorn in Python virtual environment.
 
* Installs additional packages required for running the role in Python virtual
 
  environment (as configured).
 
* Configures systemd to run the website code (using Gunicorn)
 
* Configures nginx to serve the website (static files served directly, requests
 
  passed on to Gunicorn).
 

	
 
The role is implemented with the following layout/logic in mind:
 

	
 
* Website users are named after the ``FQDN`` (fully qualified domain name) of
 
  website, in format of ``web-ESCAPEDFQDN``, where ``ESCAPEDFQDN`` is equal to
 
  ``FQDN`` where dots have been replaced by underscores (for example,
 
  ``web-wiki_example_com``).
 
* All websites reside within a dedicated sub-directory in ``/var/www``. The
 
  sub-directory name is equal to the ``FQDN`` used for accessing the
 
  website. Owner of the directory is set to be the application administrator,
 
  while group is set to be the website group. Additionally, ``SGID`` bit is set
 
  on the directory. This allows admin, with correct umask, to create necessary
 
  files and directories that should be readable (and eventually writeable) by
 
  the website user (running the WSGI application) without having to become root.
 
* All files placed in the website directory should be either created there
 
  directly, or copied to the directory in order to make sure the ``SGID`` gets
 
  honored. **Do not move the files, the permissions will not be set correctly.**
roles/php_website/meta/main.yml
Show inline comments
 
new file 100644
 
---
 

	
 
allow_duplicates: yes
 
\ No newline at end of file
roles/wsgi_website/handlers/main.yml
Show inline comments
 
---
 

	
 
- name: Restart website
 
- name: "Restart website {{ fqdn }}"
 
  service: name="{{ fqdn }}" state=restarted
roles/wsgi_website/meta/main.yml
Show inline comments
 
new file 100644
 
---
 

	
 
allow_duplicates: yes
 
\ No newline at end of file
roles/wsgi_website/tasks/main.yml
Show inline comments
 
@@ -20,75 +20,75 @@
 
  notify:
 
    - Restart nginx
 

	
 
- name: Add admin to website group
 
  user: name="{{ admin }}" groups="{{ user }}" append="yes"
 

	
 
- name: Create directory for storing socket file
 
  file: path="/var/run/wsgi/{{ fqdn }}" state="directory"
 
        owner="{{ user }}" group="www-data" mode="750"
 

	
 
- name: Install extra packages for website
 
  apt: name="{{ item }}" state=present
 
  with_items: packages
 

	
 
- name: Create directory for storing the Python virtual environment
 
  file: path="{{ home }}/virtualenv" state=directory
 
        owner="{{ admin }}" group="{{ user }}" mode="2750"
 

	
 
- name: Create Python virtual environment
 
  sudo_user: "{{ admin }}"
 
  command: /usr/bin/virtualenv "{{ home }}/virtualenv" creates="{{ home }}/virtualenv/bin/activate"
 

	
 
- name: Create directory where virtualenvs will be symlinked to
 
  sudo_user: "{{ admin }}"
 
  file: path="~/.virtualenvs" state=directory mode=750
 

	
 
- name: Create convenience symlink for Python virtual environment wrapper utility
 
  sudo_user: "{{ admin }}"
 
  file: src="{{ home }}/virtualenv" dest="~/.virtualenvs/{{ fqdn }}" state=link
 

	
 
- name: Deploy virtualenv wrapper
 
  template: src="venv_exec.j2" dest="{{ home }}/virtualenv/bin/exec"
 
            owner="{{ admin }}" group="{{ user }}" mode="750"
 

	
 
- name: Install Gunicorn in Python virtual environment
 
  sudo_user: "{{ admin }}"
 
  pip: name=gunicorn state=present virtualenv="{{ home }}/virtualenv"
 

	
 
- name: Install additional packages in Python virtual environment
 
  sudo_user: "{{ admin }}"
 
  pip: name="{{ item }}" state=present virtualenv="{{ home }}/virtualenv"
 
  with_items: virtualenv_packages
 

	
 
- name: Deploy systemd socket configuration for website
 
  template: src="systemd_wsgi_website.socket.j2" dest="/etc/systemd/system/{{ fqdn }}.socket"
 
            owner=root group=root mode=644
 
  notify:
 
    - Reload systemd
 
    - Restart website
 
    - "Restart website {{ fqdn }}"
 

	
 
- name: Deploy systemd service configuration for website
 
  template: src="systemd_wsgi_website.service.j2" dest="/etc/systemd/system/{{ fqdn }}.service"
 
            owner=root group=root mode=644
 
  notify:
 
    - Reload systemd
 
    - Restart website
 
    - "Restart website {{ fqdn }}"
 

	
 
- name: Enable the website service
 
  service: name="{{ fqdn }}" enabled=yes state=started
 

	
 
- name: Create directory where static files can be served from
 
  file: path="{{ home }}/htdocs/" state=directory
 
        owner="{{ admin }}" group="{{ user }}" mode="2750"
 

	
 
- name: Deploy nginx configuration file for website
 
  template: src="nginx_site.j2" dest="/etc/nginx/sites-available/{{ fqdn }}"
 
            owner=root group=root mode=640 validate="/usr/local/bin/nginx_verify_site.sh -n '{{ fqdn }}' %s"
 
  notify:
 
    - Restart nginx
 

	
 
- name: Enable nginx website
 
  file: src="/etc/nginx/sites-available/{{ fqdn }}" dest="/etc/nginx/sites-enabled/{{ fqdn }}"
 
        state=link
 
  notify:
 
    - Restart nginx
testsite/ansible.cfg
Show inline comments
 
[defaults]
 

	
 
roles_path=../roles
 
force_handlers = True
 
\ No newline at end of file
0 comments (0 inline, 0 general)