Nginx Includes

The Nginx site conf generated by Trellis is designed to work with a wide range of WordPress installations, but your sites may require customization. For example, perhaps you use custom rewrites to redirect legacy URLs, or maybe you would like to proxy some requests to another server. You may create custom Nginx include files or use child templates to extend the Trellis Nginx conf templates.

include files

You may put your Nginx customizations in Ansible/Jinja2 templates, making full use of variables and logic. Store your template files in a new nginx-includes directory in the root of your Trellis project. If you prefer to name this directory some-other-name, you may define nginx_includes_templates_path: some-other-name in your group_vars/all/main.yml.

Trellis will recurse nginx-includes and template any files ending in *.conf.j2 to the /etc/nginx/includes.d/ directory on the remote, preserving the subdirectory structure. If you want to edit, add to, or delete your Nginx include files, edit them on the local machine and re-run the playbook. Tip: Append --tags nginx-includes to your command to run only the relevant portion of the playbook.

Default

By default in Trellis, a WordPress site's Nginx conf will include any nginx-includes files found in a subdirectory named after the site. To illustrate, suppose you have two sites managed by Trellis, defined in wordpress_sites as follows:

wordpress_sites:
  site1:
    ...
  site2:
    ...

You could organize your nginx-includes templates in corresponding subdirectories:

nginx-includes/
  site1/
    rewrites.conf.j2
    proxy.conf.j2
  site2/
    rewrites.conf.j2

The above directory structure would be templated to the remote server as follows:

/
  etc/
    nginx/
      includes.d/
        site1/
          rewrites.conf
          proxy.conf
        site2/
          rewrites.conf

To explicitly walk through the example, consider just the site1 site key in the wordpress_sites list. The corresponding nginx-includes/site1/ directory contains two confs which are templated to the remote's /etc/nginx/includes.d/site1/. The primary Nginx conf for site1 will have a statement include includes.d/site1/*.conf;, thus including rewrites.conf and proxy.conf.

This include directive is located inside the primary server block, just before the primary location block. Explore the Child templates section below for more options if this default does not satisfy your needs.

