Kubernetes

Every deployment is different. Please be aware as you follow these steps that all documented here might not be 100% compatible with your specific configurations.

Some Form.io users may want to utilize the Kubernetes open-source platform to manage their containers. Below is a guide on how to get Kubernetes up and running within your Local Environment.

Pre-requisites

In order to continue will we need a few libraries installed in our terminal to get started.

  • Installation of kubectl in your terminal application and authenticated against your cluster.

  • Installation of @formio/deploy CLI in your terminal

  • Installation of Helm in your terminal application.

  • After installing Helm you'll want to use it to install the Nginx Ingress Controller onto the cluster. The command displayed in the link should be all you need to achieve this.

  • OPTIONAL: If you'd like to test out the HPA configuration you'll need to install Metrics Server Repository in order for the HPA configuration to be able to monitor the pods CPU and Memory usage.

Installing Form.io Deploy CLI

To begin the setup of Form.io within a Kubernetes cluster in your local environment, you'll first need to install the @formio/deploy CLI tool. This tool is specifically designed to streamline the deployment process of Form.io on Kubernetes. The repository containing the @formio/deploy CLI, along with detailed installation instructions, is hosted on GitHub. You can access it by visiting clicking the link below.

Please ensure you have followed the provided instructions to install the CLI before proceeding with the deployment process detailed in the subsequent sections. Run the command below to install the CLI.

npm install -g @formio/deploy

Create Cluster Ingress Controller

In order to route traffic to our API and PDF server we will want to configure the cluster to include an Ingress Controller. This will vary between Cloud Provider.

The following links are provided to the documentation on creating Ingress Controllers for your varying deploying configurations.

Multi-container Deployment

This deployment assumes you have 1 API server and 1 PDF server associated with your LICENSE_KEY and have a pre-configured Mongo Database Instance and File Storage Provider.

Create Cluster Namespace

Next we will want to create a namespace for our deployment using the kubectl CLI by running the following command.

# Create namespace for Form.io multconatiner installtion
kubectl create namespace formio-prod

Kubernetes namespaces provide a mechanism for isolating groups of resources within a single cluster. A namespace is a virtual cluster within a physical cluster, used to divide cluster resources between multiple users and applications. Think of it as a label that provides a scope for names. This allows you to partition resources to manage access control, limit resource consumption, and organize objects such as Pods, Services, and Deployments into a logically named group.

Create and Unzip Deployment Configuration

# Define some command line environment variables.
PROVIDER=azure # azure | aws
API_NAMESPACE=formio-prod
LICENSE_KEY=your_license_key_here
YOUR_DOMAIN=localdev.me

# Output the Kubernetes Deployment zip to the default ~/deployments directory.
formio-deploy package helm/$PROVIDER/multicontainer.zip \
--license=$LICENSE_KEY \
--version=8.4.1 \
--pdf-version=5.4.2 \
--pdf-server-url="http://pdf-server:4005" \
--admin-email='admin@example.com' \
--admin-pass='CHANGEME' \
--db-secret='CHANGEME' \
--jwt-secret='CHANGEME' \
--base-url="$API_NAMESPACE.$YOUR_DOMAIN"

Now that we've create a deployment zip at our ~/deployments directory we should navigate to this folder, unzip the file and then set some environment variables in the .env of that directory.

# Unzip helm deployment
cd ~/deployments/helm/$PROVIDER
unzip -d . multicontainer.zip && mv helm multicontainer

# Change to directory
cd multicontainer

# View contents of current .env (This should be edited before deployment)
cat .env

Environment Variables

Depending on the cloud service provider your project is utilizing, your .env file—a crucial configuration file that stores environment variables—will need to contain specific variables tailored either for Microsoft Azure or Amazon Web Services (AWS) when it comes to file storage solutions. These variables play a critical role in how your application connects to and interacts with cloud-based file storage services provided by these platforms.

For Form.io API server:

If you followed exactly what was run in previous steps there are really on 5 variables that you need to alter to have the deployment succeed:

  • LICENSE_KEY: This is your Form.io enterprise license key that is utilized to identify your self-hosted deployments.

  • MONGO: The Mongo compatible NoSQL database string that will be utilized by your Form.io deployment. DO NOT forget to include your database name in your string.

See Azure Storage and AWS S3 Storage examples below to see how these variables should be configured.

For Azure Storage:

If your application is leveraging Azure's cloud services, your .env file will need to include the following environment variables to facilitate the connection to Azure File Storage:

  • FORMIO_AZURE_CONNECTION_STRING: This key provides your application with the necessary permissions to access your Azure storage account.

  • FORMIO_AZURE_CONTAINER: The name of the container within your Azure storage account where files will be stored.

An example configuration in your .env file for Azure might look like this:

