nginx/ansible-role-nginx-config

Question - nginx-config and proxy rewrite

Closed this issue · 4 comments

New to nginx, so I may be approaching this incorrectly.

using the nginx_config role, I've successfully configured several proxy locations but am having difficulty on one where I need a rewrite directive. It appears that the roles do not recognize rewrite: in the yaml as they never make it into the default.conf.

In the below example, the /simple, /packages get generated as expected, however, for the /publish the rewrite directive does not get generated.

What am i missing??

Input yml:

- name: Configure NGINX
  ansible.builtin.include_role:
    name: nginx_config
    apply: 
      become: true
      tags: 
        - configure
  tags: always
  vars:
    nginx_config_http_template_enable: true
    nginx_config_http_template:
      - template_file: http/default.conf.j2
        deployment_location: /etc/nginx/conf.d/default.conf
        config:
          servers:
            - core:
                listen:
                  - port: 80
                server_name: raspberrypi
              log:
                access:
                  - path: /var/log/nginx/access.log
                    # format: main 
              locations:
                - location: ~ /simple
                  # pypi-server
                  proxy:
                    pass: "http://{{ dapypi_host }}:8080"
                    set_header:
                    - field: Host
                      value: $host
                    - field: X-Real-IP
                      value: '$remote_addr:$remote_port'
                    - field: X-Scheme
                      value: $scheme

                - location: ~ /packages
                  # pypi-server
                  proxy:
                    pass: "http://{{ dapypi_host }}:8080"
                    set_header:
                    - field: Host
                      value: $host
                    - field: X-Real-IP
                      value: '$remote_addr:$remote_port'
                    - field: X-Scheme
                      value: $scheme

                - location: ~* ^/publish
                  # pypi-server
                  rewrite: ^/publish / break
                  # Above line does not seem to work...
                  proxy:
                    pass: "http://{{ dapypi_host }}:8080"
                    set_header:
                    - field: Host
                      value: $host
                    - field: X-Real-IP
                      value: '$remote_addr:$remote_port'
                    - field: X-Scheme
                      value: $scheme                

Output:

server {
    listen 80;
    server_name raspberrypi;

    access_log /var/log/nginx/access.log;

    location ~ /simple {
        proxy_pass http://rasserver:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr:$remote_port;
        proxy_set_header X-Scheme $scheme;


    }
    location ~ /packages {
        proxy_pass http://rasserver:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr:$remote_port;
        proxy_set_header X-Scheme $scheme;


    }
    location ~* ^/publish {
        proxy_pass http://rasserver:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr:$remote_port;
        proxy_set_header X-Scheme $scheme;
oxpa commented

try using another configuration approach to rewrites. You may find an example here: https://github.com/nginxinc/ansible-role-nginx-config/blob/main/molecule/default/converge.yml#L594

In general though it seems like you don't need a rewrite. Just make all the locations prefix (get rid of '~') and then add forward slash in the proxy statement where you wanted the rewrite.

Thanks for the quick response.

If I understand your response, you are suggesting I add a location: / to the definition. What I showed above is just a snippet of my play, I already have a proxy for / that fronts a different server, that's why I need the rewrite at nginx level so I can force any request with /publish it to the right server as / (i.e. remove the publish node)

My question really is, using nginx-config role, how do I supply a rewrite statement under a location:? Everything I've tried seems to ignore the rewrite directive, and never makes it into the generated default.conf file.

I'd like the block to be:

    location ~ ^/publish {
        rewrite ^/publish / break;
        proxy_pass http://servername:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr:$remote_port;
        proxy_set_header X-Scheme $scheme;

oxpa commented

Have a look at the link above. It has proper rewrite. A rewrite should have a regex, a replacement and a flags fields. Something like this:

                    rewrites:
                      - regex: ^/publish
                        replacement: /
                        flag: break

An alternative solution is to let nginx do the replacement:

                 - location: /publish
                  # pypi-server
                  proxy:
                    pass: "http://{{ dapypi_host }}:8080/"

Note, that I'm not using a '~' in the location configuration and I have added a slash to a pass statement.
Nginx is smart enough to automatically replace the prefix of a location with a URL part from proxy_pass.
You can find out more about it here: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

awesome, gotta run out for a bit, I'll give this a test this evening! Thanks for the assist.

Update:
Checked it out, your alternative solution worked, which is simpler than the rewrite (which I still couldn't get to work). I thought I had tried that alternative solution earlier and got an error message, but must have been something else...

Appreciate the assit.