Step-by-step Guide to Deploy Your PHP API on Google Cloud using Kubernetes and Docker

google-cloudkubernetesapiphpsymfonydocker

Introduction

In this article, you will learn how to deploy a PHP API on Google Cloud using Kubernetes and Docker. You will learn how to:

  • Containerize your application in a Docker image
  • Create a basic Kubernetes configuration for your API
  • Deploy your Kubernetes configuration to Google Cloud
  • Expose your API to the internet

Before we start you need to have some things ready if you are planning to deploy your own API into Google Cloud.

  1. Have a Google Cloud account, which you can have it as free trial.
  2. Have an account on Docker Hub where you are going to push your image into.
  3. Have your API ready or just create a simple index.php file with a Hello World message,
    or use symfony skeleton by running composer create-project symfony/skeleton simple_api

Optional

  1. Have Docker installed in your machine.
  2. Have kubernetes cli installed in your machine, this is only if you want to try your configuration locally.

Step 1: Containerize your application

In this step we will prepare a docker image with our code, which we will later use to deploy our API.

Create a Dockerfile in the root of your project, and add the following content.

FROM composer:latest as composer

WORKDIR /app
COPY . /app

RUN composer install

FROM php:8.2-fpm-alpine

WORKDIR /var/www/html
COPY --from=composer /app /var/www/html

Amazing! Let's build our docker file.

docker build -t username/simple-api:1.0.0 .

Next, we login into docker by running

docker login

We push our built image into docker hub by running

docker push username/simple-api:1.0.0

Step 2: Create a Kubernetes configuration

The next image is trying to give you an overview of how kubernetes will communicate with different components.
Kubernetes cluster

The current project structure that I am using looks like the following, its a simple symfony API project.

├── composer.json
├── config
├── public
│   └── index.php
├── src
│   ├── Controller
│   └── Kernel.php

And for kubernetes I have the following files, which are the ones that I will explain in the next section.

├── nginx_configMap.yaml
├── nginx_deployment.yaml
├── php_deployment.yaml
├── php_service.yaml
└── projectStorage.yaml

Kubernetes_components

This is the link to the github repo containing the files, this is a basic configuration of a kubernetes cluster with a php and nginx deployment.

ConfigMap

ConfigMap is a kubernetes object that allows you to store non-confidential data in key-value pairs, and in my case it will be used to store the nginx configuration file.
You need to keep in mind that names and labels are important in kubernetes, you always refer to them in other files. See file

Deployment

Deployment is a kubernetes object that allows you to deploy your application, in my case I have two deployments, one for nginx and one for php. They will be deployed in different pods, and they will be able to communicate with each other.
See PHP Deployment file and See Nginx Deployment file.

Here is a part of php_deployment file, where I am using an initContainer to copy my code into a volume, and then I am mounting that volume into my php container.

# ...
spec:
  replicas: 1
  selector:
    matchLabels:
      tier: backend
  template:
    metadata:
      labels:
        app: php
        tier: backend
    spec:
      initContainers:
        - name: copy-project-files
          image: diarselimi/php-sample-api:1.0.6
          command: ["/bin/sh", "-c"]
          args:
            - cp -R /var/www/html /mnt
          volumeMounts:
            - name: tvc
              mountPath: /mnt
      containers:
        - name: php
          image: diarselimi/php-sample-api:1.0.6
          command: ["/bin/sh", "-c"]
          args:
            - chmod -R 777 /var/www/html/var
          ports:
            - containerPort: 9000
          volumeMounts:
            - name: tvc
              mountPath: /var/www
      volumes:
        - name: tvc
          persistentVolumeClaim:
            claimName: project-storage

Service

Service is a kubernetes object that allows you to expose your application to the internet, in my case I have one service for PHP and for exposing it to the internet I am using the command that you will see at the end of this article.
See PHP Service file.

Volume

Volume is a kubernetes object that allows you to store data in a persistent way, in my case I have one volume for PHP and inside of PHP deployment I am mounting it to the /var/www/html directory.
See Volume file.

Last step is to add the new image to our php_deployment.yaml file, by changing the line

- image: <your-docker-hub-username>/<your-image-name>:<tag>
+ image: username/simple-api:1.0.0

This line is the one containing our codebase, so we need to add this to our kubernetes.

Step 3: Deploy your Kubernetes configuration to Google Cloud

In this step we will setup our Google Cloud account, we will create a cluster and upload our kubernetes files in the cluster.
Here is a short video for on google cloud platform.

After uploading my kubernetes configurations into google cloud platform, you will be able to run the following commands.

  1. Apply the configurations by running
kubectl apply -f .
  1. You need to wait when the pods are both running, you can check that by running
kubectl get pods
  1. Expose your external IP address so that it is accessible from everyone.
kubectl expose deployment nginx-deployment --type=LoadBalancer --port=80
  1. You can get your external IP address by running
kubectl get svc
NAME          TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
kubernetes    ClusterIP      10.51.128.1     <none>         443/TCP        3d19h
nginx         LoadBalancer   10.51.130.146   34.75.23.208   80:31852/TCP   27h
php-service   ClusterIP      10.51.131.237   <none>         9000/TCP       29h

Cleaning up

If you want to stop and clean up your cluster so that it doesn't spend your credits, first you need to delete your uploaded config files.

rm nginx_configMap.yaml nginx_deployment.yaml php_deployment.yaml php_services.yaml sample-volume.yaml

then you need to run the following command to stop everything

kubectl delete pvc,pv,deployment,pods,configmap --all 

You can also delete the cluster and that way everything is deleted. Delete cluster in google cloud

Conclusion

In this article, you learned how to deploy a PHP API microservice on Google Cloud using Kubernetes and Docker.
You can use these steps to deploy any type of application on Google Cloud.


If you enjoyed this, please give a clap or share with your network!

Suggested Posts

Step-by-step Guide to Deploy Your PHP API on Google Cloud using Kubernetes and Docker

Read more →

Loading environment values into go Structs

Read more →

Using Mutex in GO on a real world project.

Read more →