Provisioning with nginx-includes results in two copies of "location /"

Hi,

I am trying to optimise our site for SEO, starting with password protection of our staging server, to avoid duplicate content issues.

I decided that an update to our Trellis configuration would be the best tactic to avoid plugin inefficiency, bloat etc, since it only involves a modification to Nginx configuration.

Configuring Nginx manually for the password protection works. I just have to get it working with Trellis.

So:

  • Added the following to group_vars/staging/main.yml:

nginx_includes_templates_path: nginx-includes-staging

  • Created file nginx-includes-staging/australiascience.tv/assets-expiry.conf.j2, with this content:

location / {
try_files $uri $uri/ /index.php?$args;
auth_basic “closed_site”;
auth_basic_user_file conf.d/.htpasswd;
}

  • Also added the file nginx-includes/australiascience.tv/assets-expiry.conf.j2, ready for the next thing I have to do. The idea is that nginx-includes/ will be used as the default, to be used by production. I can’t see any evidence that it’s causing a problem.
  • Reprovisioned:

ansible-playbook server.yml -e env=staging

resulting in the usual (correct) output, but concluding with:

RUNNING HANDLER [common : reload nginx] ************************************************************************************************************************
System info:
Ansible 2.4.0.0; Linux
Trellis at "Update vagrant_box_version to >= 201801.02.0"

non-zero return code
nginx: [emerg] duplicate location “/” in /etc/nginx/sites-
enabled/australiascience.tv.conf:54
nginx: configuration file /etc/nginx/nginx.conf test failed
fatal: [35.201.10.255]: FAILED! => {“changed”: true, “cmd”: [“nginx”, “-t”], “delta”: “0:00:00.020786”, “end”: “2018-02-01 02:51:49.501284”, “failed”: true, “rc”: 1, “start”: “2018-02-01 02:51:49.480498”, “stderr_lines”: [“nginx: [emerg] duplicate location “/” in /etc/nginx/sites-enabled/australiascience.tv.conf:54”, “nginx: configuration file /etc/nginx/nginx.conf test failed”], “stdout”: “”, “stdout_lines”: []}
to retry, use: --limit @/home/mclarke/gitlab/australiascience.tv/trellis/server.retry

PLAY RECAP *****************************************************************************************************************************************************
35.201.10.255 : ok=91 changed=8 unreachable=0 failed=1
localhost : ok=0 changed=0 unreachable=0 failed=0

~/gitlab/australiascience.tv/trellis$

On the server in /etc/nginx/sites-available/australiascience.tv.conf, it seems that the problem is here:

. . .
include includes.d/australiascience.tv/*.conf;

location ~* /app/uploads/.*.php$ {
deny all;
}

location / {
try_files $uri $uri/ /index.php?$args;
}
. . .

and, of course, includes.d/australiascience.tv/assets-expiry.conf contains this:

location / {
try_files $uri $uri/ /index.php?$args;
auth_basic “closed_site”;
auth_basic_user_file conf.d/.htpasswd;
}

thus causing the duplicate entry.

This is probably a silly mistake on my part, but so far I can’t spot it. Note that I previously tried with “–tags nginx-includes” but the same thing happened.

It will be great if I can get this working, because I can then do something similar to enable our assets to leverage browser caching, one of the things we have to achieve to appease Google Page Insights.

Note also that I have just rebased our Trellis fork from your master branch, hoping it would solve the problem, but no joy.

Hoping you can advise! Thanks in advance.

It seems that even if I comment out the offending section in australiascience.tv.conf, there is a further section for https redirection that “nginx -t” complains about:

server {
listen [::]:80;
listen 80;
server_name staging.australiascience.tv;

include acme-challenge-location.conf;

include includes.d/australiascience.tv/*.conf;

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

It’s starting to look as though I’ll have to do this manually, unfortunately.

You might try a user contributed extension named bedrock-site-protect which sets up basic auth for you. :star: recommended

Indeed a given server block can’t have two location / {} blocks. And as you discovered, the nginx-includes approach you are using includes files outside of the other location / {} block. So if you were in a situation requiring something inside this pre-existing location block, you’d need a child template that extends the location_primary block (see example of replacing the content of a block).

However, the good news is that the auth_basic directives can be placed in the server block context, so you could just adjust your include file:

 # nginx-includes-staging/australiascience.tv/assets-expiry.conf.j2
- location / {
- try_files $uri $uri/ /index.php?$args;
  auth_basic “closed_site”;
  auth_basic_user_file conf.d/.htpasswd;
- }
2 Likes

Okay. Thank you for the fast response! I will have a look into doing things this way, and I guess the nginx-includes could then just be used to fix browser caching etc.