> For the complete documentation index, see [llms.txt](https://docs.facephi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.facephi.com/docs.facephi-en/sdks/backend-sdk/selphid/installation/kubernetes_deployment.md).

# Deployment in Kubernetes

## 1. Introduction

Below is everything needed to install the SelphID SDK service in a Kubernetes environment.

## 2. Manual deployment

### 2.1 Introduction

We can deploy SelphID SDK in a Kubernetes cluster using the command `kubectl`:

```bash
kubectl apply -f manifest.yaml
```

Using a 'manifest.yaml' file similar to this:

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: selphid-sdk
---

apiVersion: v1
kind: Secret
metadata:
  name: license-secret
  namespace: selphid-sdk
stringData:
  stringData:
  # Write here your license content. E.g:
  license.lic: |-
    {
       "key":"XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX-XXXXXX",
       "type":"NODE_ONLINE"
    }
---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: selphid-sdk
  namespace: selphid-sdk
spec:
  replicas: 3
  selector:
    matchLabels:
      name: selphid-sdk
  template:
    metadata:
      labels:
        name: selphid-sdk
    spec:
      volumes:
        - name: license-volume
          secret:
            secretName: license-secret
            defaultMode: 420
        - name: config
          emptyDir:
            sizeLimit: 50Mi
      containers:
        - name: selphid-sdk-container-name
          # Use your image name and version
          image: >-
            selphid-sdk-rest-api:major.minor.patch
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          # Optional service configuration variables
          env:
            - name: FACEPHI_SELPHID_FACIALAUTHENTICATION_THRESHOLD
              value: '65'
            - name: FACEPHI_SELPHID_FACIALLIVENESS_THRESHOLD
              value: '60'

            # Only for 5.X versions
            - name: FACESDK_NUM_THREADS_ENGINE
              value: '8'

            # Only for 6.X versions
            - name: FACEPHI_SELPHID_FACIALEXTRACTOR_NUM_THREADS
              value: '8'
            - name: FACEPHI_SELPHID_FACIALLIVENESS_NUM_THREADS
              value: '8'

          resources:
            limits:
              cpu: 2096m
              memory: 4Gi
            requests:
              cpu: 1024m
              memory: 2Gi
          volumeMounts:
            - name: license-volume
              readOnly: true
              mountPath: /app/selphid-sdk/config/license.lic
              subPath: license.lic
            - name: config
              readOnly: false
              mountPath: /app/selphid-sdk/config
---

apiVersion: v1
kind: Service
metadata:
  name: selphid-service
  namespace: selphid-sdk
spec:
  ports:
    - name: http
      protocol: TCP
      port: 8080
      targetPort: 8080
  selector:
    app: selphid-sdk
  type: ClusterIP
---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: selphid-ingress
  namespace: selphid-sdk
  annotations:
    konghq.com/strip-path: "true"
spec:
  ingressClassName: kong
  rules:
    - host: core-test-selphid.facephi.dev
      http:
        paths:
          - path: /selphid
            pathType: Prefix
            backend:
              service:
                name: selphid-service
                port:
                  number: 8080
---
```

## 2.2 Secret

It is necessary to declare a Kubernetes secret where the license is passed to Kubernetes.

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: ocr-license-secret
  namespace: facephi-ocr-service
stringData:
  license.lic: |-
    # Json license content provided by Facephi
```

### 2.3 Volumes

It is necessary to map a volume in `/app/selphid-sdk/config`, where SelphID will read the license file and write the log information. By default, the path where the license file is stored is `/app/selphid-sdk/config/license.lic`.

```yaml
...
  spec:
    volumes:
      - name: license-volume
        secret:
          secretName: license-secret
          defaultMode: 420
      - name: config
        emptyDir:
          sizeLimit: 50Mi
...
    volumeMounts:
      - name: license-volume
        readOnly: true
        mountPath: /app/selphid-sdk/config/license.lic
        subPath: license.lic
      - name: config
        readOnly: false
        mountPath: /app/selphid-sdk/config
```

### 2.4 Environment variables

```yaml
    env:
    - name: FACEPHI_SELPHID_FACIALAUTHENTICATION_THRESHOLD
    value: '65'
    - name: FACEPHI_SELPHID_FACIALLIVENESS_THRESHOLD
    value: '60'
    - name: LICENSE_PATH
    value: /path/to/license
    - name: CONFIG_FILE
    value: /path/to/config/config.json
    - name: DEBUG_PATH
    value: /path/to/debug
    - name: USAGE_PATH
    value: /path/to/usage
    - name: FACEPHI_SELPHID_REST_AUTH_ENABLED
      value: 'true'
    - name: FACEPHI_SELPHID_REST_AUTH_JWT_SECRET
      value: shared-secret
    - name: FACEPHI_SELPHID_REST_AUTH_ACCEPT_AUTHORIZATION_HEADER
      value: 'true'
    - name: FACEPHI_SELPHID_REST_AUTH_ACCEPT_API_KEY_HEADER
      value: 'true'
    - name: FACEPHI_SELPHID_REST_AUTH_API_KEY_HEADER_NAME
      value: x-api-key
    - name: FACESDK_NUM_THREADS_ENGINE
      value: '8'
    - name: FACEPHI_SELPHID_FACIALEXTRACTOR_NUM_THREADS
      value: '8'
    - name: FACEPHI_SELPHID_FACIALLIVENESS_NUM_THREADS
      value: '8'
```

Each of them modifies an aspect of SelphID SDK's behavior:

* `FACEPHI_SELPHID_FACIALAUTHENTICATION_THRESHOLD`: Modifies the threshold when performing a FacialAuthentication. The default value is `65` (0-100).
* `FACEPHI_SELPHID_FACIALLIVENESS_THRESHOLD`: Modifies the threshold when performing a FacialLiveness. The default value is `50` (0-100).
* `LICENSE_PATH`: Alternative path where to look for the file `license.lic`. The default is `/app/selphid-sdk/config/license.lic`.
* `CONFIG_FILE`: Path to a custom configuration file for the REST API service. The default is `/app/selphid-sdk/config/config.json`
* `DEBUG_PATH`: Alternative path to store log files. The default is `/app/selphid-sdk/config`.
* `USAGE_PATH`: Alternative path to store usage files. The default is `/app/selphid-sdk/config`.
* `FACEPHI_SELPHID_REST_AUTH_ENABLED`, `FACEPHI_SELPHID_REST_AUTH_JWT_SECRET`, `FACEPHI_SELPHID_REST_AUTH_ACCEPT_AUTHORIZATION_HEADER`, `FACEPHI_SELPHID_REST_AUTH_ACCEPT_API_KEY_HEADER`, `FACEPHI_SELPHID_REST_AUTH_API_KEY_HEADER_NAME`: Optional configuration parameters for JWT authentication of the REST API, unique at startup.
* `FACESDK_NUM_THREADS_ENGINE`: Number of threads assigned to the Liveness service. **Only in versions `5.x`**. By default `4`.
* `FACEPHI_SELPHID_FACIALEXTRACTOR_NUM_THREADS`: Number of threads assigned to the Authentication service. **Only in versions `6.x`**. By default `4`.
* `FACEPHI_SELPHID_FACIALLIVENESS_NUM_THREADS`: Number of threads assigned to the Liveness service. **Only in versions `6.x`**. By default `4`.

### 2.5 Service

#### 2.5.1 LoadBalancer

We note that we will configure a LoadBalancer with Kong in front to access the SelphID SDK service. Note that the service is exposed on port `80` and targets the Pod on the `8080`.

```yaml
apiVersion: v1
kind: Service
metadata:
  name: selphid-service
  namespace: selphid-sdk
spec:
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8080
  selector:
    name: selphid-sdk
  type: ClusterIP
```

#### 2.5.2 Ingress

We configure an Ingress in front to redirect Kong requests to the service inside the Pod that we previously exposed on port 80.

## 3 Deployment using Helm chart

It is possible to automate the deployment of selphid in a Kubernetes cluster using the tool `helm`.

```bash
helm upgrade --install <release-name> selphid-sdk-1.0.0.tgz --namespace <namespace> --create-namespace --wait
```

where:

* `<release-name>`: Name to identify the installation.
* `<namespace>`: Kubernetes namespace where the deployment will be performed.
* `--create-namespace`: The namespace will be created if it does not exist.
* `--wait`: Waits until everything has started correctly before reporting any success message.

The file `selphid-sdk-1.0.0.tgz` will be provided for the deployment and will contain all the templates and configuration files necessary for `helm`.

```
selphid-sdk
├─ .helmignore
├─ Chart.yaml
├─ values.yaml
└─ templates
   ├─ deployment.yaml
   ├─ pvc.yaml
   ├─ secret.yaml
   ├─ service.yaml
   └─ serviceaccount.yaml
```

### 3.1 Chart.yaml

```yaml
apiVersion: v2
appVersion: 1.0.0
description: A Helm chart for SelphID SDK
name: selphid-sdk
type: application
version: 1.0.0
```

### 3.2 values.yaml

In this file you must configure the specific values for the deployment:

```yaml
replicaCount: 1

image:
  repository: selphid-sdk-rest-api
  pullPolicy: IfNotPresent
  tag: 6.8.0

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

license:

resources:
  limits:
    cpu: 4
    memory: 8192Mi
  requests:
    cpu: 2
    memory: 3072Mi

affinity:
  podAntiAffinity:
    enabled: true

nodeSelector: {}

tolerations: []

service:
  type: NodePort
  port: 8080
  nodePort: 32080

storage:
  class: standard
  capacity: 100Mi

serviceAccount:
  create: true
  annotations: {}
  name: ""

podAnnotations: {}

podSecurityContext: {}

securityContext: {}
```

## 4 Instance types

The recommended instance types for using the SelphID SDK service in production would be the following, where the SelphID SDK Pods that fit are shown depending on the instance type used.

| Instance type | CPU | Memory | SDK Pod capacity |
| ------------- | --- | ------ | ---------------- |
| c5.xlarge     | 4   | 8      | 2                |
| c5.2xlarge    | 8   | 16     | 4                |
| c5.4xlarge    | 16  | 32     | 9                |
