Paul Schuldesz
Paul Schuldesz

Reputation: 133

Kubernetes Access service nextcloud from /nextcloud

I am trying to host my own Nextcloud server using Kubernetes.

I want my Nextcloud server to be accessed from http://localhost:32738/nextcloud but every time I access that URL, it gets redirected to http://localhost:32738/login and gives me 404 Not Found.

If I replace the path with:

path: /

then, it works without problems on http://localhost:32738/login but as I said, it is not the solution I am looking for. The login page should be accessed from http://localhost:32738/nextcloud/login.

Going to http://127.0.0.1:32738/nextcloud/ does work for the initial setup but after that it becomes inaccessible as it always redirects to:

http://127.0.0.1:32738/apps/dashboard/

and not to:

http://127.0.0.1:32738/nextcloud/apps/dashboard/

This is my yaml:

#Nextcloud-Dep
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextcloud-server
  labels:
    app: nextcloud
spec:
  replicas: 1
  selector:
    matchLabels:
      pod-label: nextcloud-server-pod
  template:
    metadata:
      labels:
        pod-label: nextcloud-server-pod
    spec:
      containers:
      - name: nextcloud
        image: nextcloud:22.2.0-apache
        env:
        - name: POSTGRES_DB
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-name
        - name: POSTGRES_USER
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-username
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-password
        - name: POSTGRES_HOST
          value: nextcloud-database:5432
        volumeMounts:
        - name: server-storage
          mountPath: /var/www/html
          subPath: server-data
      volumes:
      - name: server-storage
        persistentVolumeClaim:
          claimName: nextcloud
---
#Nextcloud-Serv
apiVersion: v1
kind: Service
metadata:
  name: nextcloud-server
  labels:
    app: nextcloud
spec:
  selector:
    pod-label: nextcloud-server-pod
  ports:
  - port: 80
    protocol: TCP
    name: nextcloud-server
---
#Database-Dep
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextcloud-database
  labels:
    app: nextcloud
spec:
  replicas: 1
  selector:
    matchLabels:
      pod-label: nextcloud-database-pod
  template:
    metadata:
      labels:
        pod-label: nextcloud-database-pod
    spec:
      containers:
      - name: postgresql
        image: postgres:13.4
        env:
        - name: POSTGRES_DATABASE
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-name
        - name: POSTGRES_USER
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-username
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-password
        - name: POSTGRES_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-rootpassword
        - name: PGDATA
          value: /var/lib/postgresql/data/
        volumeMounts:
        - name: database-storage
          mountPath: /var/lib/postgresql/data/
          subPath: data
      volumes:
      - name: database-storage
        persistentVolumeClaim:
          claimName: nextcloud
---
#Database-Serv
apiVersion: v1
kind: Service
metadata:
  name: nextcloud-database
  labels:
    app: nextcloud
spec:
  selector:
    pod-label: nextcloud-database-pod
  ports:
  - port: 5432
    protocol: TCP
    name: nextcloud-database
---
#PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nextcloud-pv
  labels:
    type: local
spec:
  capacity:
    storage: 8Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/tmp"
---
#PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nextcloud
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
---
#Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nextcloud-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - http:
      paths:
      - backend:
          service:
            name: nextcloud-server
            port:
              number: 80
        pathType: Prefix
        path: /nextcloud(/.*)
---
#Secret
apiVersion: v1
kind: Secret
metadata:
  name: nextcloud
  labels:
    app: nextcloud
immutable: true
stringData:
  db-name: nextcloud
  db-username: nextcloud
  db-password: changeme
  db-rootpassword: longpassword
  username: admin
  password: changeme

ingress-nginx was installed with:

helm install nginx ingress-nginx/ingress-nginx

Please tell me if you want me to supply more information.

Upvotes: 1

Views: 1040

Answers (1)

kkopczak
kkopczak

Reputation: 862

In your case there is a difference between the exposed URL in the backend service and the specified path in the Ingress rule. That's why you get an error.

To avoid that you can use rewrite rule.

Using that one your ingress paths will be rewritten to value you provide. This annotation ingress.kubernetes.io/rewrite-target: /login will rewrite the URL /nextcloud/login to /login before sending the request to the backend service.

But:

Starting in Version 0.22.0, ingress definitions using the annotation nginx.ingress.kubernetes.io/rewrite-target are not backwards compatible with previous versions.

On this documentation you can find following example:

$ echo '
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rewrite
  namespace: default
spec:
  rules:
  - host: rewrite.bar.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /something(/|$)(.*)
' | kubectl create -f -

In this ingress definition, any characters captured by (.*) will be assigned to the placeholder $2, which is then used as a parameter in the rewrite-target annotation.

So in your URL you could see wanted /nextcloud/login, but rewriting will couse changing path to /login in the Ingress rule and finding your backend. I would suggest use one of following option:

path: /nextcloud(/.*)
nginx.ingress.kubernetes.io/rewrite-target: /$1

or

path: /nextcloud/login
nginx.ingress.kubernetes.io/rewrite-target: /login

See also this article.

Upvotes: 1

Related Questions