Google Cloud Platform with Kubernetes

This guide article will walk you through the steps for deploying PSPDFKit Server to the Google Cloud Platform with Kubernetes.

Creating a Google Cloud Project

To create a Google Cloud project, please refer to the steps outlined in the Google Cloud Platform Documentation.

Setting Up Google Cloud SDK

To be able to deploy PSPDFKit Server to the Google Cloud Platform with Kubernetes, you have to set up the gcloud utility in order to manage your Kubernetes cluster in the command line.

To install gcloud, follow the installation instructions for your platform:

kubectl is a utility for running commands against Kubernetes clusters. After installing gcloud, add the kubectl components by running the following command:

1
gcloud components install kubectl

Make sure to set the compute zone to the one you want to deploy to. In this example, we are using europe-west2-c, but you can also pick another one if you are not located in Europe. Then insert it into the example below:

1
gcloud config set compute/zone europe-west2-c

Now run gcloud compute zones list to get a list of all available compute zones.

Creating the Kubernetes Cluster

To create a Kubernetes cluster with the name pspdfkit-example-cluster, run the following:

1
gcloud container clusters create pspdfkit-example-cluster

This will create a cluster using the default settings. To get an overview of your clusters, visit the Container Engine Dashboard.

Container Engine Dashboard

Run the following command to make sure kubectl is connected to your cluster:

1
kubectl get pods

This command should print No resources found. When you get an error, try to authenticate to the Google Cloud Platform with gcloud auth application-default login.

Upload the PSPDFKit Image to the Google Container Registry

Before you can upload the PSPDFKit image to the Google Container Registry, you have to download it to your local machine.

First make sure you have Docker installed and running.

To log in to the private PSPDFKit Docker registry and pull the pspdfkit image, run the following:

Copy
1
2
docker login -u YOUR_DOCKER_USERNAME_GOES_HERE -p YOUR_DOCKER_PASSWORD_GOES_HERE docker.pspdfkit.com
docker pull docker.pspdfkit.com/pspdfkit:latest

Now that the image is built, you need to create a separate tag that will represent the destination in the Google Container Registry.

To publish a Docker image to the Google Container Registry, you have to create a tag, which will represent where this image will be saved in the Google Container Registry. The tag consists of the root URL, which is either us.gcr.io, eu.gcr.io, or asia.gcr.io, depending upon your region and the project ID of your Google Cloud project.

You can find out your Google Cloud project ID by running the following:

1
gcloud projects list

Doing that should print something like this:

1
2
PROJECT_ID                   NAME                      PROJECT_NUMBER
pspdfkit-example-project     pspdfkit-example-project  123456789123

In the above example, the project ID is pspdfkit-example-project. To create the tag, run the following command and replace eu.gcr.io with your region and pspdfkit-example with your project ID:

1
docker tag docker.pspdfkit.com/pspdfkit:latest eu.gcr.io/pspdfkit-example-project/pspdfkit:latest

After you tag the image, you can publish it to the Google Container Registry with this:

1
gcloud docker -- push eu.gcr.io/pspdfkit-example-project/pspdfkit:latest

Make sure to also replace the tag with the tag you created in the step above.

Create a Google Cloud SQL PostgreSQL Database Instance

In order to run PSPDFKit Server, you will need to set up a Postgres database for it. To do this, go to the Google Cloud SQL Instances page and click on Create instance.

create instance

Then you will be able to select a database engine for Google Cloud SQL to run on. Here you need to select PostgreSQL.

select database engine

Finally, you have to set an instance ID, the default user password, and the region of the database.

postgres settings

Connecting the Kubernetes Engine to the Cloud SQL Instance

To enable the PSPDFKit Server deployment to connect to the Cloud SQL Instance, we will use the Cloud SQL Proxy Docker image. First you need to enable the Cloud SQL Administration API. Then you have to set up a service account with access privileges for your Cloud SQL instance.

To do this, go to the service accounts page, click on Select, select your Google Cloud project, and then click on Create Service Account. Set a service account name and an ID, and make sure to select Cloud SQL Admin as the Project role and Furnish a new private key with the key type JSON.

Click on Save to save this service account and to download the service account private key file. Be sure to save this file, because you will need it later.

create service account

Run the following command to create a user named proxyuser for the Google Cloud SQL database. This user will be used to access the database from the PSPDFKit Server deployment:

