skip to Main Content

I’m new to kubernetes and nginx, and am having trouble understanding how to implement Ingress (nginx-ingress) for my particular use case.

I want to expose the pgadmin PostgreSQL admin tool from my cluster.

I have other applications exposed via nginx-ingress from my cluster and I like each to hang off its own subdirectory e.g.:

  • myserver.com/purchasing/index.html
  • myserver.com/sales/index.html

I have a problem doing this with pgadmin (although the problem would no doubt apply equally to other apps that behave in the same way)

I have set up an Ingress rule to capture and route accordingly:

  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$2

  rules:
  - http:
      paths:
        - path: /pgadmin4(/|$)(.*)

it does the routing and the backend is hit.

However when pgadmin then does a redirect, I lose the pgadmin/ from the redirect URl i.e.

  • I send a GET to myserver.com/pgadmin
  • I receive a 302 redirect to myserver.com/login

whereas I want redirecting to:

  • myserver.com/pgadmin/login

What pieces am I missing to achieve this – it feels like it should be simple?

Thanks

2

Answers


  1. It’s worth mentioning that exposing many different services using the same domain name may not be the best idea in terms of security. Many web security mechanisms rely on the domain name to determine what’s trusted and what isn’t. So if one of your containers is breached, other services sharing the same domain name might be affected.

    Anyway, the problem is with pgadmin. It isn’t aware that it’s being served from myserver.com/pgadmin/ (another reason why having multiple services use the same domain name isn’t the best idea), so it sends the wrong redirects.

    Luckily, the pgadmin documentation offers a solution:

    If you wish to host pgAdmin under a subdirectory rather than on the root of the server, you must specify the location and set the X-Script-Name header which tells the pgAdmin container how to rewrite paths:

    server {
      listen 80;
      server_name _;
    
      location /pgadmin4/ {
          proxy_set_header X-Script-Name /pgadmin4;
          proxy_set_header Host $host;
          proxy_pass http://localhost:5050/;
          proxy_redirect off;
      } 
    }
    

    So it looks like you just have to make sure that calls to pgadmin are sent with the X-Script-Name /pgadmin4 header, which is something that the nginx ingress controller knows how to do.

    Login or Signup to reply.
  2. Had same kind of requirement for me, solved it by adding X-Script-Name in annotations

    nginx.ingress.kubernetes.io/configuration-snippet: |
          proxy_set_header X-Script-Name /pgadmin;
    

    The full Ingress file looks like mentioned below.

    Note: This is my test environment, so I am not enabling SSL certs, In your case, you may need to enable SSL settings

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ingress-resource
      annotations:
        kubernetes.io/ingress.class: "nginx"
        nginx.ingress.kubernetes.io/ssl-redirect: "false" 
        nginx.ingress.kubernetes.io/configuration-snippet: |
          proxy_set_header X-Script-Name /pgadmin;
    spec:
      rules:
      - host: "34.70.247.68.nip.io"
        http:
          paths:
          - pathType: ImplementationSpecific
            path: /pgadmin
            backend:
              service:
                name: pgadmin-service
                port:
                  number: 80
    

    Reference: https://github.com/helm/charts/issues/21046#issuecomment-591840105

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search