Deploying to Microsoft Azure
PSPDFKit Server has been deprecated and replaced by Document Engine. To start using Document Engine, refer to the migration guide. With Document Engine, you’ll have access to robust new capabilities (read the blog for more information).
This guide will walk you through the steps for deploying PSPDFKit Server to the Microsoft Azure Container Service with Kubernetes.
Setting Up Azure CLI
To be able to deploy PSPDFKit Server to the Microsoft Azure Container Service with Kubernetes, you have to set up the Azure CLI utility to manage your Kubernetes cluster in the command line.
To install Azure CLI, follow the installation instructions from the Azure CLI installation guide.
After you’ve installed Azure CLI, run the following command to log in to Microsoft Azure:
az login
This command will print the URL https://microsoft.com/devicelogin and the code for signing in. Open the URL in your browser and enter the code to sign in to your Microsoft Azure account.
Creating a Resource Group
To create a resource group, run the following:
az group create -l eastus -n pspdfkitresourcegroup
In this example, we created the resource group in the eastus
region with the name pspdfkitresourcegroup
. An overview of available regions can be found on Microsoft’s Azure Regions page.
Creating a Kubernetes Cluster
To be able to manage your Kubernetes cluster from the command line, you have to install kubectl
:
az aks install-cli
To create a Kubernetes cluster with the name pspdfkitAKScluster
, run the following:
az aks create -g pspdfkitresourcegroup --name pspdfkitAKScluster --generate-ssh-keys
To connect kubectl
with your cluster, execute:
az aks get-credentials -g pspdfkitresourcegroup -n pspdfkitAKScluster
Creating a ConfigMap
ConfigMaps allow you to decouple configuration artifacts from image content. To create the pspdfkit-config
ConfigMap, run the following command:
kubectl create configmap pspdfkit-config
After the ConfigMap is created, you can edit it with the following:
kubectl edit configmap pspdfkit-config
This should open the created ConfigMap in your editor. Edit the file to match the following file and replace activation_key
with your activation key:
# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving, # this file will be reopened with the relevant failures. # apiVersion: v1 data: activation_key: YOUR_ACTIVATION_KEY_GOES_HERE api_auth_token: secret dashboard_password: secret dashboard_username: dashboard jwt_algorithm: RS256 jwt_public_key: | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2gzhmJ9TDanEzWdP1WG+ 0Ecwbe7f3bv6e5UUpvcT5q68IQJKP47AQdBAnSlFVi4X9SaurbWoXdS6jpmPpk24 QvitzLNFphHdwjFBelTAOa6taZrSusoFvrtK9x5xsW4zzt/bkpUraNx82Z8MwLwr t6HlY7dgO9+xBAabj4t1d2t+0HS8O/ed3CB6T2lj6S8AbLDSEFc9ScO6Uc1XJlSo rgyJJSPCpNhSq3AubEZ1wMS1iEtgAzTPRDsQv50qWIbn634HLWxTP/UH6YNJBwzt 3O6q29kTtjXlMGXCvin37PyX4Jy1IiPFwJm45aWJGKSfVGMDojTJbuUtM+8P9Rrn AwIDAQAB -----END PUBLIC KEY----- pgdata: /var/lib/postgresql/data/pgdata pgdatabase: pspdfkit pghost: pspdfkitdb pgpassword: examplepassword pgport: "5432" pguser: pspdfkit secret_key_base: secret-key-base kind: ConfigMap
Don’t change anything that comes after the kind: ConfigMap
line, because that part is autogenerated.
Creating an Azure Disk Volume
To create the Azure Disk Volume where the database saves the data, run:
az group list --output table
This will print a list of resource groups. Copy the name of the resource group that starts with MC
— for example, MC_pspdfkitresourcegroup_pspdfkitAKScluster_eastus
— and insert it into the following command after --resource-group
:
az disk create \ --resource-group MC_pspdfkitresourcegroup_pspdfkitAKScluster_eastus \ --name postgres-disk\ --size-gb 50 \ --query id --output tsv
This will print the disk ID of the created disk. For example:
/subscriptions/12345abc-def1-2345-6789-abcdef123456/resourceGroups/MC_pspdfkitresourcegroup_pspdfkitAKScluster_eastus/providers/Microsoft.Compute/disks/postgres-disk
Creating Services and Deployments
Kubernetes Services and Deployments can be configured in a file. To run PSPDFKit Server, you have to define a Service and a Deployment for the database and a Service and a Deployment for PSPDFKit Server. First, create the file that configures the database Service and Deployment. To do this, create the pspdfkitdb.yml
file in the current directory:
apiVersion: v1 kind: Service metadata: name: pspdfkitdb spec: ports: - port: 5432 selector: app: pspdfkitdb --- apiVersion: apps/v1 kind: Deployment metadata: name: pspdfkitdb spec: selector: matchLabels: app: pspdfkitdb template: metadata: labels: app: pspdfkitdb spec: containers: - image: "postgres:15" name: pspdfkitdb env: - name: POSTGRES_USER valueFrom: configMapKeyRef: name: pspdfkit-config key: pguser - name: POSTGRES_PASSWORD valueFrom: configMapKeyRef: name: pspdfkit-config key: pgpassword - name: PGDATA valueFrom: configMapKeyRef: name: pspdfkit-config key: pgdata ports: - containerPort: 5432 name: pspdfkitdb volumeMounts: - name: postgres-storage mountPath: /var/lib/postgresql/data volumes: - name: postgres-storage azureDisk: kind: Managed diskName: postgres-disk diskURI: /subscriptions/12345abc-def1-2345-6789-abcdef123456/resourceGroups/MC_pspdfkitresourcegroup_pspdfkitAKScluster_eastus/providers/Microsoft.Compute/disks/postgres-disk
Make sure to replace diskURI
in the last line with the disk ID you got from the command before.
After you’ve created the configuration file for the database, create the configuration for PSPDFKit Server (pspdfkit.yml
) and ensure that the pspdfkit/pspdfkit
image tag corresponds to the latest PSPDFKit Server version:
apiVersion: v1 kind: Service metadata: name: pspdfkit spec: ports: - protocol: TCP port: 5000 targetPort: 5000 selector: app: pspdfkit type: LoadBalancer --- apiVersion: apps/v1 kind: Deployment metadata: name: pspdfkit spec: selector: matchLabels: app: pspdfkit template: metadata: labels: app: pspdfkit spec: containers: - image: "pspdfkit/pspdfkit:2024.8.1" name: pspdfkit env: - name: PGUSER valueFrom: configMapKeyRef: name: pspdfkit-config key: pguser - name: PGPASSWORD valueFrom: configMapKeyRef: name: pspdfkit-config key: pgpassword - name: PGDATABASE valueFrom: configMapKeyRef: name: pspdfkit-config key: pgdatabase - name: PGHOST valueFrom: configMapKeyRef: name: pspdfkit-config key: pghost - name: PGPORT valueFrom: configMapKeyRef: name: pspdfkit-config key: pgport - name: ACTIVATION_KEY valueFrom: configMapKeyRef: name: pspdfkit-config key: activation_key - name: API_AUTH_TOKEN valueFrom: configMapKeyRef: name: pspdfkit-config key: api_auth_token - name: SECRET_KEY_BASE valueFrom: configMapKeyRef: name: pspdfkit-config key: secret_key_base - name: JWT_ALGORITHM valueFrom: configMapKeyRef: name: pspdfkit-config key: jwt_algorithm - name: JWT_PUBLIC_KEY valueFrom: configMapKeyRef: name: pspdfkit-config key: jwt_public_key - name: DASHBOARD_USERNAME valueFrom: configMapKeyRef: name: pspdfkit-config key: dashboard_username - name: DASHBOARD_PASSWORD valueFrom: configMapKeyRef: name: pspdfkit-config key: dashboard_password ports: - containerPort: 5000 name: pspdfkit
To create all Services and Deployments needed to run PSPDFKit Server, execute:
kubectl create -f ./pspdfkitdb.yml
kubectl create -f ./pspdfkit.yml
Viewing the Dashboard
To be able to access the server, you have to get the external IP address that was assigned to the server. Run the following command to view all the Services in your cluster, along with their assigned external IP addresses:
kubectl get services
This will show something like the following:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.15.240.1 <none> 443/TCP 54m pspdfkit LoadBalancer 10.15.247.197 12.345.678.910 5000:32393/TCP 1m pspdfkitdb ClusterIP 10.15.244.127 <none> 5432/TCP 4m
Copy the EXTERNAL-IP
address from the pspdfkit
column and access the dashboard with the port 5000
and the /dashboard
path in your web browser. In this example, you would access the dashboard with http://12.345.678.910:5000/dashboard
.
Limitations
Be aware that this is just an example setup, and we recommend looking deeper into the Microsoft Azure Container Service for a production-ready setup.