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.


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:


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


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


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.


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.


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.

    nginx_wordpress_site_conf: nginx-includes/

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.