Getting Started#

Xandikos can either be run in a container (e.g. in docker or Kubernetes) or outside of a container.

It is recommended that you run it behind a reverse proxy, since Xandikos by itself does provide authentication support. See reverse-proxy for details.

Running from systemd#

Xandikos supports socket activation through systemd. To use systemd, run something like:

cp examples/xandikos.{socket,service} /etc/systemd/system
systemctl daemon-reload
systemctl enable xandikos.socket

Running from docker#

There is a docker image that gets regularly updated at ghcr.io/jelmer/xandikos.

If you use docker-compose, see the example configuration in examples/docker-compose.yml.

To run in docker interactively, try something like:

mkdir /tmp/xandikos
docker -it run ghcr.io/jelmer/xandikos -v /tmp/xandikos:/data

The following environment variables are supported by the docker image:

  • CURRENT_USER_PRINCIPAL: path to current user principal; defaults to “/$USER”

  • AUTOCREATE: whether to automatically create missing directories (“yes” or “no”)

  • DEFAULTS: whether to create a default directory hierarch with one

    calendar and one addressbook (“yes” or “no”)

  • ROUTE_PREFIX: HTTP prefix under which Xandikos should run

Running from kubernetes#

Here is an example configuration for running Xandikos in kubernetes:

---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: xandikos
spec:
 strategy:
   rollingUpdate:
     maxSurge: 1
     maxUnavailable: 1
   type: RollingUpdate
 replicas: 1
 selector:
   matchLabels:
     app: xandikos
 template:
   metadata:
     labels:
       app: xandikos
   spec:
     containers:
       - name: xandikos
         image: ghcr.io/jelmer/xandikos
         imagePullPolicy: Always
         command:
          - "python3"
          - "-m"
          - "xandikos.web"
          - "--port=8081"
          - "-d/data"
          - "--defaults"
          - "--listen-address=0.0.0.0"
          - "--current-user-principal=/jelmer"
          - "--route-prefix=/dav"
         resources:
           limits:
             cpu: "2"
             memory: "2Gi"
           requests:
             cpu: "0.1"
             memory: "10M"
         livenessProbe:
            httpGet:
              path: /health
              port: 8081
            initialDelaySeconds: 30
            periodSeconds: 3
            timeoutSeconds: 90
         ports:
           - containerPort: 8081
         volumeMounts:
           - name: xandikos-volume
             mountPath: /data
     volumes:
        - name: xandikos-volume
          persistentVolumeClaim:
           claimName: xandikos
---
apiVersion: v1
kind: Service
metadata:
  name: xandikos
  labels:
    app: xandikos
spec:
  ports:
    - port: 8081
      name: web
  selector:
    app: xandikos
  type: ClusterIP

If you’re using the prometheus operator, you may want also want to use this service monitor:

---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: xandikos
  labels:
    app: xandikos
spec:
  selector:
    matchLabels:
      app: xandikos
  endpoints:
  - port: web