Note that this default include directive per site will not recurse subdirectories within includes.d/site1 so if you place templates in nginx-includes/site1/somedir/*.conf.j2, they will be templated to the remote's includes.d/site1/somedir/*.conf but will not be included by default. See the Child templates section below for how you could include such confs.

File cleanup

By default, Trellis will remove from the remote's includes.d directory any *.conf file that lacks a corresponding template in your local machine's nginx-includes. If you prefer to leave all conf files on the remote, you may disable this file cleanup by defining nginx_includes_d_cleanup: false in group_vars/all/main.yml.

Deprecated templates directory

The original implementation of Trellis Nginx includes required template files to be stored in roles/wordpress-setup/templates/includes.d. That directory is now deprecated and will no longer function beginning with Trellis 1.0. Please move your templates to a directory named nginx-includes in the root of this project. It is preferable to store user-created templates separate from Trellis core files.

Trellis Nginx includes were originally made possible thanks to @chriszarate in #242.

Child templates

You may use child templates to override any block in the two Nginx conf templates:

Create your child templates following the Jinja template inheritance docs and the guidelines below.

Tip: Once you have set up your child templates, append --tags nginx-includes to your command to run only the Nginx conf portions of the playbook.

Designate a child template

You will need to inform Trellis of the child templates you have created.

nginx_conf

Use the nginx_conf variable to designate your child template for nginx.conf.j2. Given that this template applies to all sites, it would be appropriate to define the variable in a group_vars/<environment>/main.yml file (including group_vars/all/main.yml).

nginx_conf: nginx-includes/nginx.conf.child

The example above designates a child template in the nginx-includes path on your local machine (i.e., the default path for nginx_includes_templates_path variable; see include files section above). You may choose a different path and assign the template any name and file extension you wish. When using the nginx-includes path, however, avoid using a filename that matches the *.conf.j2 pattern required for include files described above.

nginx_wordpress_site_conf

Use the nginx_wordpress_site_conf variable to designate your child template for wordpress-site.conf.j2, which is used for each of your sites. To designate a global child template for all your sites, you could define the variable in a group_vars/<environment>/main.yml file.

nginx_wordpress_site_conf: nginx-includes/wordpress-site.conf.child

You may designate a child template per site by defining the variable in group_vars/<environment>/wordpress_sites.yml.

wordpress_sites:
  example.com:
    ...
    nginx_wordpress_site_conf: nginx-includes/example.com.conf.child
    ...

Create a child template

Create your child templates at the paths you designated in the nginx_conf and nginx_wordpress_site_conf variables described above. Child templates must include two elements:

  • an {% extends 'base_template' %} statement
  • one or more {% block block_name %} blocks

Child template example – simple

Here is an example child template that replaces the http_begin block in the nginx.conf.j2 base template.

{% extends 'roles/nginx/templates/nginx.conf.j2' %}

{% block http_begin -%}
  server_names_hash_bucket_size 128;
  server_names_hash_max_size 512;
{% endblock %}

The path for your base template – referenced in your extends statement – must be relative to the server.yml playbook (i.e., relative to the Trellis root directory).

Child template example – complex

The first block in the example child template below augments the content of the fastcgi_basic block from the wordpress-site.conf.j2 base template. It inserts {{ super() }}, which represents the original block content from the base template, then adds an extra fastcgi_param. The second block in the example rewrites the redirects_https block, omitting the ssl_enabled conditional and adding a new listen 8080 directive.

{% extends 'roles/wordpress-setup/templates/wordpress-site.conf.j2' %}

    {% block fastcgi_basic -%}
    {{ super() }}
    fastcgi_param HTTPS on;
    {%- endblock %}

{% block redirects_https %}
# Redirect to https
server {
  listen 80;
  listen 8080;
  server_name {{ site_hosts | join(' ') }}{% if item.value.multisite.subdomains | default(false) %} *.{{ site_hosts_canonical | join(' *.') }}{% endif %};

  {{ self.acme_challenge() -}}

  location / {
    return 301 https://$host$request_uri;
  }
}

{% endblock -%}

You'll notice that these blocks use indentation and whitespace control (e.g., -%}) parallel to their counterparts in the the base template wordpress-site.conf.j2. This will achieve the best formatting of templated conf files on the server.

Sites templates

You may use sites templates to add new sites confs to Nginx in addition to the standard WordPress confs. They are also Ansible/Jinja2 templates, and thus can make full use of variables and logic.

Create your sites templates following the guidelines below.

Tip: Once you have set up your sites templates, append --tags nginx-sites to your command to run only the Nginx sites portions of the playbook.

Default

By default in Trellis, a "no-default" site Nginx conf is included. Its purpose is to drop requests to unknown server names, preventing host header attacks and other potential problems.

The nginx_sites_confs variable contains the list of confs to be templated to the server's sites-available folder. Its default value only registers the default site (whose template resides in roles/nginx/templates/no-default.conf.j2):

nginx_sites_confs:
  - src: no-default.conf.j2

Each entry to this variable also has an enabled parameter, which can be omitted, and defaults to true. It controls whether the conf is linked to the server's sites-enabled folder, and thus activated. The above default is equivalent to:

nginx_sites_confs:
  - src: no-default.conf.j2
    enabled: true

However, you might want to add other sites for specific purposes.

Designate a site template

You will need to inform Trellis of the sites templates you have created.

nginx_sites_confs

Use the nginx_sites_confs variable to designate your new site template. Given that this template applies to all environments, it would be appropriate to define the variable in a group_vars/<environment>/main.yml file (including group_vars/all/main.yml). Remember to keep the default site for security purposes if you don't have a specific reason to override it.

nginx_sites_confs:
  - src: no-default.conf.j2
  - src: nginx-includes/example.conf.site.j2

The example above designates a site template in the nginx-includes path on your local machine (i.e., the default path for nginx_includes_templates_path variable; see include files section above). You may choose a different path and assign the template any name and file extension you wish. When using the nginx-includes path, however, avoid using a filename that matches the *.conf.j2 pattern required for include files described above.

Create a site template

Create your site templates at the paths you designated in the nginx_sites_confs variable described above. Templates should start with an # {{ ansible_managed }} statement to indicate that the file is managed by ansible.

Template example

Here is an example site template that hosts nginx default page, listening on example.com non-standard port 8080.

# {{ ansible_managed }}

server {
  listen 8080;
  server_name example.com;

  root /var/www/html;
  index index.html index.htm index.nginx-debian.html;

  location / {
    # First attempt to serve request as file, then
    # as directory, then fall back to displaying a 404.
    try_files $uri $uri/ =404;
  }
}

File cleanup

By default, Trellis will remove from the remote's site-enabled directory any link to a site conf file that has its enabled attribute set to false. There is no cleanup of the confs in sites-available, they're only made mute by being disabled.

This examples shows the addition of the above site template, while also disabling Trellis' default site.

nginx_sites_confs:
  - src: no-default.conf.j2
    enabled: false
  - src: nginx-includes/example.conf.site.j2