Skip to content

Installing on kubernetes

Install and start Minikube

You can use minikube to spin up a local Kubernetes cluster for development and testing purposes. Follow the Get started! guide to install and start minikube (minikube start) on your machine. You can check that minikube is running with minikube status:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

and that kubectl is properly configured to use minikube by getting the cluster information:

kubectl cluster-info

and listing existing resources:

kubectl get all --all-namespaces

Load the boidas docker image

If you've received the Boidas release as a .zip package, please extract the Docker image (a .tar file named Boidas-DockerImage-<version>.tar) somewhere on your machine and run:

docker load -i Boidas-DockerImage-<version>.tar

(change the version as needed)

You should see the following message:

Loaded image: boidas:<version>

You can now tag the image as latest:

docker tag boidas:<version> boidas:latest

and load it on the minikube cluster:

minikube image load boidas:latest

The image is now ready to be used on your local minikube cluster.

Deploy Boidas

1. Create a namespace

Start by creating a boidas namespace to hold all the resources associated to this example:

kubectl create namespace boidas

or using a YAML manifest file.

2. Create and configure the manifest file

Create a file named boidas.yaml with the following content:

---
apiVersion: v1
kind: Service
metadata:
  name: boidas
spec:
  selector:
    app: boidas
  ports:
    - port: 8443
      protocol: TCP
      targetPort: 8443
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: boidas
  labels:
    app: boidas
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: boidas
  template:
    metadata:
      name: boidas
      labels:
        app: boidas
    spec:
      initContainers:
        - name: boidas-init-volumes
          image: busybox
          command: ['sh', '-c', 'chown 33:33 /opt/boidas_backend/media /var/log/boidas && chmod 775 /opt/boidas_backend/media /var/log/boidas']
          volumeMounts:
            - mountPath: /opt/boidas_backend/media
              name: boidas-media
            - mountPath: /var/log/boidas
              name: boidas-logs
      containers:
        - name: boidas-postgresql
          image: postgres:15.5
          env:
            - name: POSTGRES_USER
              value: "boidas"
            - name: POSTGRES_DB
              value: "boidas"
            - name: POSTGRES_PASSWORD
              value: "boidas"
          ports:
            - containerPort: 5432
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: boidas-pgdata
        - name: boidas-api
          image: boidas:latest
          imagePullPolicy: IfNotPresent
          env:
            - name: DB_HOST
              value: "localhost"
            - name: DB_USER
              value: "boidas"
            - name: DB_PASS
              value: "boidas"
            - name: DB_NAME
              value: "boidas"
            - name: WORKERS
              value: "1"
            - name: ENABLE_SSL
              value: "TRUE"
            - name: VALIDAS_URL
              value: "https://api-work.eu.veri-das.com/validas/v1"
            - name: API_KEY
              value: "your API key here"
            - name: BASE_URL
              value: "https://localhost:8443"
            - name: MIGRATIONS
              value: "yes"
            - name: TZ
              value: "Europe/Madrid"
            - name: EMAIL_HOST_NAME
              value: "your server name here"
            - name: EMAIL_HOST_PORT
              value: "your server port here"
            - name: EMAIL_HOST_USER
              value: "your email here"
            - name: EMAIL_HOST_PASSWORD
              value: "your email pass here"
            - name: LOG_INTEGRITY_KEY
              value: "/var/keys/public_key.pem"
          ports:
            - name: api-port
              containerPort: 8850
          livenessProbe:
            httpGet:
              scheme: HTTPS
              path: /api/v1/alive
              port: api-port
            failureThreshold: 3
            periodSeconds: 10
            timeoutSeconds: 10
          startupProbe:
            httpGet:
              scheme: HTTPS
              path: /api/v1/alive
              port: api-port
            failureThreshold: 30
            periodSeconds: 10
            timeoutSeconds: 10
          volumeMounts:
          - mountPath: /opt/boidas_backend/media
            name: boidas-media
          - mountPath: /var/log/boidas
            name: boidas-logs
          - mountPath: "/var/keys"
            name: boidas-integrity-key
            readOnly: true
        - name: boidas-nginx
          image: boidas:latest
          imagePullPolicy: IfNotPresent
          env:
            - name: SERVER_NAME
              value: "localhost"
            - name: NGINX_UPSTREAM
              value: "localhost"
            - name: PORT
              value: "8850"
          ports:
            - containerPort: 8443
          command: ["/opt/boidas_backend/run_nginx.sh"]
      volumes:
        - name: boidas-media
          persistentVolumeClaim:
            claimName: boidas-media
        - name: boidas-logs
          persistentVolumeClaim:
            claimName: boidas-logs
        - name: boidas-pgdata
          persistentVolumeClaim:
            claimName: boidas-pgdata
        - name: boidas-integrity-key
          secret:
            secretName: boidas-integrity-key

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: boidas-pgdata
  labels:
    type: local
