This content originally appeared on DEV Community and was authored by Harry Tang
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
- A Kubernetes cluster.
- MariaDB (see Deploy MariaDB Galera with MaxScale on Kubernetes).
- MinIO (see Deploy MinIO in Kubernetes with Tenant Separation).
- FluxCD.
- Sealed Secrets.
- SMTP provider.
- Cert Manager.
- CloudFlare Tunnel.
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
.
- 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
```
- 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
-
Create the Certificate
I use a wildcard certificate to access Nextcloud both from home and remotely via the domains
homecloud.harrytang.com
andnextcloud.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
-
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
-
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 ...
-
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
This content originally appeared on DEV Community and was authored by Harry Tang