DEV Community

Cover image for Deploy Nextcloud on Kubernetes
Harry Tang
Harry Tang

Posted on • Originally published at harrytang.xyz

Deploy Nextcloud on Kubernetes

Introduction

Nextcloud is an open-source data storage solution that you can self-host at home. This article shows how I deployed Nextcloud on my home Kubernetes cluster.

Prerequisites

Step-by-step Guide

I used FluxCD to manage my YAML files in Git, following the GitOps approach. However, you can also use standard Helm commands for the HelmRelease.

  1. Prepare the ENVs

I set up the environment variables for Nextcloud's user credentials, SMTP mail server, and MinIO credentials:

```bash
export NEXTCLOUD_ADMIN_USER=harry
export NEXTCLOUD_ADMIN_PASSWORD=$(openssl rand -base64 32)
export SMTP_HOST=smtp.eu.mailgun.org
export SMTP_USER=nextcloud@notify.harrytang.com
export SMTP_PASSWORD=YOUR_SMTP_PASSWORD
export MINIO_ACCESS_KEY=YOUR_MINIO_ACCESS_KEY
export MINIO_SECRET_KEY=YOUR_MINIO_SECRET_KEY
```
Enter fullscreen mode Exit fullscreen mode
  1. Create Sealed Secrets
    kubectl -n nextcloud create secret generic nextcloud-secrets --dry-run=client --from-literal=nextcloud-password=$NEXTCLOUD_ADMIN_PASSWORD \
      --from-literal=nextcloud-username=$NEXTCLOUD_ADMIN_USER \
      --from-literal=smtp-host=$SMTP_HOST \
      --from-literal=smtp-username=$SMTP_USER \
      --from-literal=smtp-password=$SMTP_PASSWORD \
      --from-literal=minio-access-key=$MINIO_ACCESS_KEY \
      --from-literal=minio-secret-key=$MINIO_SECRET_KEY \
      -o yaml | kubeseal --format=yaml > sealed-secret.yaml   
Enter fullscreen mode Exit fullscreen mode
  1. Create the Certificate

    I use a wildcard certificate to access Nextcloud both from home and remotely via the domains homecloud.harrytang.com and nextcloud.harrytang.com, respectively.

    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: harrytang-com
      namespace: nextcloud
    spec:
      secretName: harrytang-com-tls
      dnsNames:
        - 'harrytang.com'
        - '*.harrytang.com'
      issuerRef:
        name: letsencrypt
        kind: ClusterIssuer
    
  2. Deploy Ingress

    I use Nginx Ingress to expose Nextcloud within my home network (by adding an A record to my domain):

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: nextcloud
      namespace: nextcloud
      annotations:
        nginx.ingress.kubernetes.io/proxy-body-size: 100G
        nginx.ingress.kubernetes.io/proxy-read-timeout: '86400'
        nginx.ingress.kubernetes.io/proxy-send-timeout: '86400'
        nginx.ingress.kubernetes.io/proxy-connect-timeout: '86400'
    spec:
      tls:
        - hosts:
            - homecloud.harrytang.com
          secretName: harrytang-com-tls
      rules:
        - host: homecloud.harrytang.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: nextcloud
                    port:
                      number: 8080    
    
  3. Config CloudFlare Tunnel

    Configure Cloudflare Tunnel to acess your Nextcloud remotely and securely:

    ...
      ingress: # https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/configure-tunnels/origin-configuration/#tls-settings 
        - hostname: nextcloud.harrytang.com
          service: http://nextcloud.nextcloud:8080
    ...
    
  4. Deploy Nextcloud

    Finally, after setting everything up, I deployed Nextcloud:

    ---
    apiVersion: source.toolkit.fluxcd.io/v1
    kind: HelmRepository
    metadata:
      name: nextcloud
      namespace: nextcloud
    spec:
      interval: 24h
      url: https://nextcloud.github.io/helm/
    ---
    apiVersion: helm.toolkit.fluxcd.io/v2
    kind: HelmRelease
    metadata:
      name: nextcloud
      namespace: nextcloud
    spec:
      interval: 24h
      chart:
        spec:
          chart: nextcloud
          version: '~6.6.4'
          sourceRef:
            kind: HelmRepository
            name: nextcloud
            namespace: nextcloud
          interval: 24h
      values:
        replicaCount: 1
        livenessProbe:
          initialDelaySeconds: 180
        readinessProbe:
          initialDelaySeconds: 180
        nextcloud:
          update: true
          host: nextcloud.harrytang.com
          trustedDomains:
            - nextcloud.harrytang.com
            - homecloud.harrytang.com
          existingSecret:
            enabled: true
            secretName: nextcloud-secrets
          mail:
            enabled: true
            fromAddress: noreply
            domain: harrytang.com
          objectStore:
            s3:
              enabled: true
              bucket: nextcloud
              usePathStyle: true
              host: minio.nextcloud.svc.cluster.local
              existingSecret: nextcloud-secrets
              secretKeys:
                accessKey: minio-access-key
                secretKey: minio-secret-key
              ssl: false
              port: 80
          configs:
            proxy.config.php: |-
              <?php
              $CONFIG = array (
                'trusted_proxies' => array(
                  0 => '127.0.0.1',
                  1 => '10.0.0.0/8',
                ),
                'forwarded_for_headers' => array('HTTP_X_FORWARDED_FOR'),
              );
            zz.config.php: |-
              <?php
              $CONFIG = array (
                'trusted_domains' => array(
                  0 => 'localhost',
                  1 => 'nextcloud.harrytang.com',
                  2 => 'homecloud.harrytang.com',
                ),
              );
          phpConfigs:
            zz-custom.ini: |-
              memory_limit=1024M
              upload_max_filesize=100G
              post_max_size=100G
              max_execution_time=86400
              max_input_time=86400
          extraVolumes:
            - name: private-ca
              configMap:
                name: private-ca
                items:
                  - key: private-ca.pem
                    path: private-ca.crt
          extraVolumeMounts:
            - name: private-ca
              mountPath: /usr/local/share/ca-certificates
              readOnly: true
        lifecycle:
          postStartCommand:
            - update-ca-certificates
        persistence:
          enabled: true
          accessMode: ReadWriteMany
        phpClientHttpsFix:
          enabled: true
        cronjob:
          enabled: false
        internalDatabase:
          enabled: false
        externalDatabase:
          enabled: true
          type: mysql
          host: maxscale-galera.nextcloud.svc.cluster.local
          database: nextcloud
          existingSecret:
            enabled: true
            secretName: mariadb
            usernameKey: mariadb-username
            passwordKey: mariadb-password    
    

Conclusion

Running Nextcloud on your home lab Kubernetes cluster provides a secure and private way to store your data. You can store unlimited photos and videos for yourself and your family while accessing them from anywhere.

References

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay