Deployment Examples


There are many container orchestration tools suitable for Infinite Scale, e.g. Docker-Compose, Docker Swarm and Kubernetes.

Container orchestration tools are necessary to meet the requirements described in Availability and Scalability.

The pages
Docker Swarm vs Kubernetes: how to choose a container orchestration tool and
Kubernetes Vs. Docker Swarm: A Comparison of Containerization Platforms
can give a brief overview of their purpose, advantages and disadvantages of both tools.

In this section, we provide guidelines for using Infinite Scale with Docker-Compose and Kubernetes. For Kubernetes, there are already Helm Charts available that can be used and adjusted.

Docker Compose

Similar to when using docker run and handing over command-line parameters for a single container, you can define a docker-compose.yml yaml file which defines all the environment variables for each container in one file. This is the next step of multi-container environments.

Check if the package docker-compose is installed (in addition to docker):

which docker-compose

If Docker-Compose is installed, you’ll be informed. If not, you may get no output at all or a message that it couldn’t be found. In that case you need to install Docker-Compose first. On most Linux distributions, you can simply use the package manager to do so.

Create a project directory, e.g. ocis-compose in your home directory. Depending on your deployment intentions, pick configurations from our example docker compose files or a complete stack.

These are bundles of containers. For example, ocis_keycloak delivers Keycloak and Infinite Scale, running behind Traefik as reverse proxy. Traefik generates self-signed certificates for a local setup or obtains valid SSL certificates for a server setup. Keycloak acts as Identity Provider (IDP) and comes with a PostgreSQL database. In total, this stack consists of four containers.

In this example, you’ll need three domains set up. For experimenting with a local setup, you may want to simply add them to your /etc/hosts file. ocis.owncloud.test traefik.owncloud.test keycloak.owncloud.test

Download the ocis_keycloak files from GitHub into your project directory. Open the .env file in a text editor and adjust the environment variables according to your wishes. The default configuration looks like this:

version: "3.7"

    image: traefik:v2.9.1
          - ${OCIS_DOMAIN:-ocis.owncloud.test}
          - ${KEYCLOAK_DOMAIN:-keycloak.owncloud.test}
      - "--log.level=${TRAEFIK_LOG_LEVEL:-ERROR}"
      # letsencrypt configuration
      - "${}"
      - ""
      - "--certificatesResolvers.http.acme.httpChallenge.entryPoint=http"
      # enable dashboard
      - "--api.dashboard=true"
      # define entrypoints
      - "--entryPoints.http.address=:80"
      - ""
      - "--entryPoints.http.http.redirections.entryPoint.scheme=https"
      - "--entryPoints.https.address=:443"
      # docker provider (get configuration from container labels)
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedByDefault=false"
      # access log
      - "--accessLog=true"
      - "--accessLog.format=json"
      - "--accessLog.fields.headers.names.X-Request-Id=keep"
      - "80:80"
      - "443:443"
      - "${DOCKER_SOCKET_PATH:-/var/run/docker.sock}:/var/run/docker.sock:ro"
      - "certs:/certs"
      - "traefik.enable=${TRAEFIK_DASHBOARD:-false}"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_BASIC_AUTH_USERS:-admin:$$apr1$$4vqie50r$$YQAmQdtmz5n9rEALhxJ4l.}" # defaults to admin:admin
      - "traefik.http.routers.traefik.entrypoints=https"
      - "traefik.http.routers.traefik.rule=Host(`${TRAEFIK_DOMAIN:-traefik.owncloud.test}`)"
      - "traefik.http.routers.traefik.middlewares=traefik-auth"
      - "traefik.http.routers.traefik.tls.certresolver=http"
      - "traefik.http.routers.traefik.service=api@internal"
      driver: ${LOG_DRIVER:-local}
    restart: always

    image: owncloud/ocis:${OCIS_DOCKER_TAG:-latest}
      - /bin/sh
    # run ocis init to initialize a configuration file with random secrets
    # it will fail on subsequent runs, because the config file already exists
    # therefore we ignore the error and then start the ocis server
    command: ["-c", "ocis init || true; ocis server"]
      # Keycloak IDP specific configuration
      OCIS_OIDC_ISSUER: https://${KEYCLOAK_DOMAIN:-keycloak.owncloud.test}/realms/${KEYCLOAK_REALM:-oCIS}
      # general config
      OCIS_URL: https://${OCIS_DOMAIN:-ocis.owncloud.test}
      OCIS_LOG_COLOR: "${OCIS_LOG_COLOR:-false}"
      PROXY_TLS: "false" # do not use SSL between Traefik and oCIS
      # INSECURE: needed if oCIS / Traefik is using self generated certificates
      OCIS_INSECURE: "${INSECURE:-false}"
      - ocis-config:/etc/ocis
      - ocis-data:/var/lib/ocis
      - "traefik.enable=true"
      - "traefik.http.routers.ocis.entrypoints=https"
      - "traefik.http.routers.ocis.rule=Host(`${OCIS_DOMAIN:-ocis.owncloud.test}`)"
      - "traefik.http.routers.ocis.tls.certresolver=http"
      - "traefik.http.routers.ocis.service=ocis"
      - ""
      driver: ${LOG_DRIVER:-local}
    restart: always

    image: postgres:alpine
      - keycloak_postgres_data:/var/lib/postgresql/data
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: keycloak
      driver: ${LOG_DRIVER:-local}
    restart: always

    command: ["start", "--proxy edge", "--import-realm"]
    entrypoint: ["/bin/sh", "/opt/keycloak/bin/"]
      - "./config/keycloak/"
      - "./config/keycloak/ocis-realm.dist.json:/opt/keycloak/data/import-dist/ocis-realm.json"
      OCIS_DOMAIN: ${OCIS_DOMAIN:-ocis.owncloud.test}
      KC_HOSTNAME: ${KEYCLOAK_DOMAIN:-keycloak.owncloud.test}
      KC_DB: postgres
      KC_DB_URL: "jdbc:postgresql://postgres:5432/keycloak"
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: keycloak
      KC_FEATURES: impersonation
      - "traefik.enable=true"
      - "traefik.http.routers.keycloak.entrypoints=https"
      - "traefik.http.routers.keycloak.rule=Host(`${KEYCLOAK_DOMAIN:-keycloak.owncloud.test}`)"
      - "traefik.http.routers.keycloak.tls.certresolver=http"
      - "traefik.http.routers.keycloak.service=keycloak"
      - ""
      - postgres
      driver: ${LOG_DRIVER:-local}
    restart: always



If you are installing Infinite Scale on a server and Traefik will obtain valid certificates for you, remove INSECURE=true or set it to false.

If you want to use the Traefik dashboard, set TRAEFIK_DASHBOARD=true. Default is false and therefore the dashboard is not active. If you activate it, you must set a domain for the Traefik dashboard in TRAEFIK_DOMAIN=, e.g. TRAEFIK_DOMAIN=traefik.owncloud.test.

The Traefik dashboard is secured by basic auth. Default credentials are the user admin with the password admin. To set your own credentials, generate a htpasswd, e.g. by using an online tool or a command-line tool.

Traefik will issue certificates with LetsEncrypt and therefore you must set an email address in TRAEFIK_ACME_MAIL=.

By default Infinite Scale will be started with the latest version. If you want to start a specific version set it with OCIS_DOCKER_TAG=. Available versions can be found on Docker Hub.

Set your domain for the Infinite Scale frontend in OCIS_DOMAIN=, e.g. OCIS_DOMAIN=ocis.owncloud.test.

If you want to change the OIDC client ID of the ownCloud Web frontend, specify the name with OCIS_OIDC_CLIENT_ID=.

Set your domain for the Keycloak administration panel and authentication endpoints with KEYCLOAK_DOMAIN=, e.g. KEYCLOAK_DOMAIN=keycloak.owncloud.test.