1
gcloud sql users create proxyuser host --instance=[INSTANCE_NAME] --password=[PASSWORD]

Make sure to replace [INSTANCE_NAME] with the name of your Google Cloud SQL instance and [PASSWORD] with a password for the user.

You also need to create two secrets for the Kubernetes Engine application to be able to access the Cloud SQL instance.

To create the secret for the service account, replace [PROXY_KEY_FILE_PATH] in the following command with the path where you saved the service accounts’ private key, and then run it:

1
2
kubectl create secret generic cloudsql-instance-credentials \
    --from-file=credentials.json=[PROXY_KEY_FILE_PATH]

The second secret you need to create provides the proxy user account and its password. Here you need to replace [PASSWORD] with the password you set for the proxy user you just created:

1
2
kubectl create secret generic cloudsql-db-credentials \
    --from-literal=username=proxyuser --from-literal=password=[PASSWORD]

Creating a ConfigMap

ConfigMaps allow you to decouple configuration artifacts from image content. To create the pspdfkit-config ConfigMap, run the following command:

1
kubectl create configmap pspdfkit-config

After the ConfigMap is created, you can edit it with the following:

1
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:

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 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-----
    MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALd41vG5rMzG26hhVxE65kzWC+bYQ94t
    OxsSxIQZMOc1GY8ubuqu2iku5/5isaFfG44e+VAe+YIdVeQY7cUkaaUCAwEAAQ==
    -----END PUBLIC KEY-----
  pgdatabase: 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 the Services and Deployments

For the configuration of the proxy container you will use to connect to the Cloud SQL database, you will need the instance connection name of the instance. To get this, run the following command:

1
gcloud sql instances describe [INSTANCE_NAME]

The output of this command will contain a line like this, where pspdfkit-example-project:europe-west1:pspdfkitexampledb is the name of the instance:

1
connectionName: pspdfkit-example-project:europe-west1:pspdfkitexampledb

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 PSPDFKit Server. To do this, create the pspdfkit.yml file in the current directory, replace the image eu.gcr.io/pspdfkit-example-project/pspdfkit:latest with the PSPDFKit Docker image you uploaded to the Google Container Registry in an earlier step, and replace pspdfkit-example-project:europe-west1:pspdfkitexampledb with the name of the Cloud SQL database instance from the previous command:

Copy
pspdfkit.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
apiVersion: v1
kind: Service
metadata:
  name: pspdfkit
spec:
  ports:
    - protocol: TCP
      port: 5000
      targetPort: 5000
  selector:
    app: pspdfkit
  type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: pspdfkit
spec:
  template:
    metadata:
      labels:
        app: pspdfkit
    spec:
      containers:
        - name: cloudsql-proxy
          image: gcr.io/cloudsql-docker/gce-proxy:1.11
          command: ["/cloud_sql_proxy",
                    "-instances=pspdfkit-example-project:europe-west1:pspdfkitexampledb=tcp:5432",
                    "-credential_file=/secrets/cloudsql/credentials.json"]
          volumeMounts:
            - name: cloudsql-instance-credentials
              mountPath: /secrets/cloudsql
              readOnly: true
        - image: "eu.gcr.io/pspdfkit-example-project/pspdfkit:latest"
          name: pspdfkit
          env:
            - name: PGUSER
              valueFrom:
                secretKeyRef:
                      name: cloudsql-db-credentials
                      key: username
            - name: PGPASSWORD
              valueFrom:
                secretKeyRef:
                      name: cloudsql-db-credentials
                      key: password
            - name: PGDATABASE
              valueFrom:
                configMapKeyRef:
                  name: pspdfkit-config
                  key: pgdatabase
            - name: PGHOST
              value: "127.0.0.1"
            - name: PGPORT
              value: "5432"
            - 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
      volumes:
        - name: cloudsql-instance-credentials
          secret:
            secretName: cloudsql-instance-credentials

To create the services and deployments needed to run PSPDFKit Server, execute the following:

1
kubectl create -f ./pspdfkit.yml

View 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:

1
kubectl get services

This will show something like the following:

Copy
1
2
3
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

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.

Limitation

Be aware that this is just an example setup, and we recommend looking deeper into the Google Cloud Platform for a production-ready setup.