APP_ENV=production # Not required
API_IMAGE=formio/formio-enterprise:8.4.1
PDF_IMAGE=formio/pdf-server:5.4.2
LICENSE_KEY=your_license_key_here
MONGO=""
PORT=3000
PORTAL_ENABLED=1
ADMIN_EMAIL=admin@example.com
ADMIN_PASS=CHANGEME
DB_SECRET=CHANGEME
JWT_SECRET=CHANGEME
BASE_URL=formio-prod.localdev.me
PDF_SERVER=http://pdf-server:4005

## Azure Blob
FORMIO_AZURE_CONTAINER=
FORMIO_AZURE_CONNECTION_STRING=""

For AWS S3 Storage:

For projects that use AWS for cloud services, the .env file should include details pertinent to accessing AWS S3, a secure, durable, and scalable object storage infrastructure. The required keys include:

  • FORMIO_S3_KEY: This key identifies your AWS account, granting the necessary access permissions.

  • FORMIO_S3_SECRET: This key acts as the password to your AWS account, and it is used in conjunction with the access key id.

  • FORMIO_S3_BUCKET: The name of the S3 bucket where your files will be stored.

  • FORMIO_S3_REGION: The region of where your S3 bucket resides.

A typical AWS S3 configuration in the .env file might resemble the following:

APP_ENV=production # Not required
API_IMAGE=formio/formio-enterprise:8.4.1
PDF_IMAGE=formio/pdf-server:5.4.2
LICENSE_KEY=your_license_key_here
MONGO=""
PORT=3000
PORTAL_ENABLED=1
ADMIN_EMAIL=admin@example.com
ADMIN_PASS=CHANGEME
DB_SECRET=CHANGEME
JWT_SECRET=CHANGEME
BASE_URL=formio-prod.<your-domain>.com
PDF_SERVER=http://pdf-server:4005

## AWS S3 Bucket Settings
FORMIO_S3_KEY=
FORMIO_S3_SECRET=
FORMIO_S3_BUCKET=formio-files
FORMIO_S3_REGION=us-east-1

## Only required if utilizing Textract Field Recognition
# TEXTRACT_OUTPUT_FOLDER=textract
# TEXTRACT_ROLE_ARN=
# TEXTRACT_SNS_TOPIC_ARN=

See AWS Textract Integration for more information on how to configure Textract.

It's vital to ensure that these variables are correctly set and securely stored since they provide direct access to your cloud storage resources. Misconfiguration or exposure of these keys can lead to unauthorized access and potential data breaches. Always follow best practices for security, such as using secrets managers and regularly rotating keys.

Deploy Containers

Note: If you are deploying from Windows would recommend running from Windows Subsystem for Linux (WSL), or run the commands from these scripts individually as these shell scripts are specific to UNIX based operating systems.

Now that you've concluded updating your .env for you configured provider we are ready to deploy our application on to our Kubernetes cluster using Helm. In the scripts folder of the current multicontainer directory we have some pre-made scripts that will assist you with the install, upgrade, and rollback processes.

# The following scripts can be utilized to install and upgrade your deployment:
bash scripts/upgrade.sh --namespace  $API_NAMESPACE --path ./deployment

# This script can be utilized to rollback to a previous deployment revision.
bash scripts/rollback.sh

Remotely Connected Multi-stage API Deployment

This deployment assumes you have 3 API server and 1 PDF server associated with your LICENSE_KEY and have a pre-configured Mongo Database Instance and File Storage Provider.

We will create a single PORTAL_ENABLED API server in our lowest environment then connecting 2 higher level environment API servers to our portal and connecting each of these API servers to a standalone PDF server all running in their own standalone namespaces.

Create Cluster Namespaces

Like we handled in the Multicontainer deployment documentation we want to create namespaces for each of our deployment resources. The difference between this deployment will be that we will create independent namespaces for each of our API server environments as well as our PDF server environment. The intention is to make upgrading & scaling each of these environment isolated and simple to manage.

# Create namespace PDF server
kubectl create namespace formio-pdf

# Create namespace (Portal Enabled) Development API server
kubectl create namespace formio-dev

# Create namespace (Portal Disabled) Staging Remote API server
kubectl create namespace formio-staging

# Create namespace (Portal Disabled) Production Remote API server
kubectl create namespace formio-prod

See Multicontainer deployment documentation for further explanation on Kubernetes namespaces.

Create, Unzip, and Deploy

Each of these commands by default will output a zip file to ~/deployments on your local system. We will be navigating to each of the directory to unzip each of the required resources and this deploying them individually to their respective namespaces.

Note: Would recommend going in the following deployment order as follows:

  1. Deploy PDF server: This will be connected to from EACH of the API server environments. Starting here will limit issues during the deployment process.

