Deploy Smartbox with Kubernetes
The guide covers only Smartbox mandatory components deployment in k8s
This guide shows how to deploy Smartbox in minimal configuration. One instance of PostgreSQL and a two instances of Aidbox (Sandbox and Portal).
To have a production-ready deployment there also should be:
Database and Aidbox replicas
Expose Smartbox to the Internet
This guide does not define exposing Smartbox to the Internet
Prerequisites
kubectl
utility is installed
Prebuilt k8s configuration
Run the command kubectl apply -f smartbox.yaml
The smartbox.yaml
is the k8s compiled templates configuration. The configuration components contained in the file are defined further in this guide
Smartbox mandatory ENVs
Common for Portal & Sandbox
Sandbox specific
AIDBOX_BASE_URL: http://sandbox
AIDBOX_ZEN_ENTRYPOINT: 'smartbox.dev-portal/box'
AIDBOX_CLIENT_ID: sandbox-client
AIDBOX_CLIENT_SECRET: sandbox-secret
BOX_AUTH_LOGIN__REDIRECT: "/"
Portal specific
AIDBOX_BASE_URL: http://smartbox
AIDBOX_CLIENT_ID: portal-client
AIDBOX_CLIENT_SECRET: portal-secret
BOX_SMARTBOX_SANDBOX__URL: http://sandbox
BOX_SMARTBOX_SANDBOX__BASIC: 'sandbox-client:sandbox-secret'
All the available environment variables are defined here
Components templates
Database (PostgreSQL)
Smartbox (as an Aidbox configuration) requires an instance of running PostgreSQL. There should be two databases on a PostgreSQL cluster:
First is for Sandbox
instance
Second is for Portal
instance
Volume
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: aidboxdb-data
namespace: smartbox
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
ENVs
kind: ConfigMap
metadata:
name: aidboxdb-envs
namespace: smartbox
apiVersion: v1
data:
POSTGRES_DB: postgres
PGDATA: /data/pg
kind: Secret
apiVersion: v1
metadata:
name: aidboxdb-envs
namespace: smartbox
data:
POSTGRES_USER: cG9zdGdyZXM= # base64 encoded string postgres
POSTGRES_PASSWORD: cG9zdGdyZXM= # base64 encoded string postgres
Config
kind: ConfigMap
apiVersion: v1
metadata:
name: aidboxdb-config
namespace: smartbox
data:
postgres.conf: |-
listen_addresses = '*'
max_replication_slots = 30
max_wal_senders = 30
max_wal_size = '1GB'
max_worker_processes = 128
pg_stat_statements.max = 500
pg_stat_statements.save = false
pg_stat_statements.track = top
pg_stat_statements.track_utility = true
shared_buffers = '1GB'
shared_preload_libraries = 'pg_stat_statements'
synchronous_commit = off
track_io_timing = on
wal_level = logical
wal_log_hints = on
StatefulSet
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: aidboxdb
namespace: smartbox
spec:
replicas: 1
selector:
matchLabels:
service: aidboxdb
serviceName: aidboxdb
template:
metadata:
labels:
service: aidboxdb
spec:
containers:
- name: main
imagePullPolicy: Always
image: healthsamurai/aidboxdb:14.5
volumeMounts:
- name: db-data
mountPath: /data
subPath: pg
- name: aidboxdb-config
mountPath: /etc/configs
- name: db-dshm
mountPath: /dev/shm
readinessProbe:
exec:
command:
- bash
- -c
- psql -c 'SELECT 1'
initialDelaySeconds: 10
timeoutSeconds: 2
envFrom:
- configMapRef:
name: aidboxdb-envs
- secretRef:
name: aidboxdb-envs
ports:
- containerPort: 5432
protocol: TCP
resources:
requests:
memory: 1Gi
volumes:
- name: db-data
persistentVolumeClaim:
claimName: aidboxdb-data
- name: aidboxdb-config
configMap:
name: aidboxdb-config
- name: db-dshm
emptyDir:
medium: Memory
Service
kind: Service
apiVersion: v1
metadata:
name: aidboxdb
namespace: smartbox
spec:
selector:
service: aidboxdb
ports:
- protocol: TCP
targetPort: 5432
port: 5432
Sandbox
ENVs
kind: ConfigMap
apiVersion: v1
metadata:
name: sandbox
namespace: smartbox
data:
BOX_ID: aidboxone
AIDBOX_ZEN_ENTRYPOINT: 'smartbox.dev-portal/box'
BOX_AUTH_LOGIN__REDIRECT: "/"
PGHOST: aidboxdb
PGDATABASE: sandbox
AIDBOX_STDOUT_PRETTY: 'true'
AIDBOX_PORT: '8080'
AIDBOX_BASE_URL: 'http://sandbox'
PGPORT: '5432'
AIDBOX_FHIR_VERSION: 4.0.1
BOX_PROVIDER_DEFAULT_TYPE: mailgun
apiVersion: v1
kind: Secret
metadata:
name: sandbox
namespace: smartbox
type: Opaque
data:
PGUSER: cG9zdGdyZXM= # base64 encoded postgres
PGPASSWORD: cG9zdGdyZXM= # base64 encoded postgres
AIDBOX_ADMIN_ID: YWRtaW4= # base64 encoded admin
AIDBOX_ADMIN_PASSWORD: cGFzc3dvcmQ= # base64 encoded password
AIDBOX_CLIENT_ID: cm9vdA== # base64 encoded root
AIDBOX_CLIENT_SECRET: c2VjcmV0 # base64 encoded secret
AIDBOX_LICENSE: # your base64 encoded lincense
# your base64 encoded email provider secrets
BOX_PROVIDER_DEFAULT_URL:
BOX_PROVIDER_DEFAULT_FROM:
BOX_PROVIDER_DEFAULT_USERNAME:
BOX_PROVIDER_DEFAULT_PASSWORD:
Service
kind: Service
apiVersion: v1
metadata:
name: sandbox
namespace: smartbox
spec:
selector:
service: sandbox
ports:
- protocol: TCP
targetPort: 8080
port: 80
Deployment
kind: Deployment
apiVersion: apps/v1
metadata:
name: sandbox
namespace: smartbox
spec:
replicas: 1
selector:
matchLabels:
service: sandbox
template:
metadata:
labels:
service: sandbox
spec:
containers:
- readinessProbe:
httpGet:
scheme: HTTP
path: /health
port: 8080
initialDelaySeconds: 20
timeoutSeconds: 10
periodSeconds: 10
failureThreshold: 6
envFrom:
- configMapRef:
name: sandbox
- secretRef:
name: sandbox
name: main
ports:
- containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
scheme: HTTP
path: /health
port: 8080
initialDelaySeconds: 20
timeoutSeconds: 10
periodSeconds: 10
failureThreshold: 12
imagePullPolicy: Always
image: healthsamurai/smartbox:edge
Portal
ENVs
kind: ConfigMap
apiVersion: v1
metadata:
name: smartbox
namespace: smartbox
data:
BOX_INSTANCE_NAME: smartbox
BOX_ID: aidboxone
AIDBOX_ZEN_ENTRYPOINT: 'smartbox.portal/box'
BOX_AUTH_LOGIN__REDIRECT: "/admin/portal"
BOX_SMARTBOX_SANDBOX__URL: "http://sandbox"
PGHOST: aidboxdb
PGDATABASE: smartbox
PGPORT: '5432'
AIDBOX_STDOUT_PRETTY: 'true'
AIDBOX_PORT: '8080'
AIDBOX_FHIR_VERSION: 4.0.1
AIDBOX_BASE_URL: 'http://smartbox'
BOX_PROVIDER_DEFAULT_TYPE: mailgun
BOX_BULK__STORAGE_BACKEND: gcp
BOX_BULK__STORAGE_GCP_SERVICE__ACCOUNT: gcp-ac
apiVersion: v1
kind: Secret
metadata:
name: smartbox
namespace: smartbox
type: Opaque
data:
PGUSER: cG9zdGdyZXM= # base64 encoded postgres
PGPASSWORD: cG9zdGdyZXM= # base64 encoded postgres
AIDBOX_ADMIN_ID: YWRtaW4= # base64 encoded admin
AIDBOX_ADMIN_PASSWORD: cGFzc3dvcmQ= # base64 encoded password
AIDBOX_CLIENT_ID: cm9vdA== # base64 encoded root
AIDBOX_CLIENT_SECRET: c2VjcmV0 # base64 encoded secret
BOX_SMARTBOX_SANDBOX__BASIC: cm9vdDpzZWNyZXQ= # base64 encoded root:secret
AIDBOX_LICENSE: # your base64 encoded lincense
# your base64 encoded email provider secrets
BOX_PROVIDER_DEFAULT_URL:
BOX_PROVIDER_DEFAULT_FROM:
BOX_PROVIDER_DEFAULT_USERNAME:
BOX_PROVIDER_DEFAULT_PASSWORD:
# your base64 encoded GCP storage secrets
BOX_BULK__STORAGE_GCP_SERVICE__ACCOUNT__EMAIL:
BOX_BULK__STORAGE_GCP_SERVICE__ACCOUNT__PRIVATE__KEY:
BOX_BULK__STORAGE_GCP_BUCKET:
BOX_SMARTBOX_SANDBOX__BASIC:
Service
kind: Service
apiVersion: v1
metadata:
name: smartbox
namespace: smartbox
spec:
selector:
service: smartbox
ports:
- protocol: TCP
targetPort: 8080
port: 80
Deployment
kind: Deployment
apiVersion: apps/v1
metadata:
name: smartbox
namespace: smartbox
spec:
replicas: 1
selector:
matchLabels:
service: smartbox
template:
metadata:
labels:
service: smartbox
spec:
containers:
- readinessProbe:
httpGet:
scheme: HTTP
path: /health
port: 8080
initialDelaySeconds: 20
timeoutSeconds: 10
periodSeconds: 10
failureThreshold: 6
envFrom:
- configMapRef:
name: smartbox
- secretRef:
name: smartbox
name: main
ports:
- containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
scheme: HTTP
path: /health
port: 8080
initialDelaySeconds: 20
timeoutSeconds: 10
periodSeconds: 10
failureThreshold: 12
imagePullPolicy: Always
image: healthsamurai/smartbox:edge
Prepare a configuration file
To get a k8s configuration file:
Populate the templates above
Combine all the templates to the .yaml
file separating the templates with ---
lines
The beginning of the file should look like.
---
kind: Namespace
apiVersion: v1
metadata:
name: smartbox
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: aidboxdb-data
namespace: smartbox
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
# ... other file content
Deploy Smartbox to your cluster
To deploy Smartbox run the command.
kubectl apply -f smartbox.yaml
The result should look like this.
namespace/smartbox created
persistentvolumeclaim/aidboxdb-data created
configmap/aidboxdb-envs created
secret/aidboxdb-envs created
configmap/aidboxdb-config created
statefulset.apps/aidboxdb created
service/aidboxdb created
configmap/sandbox created
secret/sandbox created
service/sandbox created
deployment.apps/sandbox created
configmap/smartbox created
secret/smartbox created
service/smartbox created
deployment.apps/smartbox created
To check if everything is working fine run the command.
kubectl get pods -n smartbox
There should be 3 running pods.
NAME READY STATUS RESTARTS AGE
aidboxdb-0 1/1 Running 1 (31s ago) 99m
sandbox-759d6b46fc-qwzwd 0/1 Running 1 (31s ago) 9m56s
smartbox-979b6dfbb-2bhkn 0/1 Running 1 (31s ago) 9m56s