spec:
  storageClassName: ""
  claimRef:
    namespace: boidas
    name: boidas-pgdata
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data/boidas/pgdata
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: boidas-pgdata
  labels:
    type: local
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  volumeName: boidas-pgdata
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: boidas-media
  labels:
    type: local
spec:
  storageClassName: ""
  claimRef:
    namespace: boidas
    name: boidas-media
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data/boidas/media
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: boidas-media
  labels:
    type: local
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  volumeName: boidas-media
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: boidas-logs
  labels:
    type: local
spec:
  storageClassName: ""
  claimRef:
    namespace: boidas
    name: boidas-logs
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data/boidas/logs
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: boidas-logs
  labels:
    type: local
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
  volumeName: boidas-logs
---
apiVersion: v1
kind: Secret
type: Opaque
data:
  public_key.pem: <contents of public_key.pem encoded in base64>
metadata:
  name: boidas-integrity-key
  namespace: boidas

This manifest creates:

  • a service to access the Boidas web interface (on port 8443).
  • a deployment that runs a pod with containers for the Boidas API (boidas-api), a web server for static content (boidas-nginx) and a PostgreSQL database (boidas-postgresql). This deployment also uses an init container to fix permissions/ownership on persistent volumes (this is needed in order to avoid running Boidas as root).
  • persistent volumes (and their corresponding claims) for Boidas media (validation images, videos, etc.), service logs and PostgreSQL data.

You may want to customize the following environment variables for the boidas-api container:

  • VALIDAS_URL: The URL to the Validas instance to fetch validations from. By default this points to the VeriSaaS sandbox environment (work)
  • API_KEY: Your API key for VeriSaaS on the environment (e.g. work) corresponding to VALIDAS_URL

3. Apply changes

You can create all the Kubernetes resources from the manifest file (boidas.yaml) defined on the previous step by running kubectl apply:

kubectl apply -f boidas.yaml --namespace boidas

4. Ensure boidas is running and get login credentials

After applying, you can check that the Boidas pod is running with:

kubectl -n boidas get pods

The expected output should be:

NAME                      READY   STATUS    RESTARTS   AGE
boidas-6c696b965c-hjcl4   3/3     Running   0          3h17m

(the name of the pod will change with every deployment)

You can view the logs from the boidas API with:

kubectl -n boidas logs boidas-6c696b965c-hjcl4 -c boidas-api

The first time the pod is started, the boidas-api container will initialize the database and create a default admin user and OAuth credentials. You can find them on the output from the command above. For example:

create_credentials
BOI-DAS SUPERUSER: admin
BOI-DAS SUPERUSER EMAIL: it@veridas.com
BOI-DAS SUPERUSER PASSWORD: 4ucSchV4PnzVM0ZYRLqFGrVs
BOI-DAS API SUPERUSER: admin
BOI-DAS API OAUTH2 CLIENT_ID: ISXyFVNqvuwMXkDcOblTDLf8
BOI-DAS API OAUTH2 CLIENT_SECRET: uGIQe3vnxMU90zMaxXanMVa47oRFHUB6qXaUdwDe2NTOBLze

Save these credentials, you'll use them later to login to Boidas.

5. Access the service

You can use kubectl port-forward to create a tunnel between your machine and the the Boidas service running on the Kubernetes cluster to access the Boidas web interface:

kubectl port-forward -n boidas svc/boidas 8443:8443

You can open the URL https://localhost:8443 on your favorite browser to navigate to the Boidas login page.

Note: Since Boidas uses self-signed HTTPS certificates by default, your browser will ask you to accept the security exception before showing the page.

You can login with the credentials (BOI-DAS SUPERUSER/BOI-DAS SUPERUSER PASSWORD) obtained from the boidas-api container logs on the previous step of this guide.