Changing the used Keycloak realm can be done by setting KEYCLOAK_REALM=. This defaults to the Infinite Scale realm KEYCLOAK_REALM=oCIS. The Infinite Scale realm will be automatically imported on startup and includes our demo users.

You should secure your Keycloak admin account by setting KEYCLOAK_ADMIN_USER= and KEYCLOAK_ADMIN_PASSWORD= to values other than admin.

When you’re done with the configuration, save the file and start the application stack from the project directory with docker-compose up -d. For more details see Docker Compose.

Check out the other container stacks on GitHub as well and adjust them to your needs.

ownCloud provides some example docker compose files as a starting point and guidance for your own setup. Change the data according your needs. Check the Infinite Scale version when using a template for production environments.

Kubernetes and Helm Charts

Kubernetes (K8s) is an open-source platform for managing containers that run applications. It ensures there is no downtime and an optimal usage of resources. It offers a framework in which to run distributed systems. ownCloud Infinite Scale (Infinite Scale) was designed with Kubernetes in mind. Therefore we provide Helm charts for a convenient deployment of Infinite Scale on a Kubernetes cluster.

For more information on Kubernetes (K8s) features, check out Why you need Kubernetes and what it can do. If that is too abstract, there is an ELI5 writeup.

We also recommend Marcel Wunderlich’s 4 series articles on Kubernetes, clarifying its declarative nature, deep-diving into ingress networking, storage and monitoring.

Also see the Deployment Evolution section in our Availability and Scalability guide.

Infinite Scale follows the Twelve-Factor App principles regarding configuration, which means almost every aspect of Infinite Scale is modifiable via environment variables. This comes in handy when you look at how a helm chart’s list of values looks like.


For efficient use of Infinite Scale with Kubernetes, you either need to install Kubernetes directly or minikube. Since a full-fledged Kubernetes setup is far beyond the scope of this documentation, we assume you have already a Kubernetes cluster running or you want to experiment with minikube.


minikube lets you run a single-node Kubernetes cluster locally. It is the most approachable way to test a deployment. It requires no extra configuration on any cloud platform as everything runs on your local machine.


kubectl is the command-line tool for Kubernetes. It allows users to run commands against a K8s cluster. It supports multiple contexts for as many clusters as you have access to. minikube also provides kubectl wrapped as minikube kubectcl.

Helm Charts

Helm is the equivalent of a package manager for Kubernetes. It can be described as a layer on top of how you would write pods, deployments or any other K8s resource declaration.

Deploying minikube

Follow the official instructions on how to set up minikube for your specific OS.

Verify your installation is correct:

minikube status
type: Control Plane
host: Stopped
kubelet: Stopped
apiserver: Stopped
kubeconfig: Stopped

Next, start the cluster:

minikube start
minikube v1.25.2 on Ubuntu 20.04
Using the docker driver based on existing profile
Starting control plane node minikube in cluster minikube
Pulling base image ...
Restarting existing docker container for "minikube" ...
Preparing Kubernetes v1.23.3 on Docker 20.10.12 ...
▪ kubelet.housekeeping-interval=5m
Verifying Kubernetes components...
▪ Using image
Enabled addons: storage-provisioner, default-storageclass
kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

Using Helm Charts with Infinite Scale

Installing Helm

To install Helm, refer to the official guide Installing Helm.

The easiest way to run the entire Infinite Scale package is by using the available charts. It is not the purpose of this guide to explain the inner workings of Kubernetes or its resources as Helm builds an abstraction on top of it, letting you interact with a refined interface that roughly translates to "helm install" and "helm uninstall".