# Define CLI Variables for @formio/deploy
PROVIDER=azure # azure | aws
PDF_NAMESPACE=formio-pdf
LICENSE_KEY=your_license_key_here

# Create helm deployment zip
formio-deploy package helm/$PROVIDER/pdf-server.zip \
--license=$LICENSE_KEY \
--pdf-version=5.4.2

# Unzip helm deployment
cd ~/deployments/helm/$PROVIDER
unzip -d . pdf-server.zip && mv helm pdf-server

# Change to directory
cd pdf-server

# View current .env (This should be edited before continuing)
cat .env

# Deploy
bash scripts/upgrade.sh --namespace $PDF_NAMESPACE --path ./deployment
  1. Deploy Development API Server (Portal Enabled): This will connect to the PDF server running in its own namespace and also allow you to create the stages that will house the remotely connected servers. Before moving on would validate that PDF server functionality is working correctly.

# Define CLI Variables for @formio/deploy
PROVIDER=azure # azure | aws
API_NAMESPACE=formio-dev
PDF_NAMESPACE=formio-pdf
LICENSE_KEY=your_license_key_here
YOUR_DOMAIN=localdev.me

# Create helm deployment zip
formio-deploy package helm/$PROVIDER/api-server.zip \
--license=$LICENSE_KEY \
--version=8.4.1 \
--admin-email='admin@example.com' \
--admin-pass='CHANGEME' \
--db-secret='CHANGEME' \
--jwt-secret='CHANGEME' \
--pdf-server-url="http://pdf-server.$PDF_NAMESPACE.svc.cluster.local:4005" \
--base-url="$API_NAMESPACE.$YOUR_DOMAIN"

# Unzip helm deployment
cd ./deployments/helm/$PROVIDER
unzip -d . api-server.zip && mv helm api-server

# Change to directory
cd api-server

# View current .env (This should be edited before continuing)
cat .env

# Deploy
bash scripts/upgrade.sh --namespace $API_NAMESPACE --path ./deployment
  1. Deploy Staging API Server (Portal Disabled): Will connect to the PDF server configured through environment variable settings. Then connect to portal using PORTAL_SECRET to its correspond stage as a remotely connected API server. Validate PDF functionality works correctly from portal on this stage.

# Define CLI Variables for @formio/deploy
PROVIDER=azure # azure | aws
API_NAMESPACE=formio-staging
PDF_NAMESPACE=formio-pdf
LICENSE_KEY=your_license_key_here
YOUR_DOMAIN=localdev.me

# Create helm deployment zip
formio-deploy package helm/$PROVIDER/remote-server.zip \
--no-portal \
--license=$LICENSE_KEY \
--version=8.4.1 \
--admin-email='admin@example.com' \
--admin-pass='CHANGEME' \
--db-secret='CHANGEME' \
--jwt-secret='CHANGEME' \
--portal-secret='CHANGEME' \
--pdf-server-url="http://pdf-server.$PDF_NAMESPACE.svc.cluster.local:4005" \
--base-url="$API_NAMESPACE.$YOUR_DOMAIN"

# Unzip helm deployment
cd ~/deployments/helm/$PROVIDER
unzip -d . remote-server.zip && mv helm remote-server

# Change to directory
cd remote-server

# View current .env (This should be edited before continuing)
cat .env

# Deploy
bash scripts/upgrade.sh --namespace $API_NAMESPACE --path ./deployment
  1. Deploy Production API Server (Portal Disabled): Repeat the same steps perform for the Staging API server (Step 3). Make sure you used the formio-prod namespace as this will define the different BASE_URL for this environment.

# Define CLI Variables for @formio/deploy
PROVIDER=azure # azure | aws
API_NAMESPACE=formio-prod
PDF_NAMESPACE=formio-pdf
LICENSE_KEY=your_license_key_here
YOUR_DOMAIN=localdev.me

# Create helm deployment zip
formio-deploy package helm/$PROVIDER/remote-server.zip \
--no-portal \
--license=$LICENSE_KEY \
--version=8.4.1 \
--admin-email='admin@example.com' \
--admin-pass='CHANGEME' \
--db-secret='CHANGEME' \
--jwt-secret='CHANGEME' \
--portal-secret='CHANGEME' \
--pdf-server-url="http://pdf-server.$PDF_NAMESPACE.svc.cluster.local:4005" \
--base-url="$API_NAMESPACE.$YOUR_DOMAIN"

# Unzip helm deployment
cd ~/deployments/helm/$PROVIDER
unzip -d . remote-server.zip && mv helm remote-server

# Change to directory
cd remote-server

# View current .env (This should be edited before continuing)
cat .env

# Deploy
bash scripts/upgrade.sh --namespace $API_NAMESPACE --path ./deployment

Last updated