Zum Inhalt

Family synchronize calendar and contacts

My family has different calendar appointments. It may be doctor appointments or kids need to date with friends or even birthdays which may be misremembered by the kids. Everything needs to be organized. Important is to gain the overview. The dates need to be availabe for all favours of operating systems like Windows, Android oder iOS, all can use calender.

Especially on Apple hardware there ical is available for calendar management. On the PC, Mac or mobile device all data should not be in the cloud. It should be synchronized using my local environment. It should run on a small device like an NAS or the Raspberry Pi. Contacts or some calendar appointments should be seen by all family members but some should be user specific.

NextCloud

To get this and much more I installed Nextcloud. With Nextcloud it is possible to synchronize calendar, contacts, notes and files. You can install a number of add-ons to handle different specific stuff.

Nextcloud can be used in two difference scenarios dependent to the security level or access infrastructure you would like to use

  1. You can define the router port to be redirected to the Nextcloud service running inside your local environment. The Nextcloud server is proxied using the NGINX proxy service. In this case you need to install Nextcloud, NGINX and a database for User and data management inside a Docker-compose container or Podman pod.
  2. NextCloud may be not accessible from outside the internet. Instead you can establish a private VPN network using this network to connect from a laptop or Mobile to your private network. In this case you gain the benefit to access other resources beside Nextcloud as well.

A port visible from outside must be save and good maintained. A VPN service is include in the router and is maintained by the router service at best. The corresponding VPN client should be available on Laptop device or smartphone devices. There are some good working example for VPN on IOS and Android already.

Microservice

Nextcloud run good in a Microservice. You only need to pull a new image and restart the container. If it fails you can step back and start the old image to restart. In addition it is only limited to the container area. It's not safe but more safe then other approaches. Nextcloud needs a database. MySQL, Postgres or other database are possible to use.

A docker-compose can look like this:

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;
        }
    }   
}

Here is a script to regenerate self-signed 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