To host charts, one can create a charts repository, but this is also beyond the scope of this documentation.


  • minikube up and running.

  • kubectl installed. minikube wraps kubectl as minikube kubectl. By default you should be able to access the minikube cluster.

  • Helm cli installed.

  • git installed.


  1. Clone the charts:

    git clone /var/tmp/ocis-charts
  2. Change directory into the charts' root:

    cd /var/tmp/ocis-charts/charts/ocis
  3. Install the package:

    helm install ocis .
  4. Verify the application is running in the cluster with:

    minikube kubectl get pods
    NAME                                     READY   STATUS    RESTARTS        AGE
    glauth-55d7b5878c-25qnt                  1/1     Running   1 (2d23h ago)   2d23h
    graph-859855c94d-l5xgt                   1/1     Running   2 (9m21s ago)   2d23h
    idp-7759f4c6b9-l25t4                     1/1     Running   1 (2d23h ago)   2d23h
    nats-6857bc5f8f-5s597                    1/1     Running   1 (2d23h ago)   2d23h
    ocs-8454747c4b-wxwms                     1/1     Running   2 (9m21s ago)   2d23h
    proxy-79df886fb4-njr9p                   1/1     Running   2 (9m23s ago)   2d23h
    settings-79597cb89d-ttvmm                1/1     Running   2 (9m23s ago)   2d23h
    storage-authbasic-6c4ccd4dc6-rwlhx       1/1     Running   1 (2d23h ago)   2d23h
    storage-authbearer-6f79cd5cc6-ldz7h      1/1     Running   1 (2d23h ago)   2d23h
    storage-authmachine-7cf95d8d89-qsxnj     1/1     Running   1 (2d23h ago)   2d23h
    storage-frontend-64d44f8f66-vnndm        1/1     Running   1 (2d23h ago)   2d23h
    storage-gateway-668b47f76f-2tvj2         1/1     Running   1 (2d23h ago)   2d23h
    storage-groupprovider-7475b4dddf-wj2g7   1/1     Running   1 (2d23h ago)   2d23h
    storage-metadata-74f6b5f489-rbsp4        1/1     Running   2 (9m19s ago)   2d23h
    storage-publiclink-f497dd5dd-flrw5       1/1     Running   1 (2d23h ago)   2d23h
    storage-shares-69d8b67d6b-rhq98          1/1     Running   1 (2d23h ago)   2d23h
    storage-sharing-5567d9b7f-978bf          1/1     Running   1 (2d23h ago)   2d23h
    storage-userprovider-59d87db58f-h7lpd    1/1     Running   1 (2d23h ago)   2d23h
    storage-users-7989b5df8-78hwc            1/1     Running   1 (2d23h ago)   2d23h
    store-6b878df78c-7cdlb                   1/1     Running   1 (2d23h ago)   2d23h
    thumbnails-7d5799b64b-wj9dx              1/1     Running   1 (2d23h ago)   2d23h
    web-967b76f6c-rgq9h                      1/1     Running   1 (2d23h ago)   2d23h
    webdav-9c494b5c-6r8r6                    1/1     Running   2 (9m21s ago)   2d23h
  5. Expose the proxy as a service to the host:

    minikube service proxy-service --url
     Starting tunnel for service proxy-service.
    | NAMESPACE |     NAME      | TARGET PORT |          URL           |
    | default   | proxy-service |             | |
  6. Attempt a PROPFIND WebDAV request to the storage. Note this example uses one of the demo users as described in Create Demo Users and Groups:

    curl -v -k -u einstein:relativity -H "depth: 0" -X \
        PROPFIND | \
        xmllint --format -

    If all is correctly setup, you should get a response like the following:

    <?xml version="1.0" encoding="utf-8"?>
    <d:multistatus xmlns:d="DAV:" xmlns:s="" xmlns:oc="">
            <d:getlastmodified>Tue, 14 Sep 2021 12:45:29 +0000</d:getlastmodified>
          <d:status>HTTP/1.1 200 OK</d:status>

    The above setup works because the proxy is configured to run using basic authentication. To access the WebUI, you need an external identity provider.

With the command minikube dashboard you start the monitoring dashboard for your cluster in a browser. With minikube stop you’re shutting down the minikube node.