Zum Inhalt

Kalender und Kontakte synchronisieren

Meine Familie hat viele Termine. Ob es ein Arzttermin oder der Schichtdienst oder Termine der Kinder ist, alles muss organisiert werden. Wichtig ist den Überblick zu bewahren. Es ist egal ob Windows, Android oder iOS, alle beinhalten mittlerweile Kalender.

Gerade Apple Hardware hat seit Jahren die Möglichkeit mit ical Daten für Kalender zu verwalten. Auf dem PC, Mac oder gar Handy sollen die Daten synchron über eine private eigene Infrastruktur synchronisiert werden. Kontakte der Familie sind meist für alle Familienmitglieder zuhause interessant, also sollen alle zugreifen können.

NextCloud

Um das zu realisieren und noch viel mehr, gibt es NextCloud. Es ist mit NextCloud möglich, Kalender und Kontakte zu synchronisieren. Es ist sogar möglich Dateien abzulegen und zu teilen.

Nextcloud kann man in zwei Szenarien installieren um es für alle Geräte auch von aussen Zugriff zu gewähren.

  1. Über den Router wird ein Port nach Innen zu einem Server weiter geleitet. Auf den freigegeben Port hört ein NextCloud-Service. Der NextCloud-Services besteht aus einer NGINX proxy, einer NextCloud Instanz und einer Datenbank für Nutzer- und Datenverwaltung.
  2. NextCloud hört nur in einem lokalen Intranet-Netzwerk. Von ausserhalb wird über ein VPN Zugang in das Intranet zugegriffen. In diesem Fall ist es Vorteilhaft, wenn der Internet-Router schon VPN Zugänge unterstützt.

Ein Port von aussen muss entsprechend auch sicher sein und gewartet werden. Ein VPN Dienst wird meistens von dem entsprechenden Router-Anbieter gepflegt. Aber auch das Client-Gerät oder Handy muss VPN unterstützen. Es gibt jedoch für die meistens VPN schon entsprechende Konfigurationen auf dem Handy.

Microservice

Nextcloud kann am Besten in einem Microservice, wie Docker oder Podman, gestartet werden. Es ist dann in seinem eigenen Bereich im Container eingeschränkt. Nexcloud braucht eine Datenbank. MySQL, Postgres oder andere Datenbanken sind hier als Datenbankspeicher möglich. Es liegt am Nutzer welche Datenbank er bevorzugt.

Eine docker-compose kann wie folgt aussehen:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2022-07-03T15:52:21Z"
  labels:
    app: nextcloud
  name: nextcloud_pod
spec:
  containers:
  - image: docker.io/library/nginx:latest
    name: nginx
    ports:
    - containerPort: 443
      hostPort: 7443
      protocol: tcp
    securityContext:
      capabilities:
        drop:
        - CAP_MKNOD
        - CAP_NET_RAW
        - CAP_AUDIT_WRITE
    env:
    - name: TZ
      value: "Europe/Berlin"
    volumeMounts:
    - mountPath: /etc/nginx/nginx.conf
      name: backup-nextcloud-nginx.conf.docker-host-0
    - mountPath: /etc/nginx/certs
      name: backup-nextcloud-certs-pv-host-1
    - mountPath: /var/log/nginx
      name: backup-nextcloud-nginx-logs-host-2
  - image: docker.io/library/nextcloud:31.0.5
    name: nextcloud
    securityContext:
      capabilities:
        drop:
        - CAP_MKNOD
        - CAP_NET_RAW
        - CAP_AUDIT_WRITE
    env:
    - name: TZ
      value: "Europe/Berlin"
    - name: DEBUG
      value: 'false'
    - name: NEXTCLOUD_URL
      value: 'https://test.example.com:7443'
    - name: NEXTCLOUD_ADMIN_USER
      value: 'admin'
    - name: NEXTCLOUD_ADMIN_PASSWORD
      value: 'changeit'
    - name: NEXTCLOUD_UPLOAD_MAX_FILESIZE
      value: '4G'
    - name: NEXTCLOUD_MAX_FILE_UPLOADS
      value: '20'
    - name: MYSQL_DATABASE
      value: 'nextcloud'
    - name: MYSQL_HOST
      value: 'localhost'
    - name: MYSQL_PASSWORD
      value: 'changeit'
    - name: MYSQL_USER
      value: 'nextcloud'
    volumeMounts:
    - mountPath: /var/www/html
      name: nextcloud-data
  - image: docker.io/library/mariadb:11.7.2
    name: elatedroentgen
    env:
    - name: TZ
      value: "Europe/Berlin"
    - name: MYSQL_ROOT_PASSWORD
      value: "changeit"
    - name: MYSQL_USERNAME
      value: "nextcloud"
    - name: MYSQL_PASSWORD
      value: "changeit"
    - name: MYSQL_DATABASE
      value: "nextcloud"
    securityContext:
      capabilities:
        drop:
        - CAP_MKNOD
        - CAP_NET_RAW
        - CAP_AUDIT_WRITE
    volumeMounts:
    - mountPath: /var/lib/mysql
      name: backup-nextcloud-db-host-0
    - mountPath: /var/lib/backup
      name: backup-nextcloud-backup-host-1
  volumes:
  - hostPath:
      path: /data/containers/nextcloud/nc-pv
      type: Directory
    name: nextcloud-data
  - hostPath:
      path: ./nextcloud/nginx.conf.podman
      type: File
    name: backup-nextcloud-nginx.conf.docker-host-0
  - hostPath:
      path: ./certs-pv
      type: Directory
    name: backup-nextcloud-certs-pv-host-1
  - hostPath:
      path: ./nginx-logs
      type: Directory
    name: backup-nextcloud-nginx-logs-host-2
  - hostPath:
      path: ./db
      type: Directory
    name: backup-nextcloud-db-host-0

und die nginx.conf.podman sieht wie folgt aus:

# Kubernetes proxy-config
#
# used for adding https security

user  www-data;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    keepalive_timeout  65;
    server {
        listen 443 ssl;
        access_log  /var/log/nginx/access.log;
        #root /var/www/html;

        # [warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive instead
        # ssl on;
        server_name <server namme>;
        ssl_certificate /etc/nginx/certs/nextcloud.crt;
        ssl_certificate_key /etc/nginx/certs/nextcloud.key;

        client_max_body_size 1G;

        proxy_connect_timeout 1200s;
        proxy_send_timeout 1200s;
        proxy_read_timeout 1200s;
        fastcgi_send_timeout 1200s;
        fastcgi_read_timeout 1200s;

        location / {
            proxy_pass http://localhost;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_buffering off;
            proxy_request_buffering off;

        }
        location ^~ /.well-known {
            # The following 6 rules are borrowed from `.htaccess`

            location = /.well-known/carddav     { return 301 https://test.example.com:7443/remote.php/dav/; }
            location = /.well-known/caldav      { return 301 https://test.example.com:7443/remote.php/dav/; }
            # Anything else is dynamically handled by Nextcloud
            location ^~ /.well-known            { return 301 /index.php$uri; }

            try_files $uri $uri/ =404;
        }
    }   
}

Regenerate certificates

podman run -it -e SSL_SUBJECT=<server name> -e CA_SUBJECT=<email> -e SSL_KEY=/certs/nextcloud.key -e SSL_CSR=/certs/nextcloud.csr -e SSL_CERT=/certs/nextcloud.crt -e SSL_EXPIRE=365 -v <container data>/nextcloud/certs-pv:/certs paulczar/omgwtfssl