Use your own TLS certificate (optional)

By default, the template used on this guide configures the boidas web server (boidas-nginx) to serve HTTPS traffic on port 8443 using a self-signed certificate bundled on the Docker image (you can find it on /etc/boidas/security/certs). Follow the next steps if you want to use your own certificate instead:

1. Create a secret with your certificate

You can create a secret (boidas-nginx-cert) with the contents of your certificate (a file named server.crt) and private key (server.key) with kubectl:

kubectl -n boidas create secret generic boidas-nginx-cert --from-file=server.crt --from-file=server.key

Please note that we're creating the secret on the boidas namespace (-n boidas). You can verify that the secret has been succesfully created with:

kubectl -n boidas get secret -o yaml boidas-nginx-cert

The output should be similar to:

apiVersion: v1
data:
  server.crt: <contents of server.crt encoded in base64>
  server.key: <contents of server.key encoded in base64>
kind: Secret
metadata:
  creationTimestamp: "2021-07-08T07:46:16Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:server.crt: {}
        f:server.key: {}
      f:type: {}
    manager: kubectl-create
    operation: Update
    time: "2021-07-08T07:46:16Z"
  name: boidas-nginx-cert
  namespace: boidas
  resourceVersion: "58097"
  uid: 098bd579-3904-422d-8bb3-21c9156bde45
type: Opaque

You can also define your secret using a YAML manifest. You need to convert the contents of server.crt and server.key to base64 (cat server.crt | base64 on Linux) and then create a YAML file (boidas-nginx-cert.yaml for example) with:

apiVersion: v1
kind: Secret
type: Opaque
data:
  server.crt: <contents of server.crt encoded in base64>
  server.key: <contents of server.key encoded in base64>
metadata:
  name: boidas-nginx-cert
  namespace: boidas

Please ensure you do not store secrets (server.key in this case) on source code management tools like git.

2. Mount the secret as a volume

In order to use your certificate (stored as a Kubernetes secret), you must mount it as a volume on the boidas-nginx container under the /etc/boidas/security/certs path. Edit the example YAML manifest and define a new volume on the volumes: section of the Deployment resource:

      volumes:
        - name: boidas-media
          persistentVolumeClaim:
            claimName: boidas-media
        - name: boidas-logs
          persistentVolumeClaim:
            claimName: boidas-logs
        - name: boidas-pgdata
          persistentVolumeClaim:
            claimName: boidas-pgdata
        - name: boidas-nginx-cert
          secret:
            secretName: boidas-nginx-cert

And mount this volume on the boidas-nginx container:

        - name: boidas-nginx
          image: boidas:latest
          imagePullPolicy: IfNotPresent
          env:
            - name: SERVER_NAME
              value: "localhost"
            - name: NGINX_UPSTREAM
              value: "localhost"
            - name: PORT
              value: "8850"
          volumeMounts:
          - name: boidas-nginx-cert
            mountPath: "/etc/boidas/security/certs"
            readOnly: true
          ports:
            - containerPort: 8443
          command: ["/opt/boidas_backend/run_nginx.sh"]

Once you've done these changes, you can apply them with:

kubectl apply -f boidas-example.yaml --namespace boidas

3. Check the HTTPS certificate has been mounted successfully

You can check that the HTTPS certificate secret has been mounted as a volume on the boidas-nginx container by opening a shell:

kubectl -n boidas exec -it $(kubectl -n boidas get pods --selector="app=boidas" --output=jsonpath={.items..metadata.name}) -c boidas-nginx -- bash

and then:

ls -al /etc/boidas/security/certs/

You should see something like:

total 4
drwxrwxrwt 3 root root  120 Jul  8 08:14 .
drwxr-xr-x 1 root root 4096 May 27 07:11 ..
drwxr-xr-x 2 root root   80 Jul  8 08:14 ..2021_07_08_08_14_01.115478538
lrwxrwxrwx 1 root root   31 Jul  8 08:14 ..data -> ..2021_07_08_08_14_01.115478538
lrwxrwxrwx 1 root root   17 Jul  8 08:14 server.crt -> ..data/server.crt
lrwxrwxrwx 1 root root   17 Jul  8 08:14 server.key -> ..data/server.key

If you now open the website on your browser, you should see the information of your certificate on the address bar.