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.
- Have a Google Cloud account, which you can have it as free trial.
- Have an account on Docker Hub where you are going to push your image into.
- Have your API ready or just create a simple
index.php
file with aHello World
message,
or use symfony skeleton by runningcomposer create-project symfony/skeleton simple_api
Optional
- Have Docker installed in your machine.
- 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.
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
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.
- Apply the configurations by running
kubectl apply -f .
- You need to wait when the pods are both running, you can check that by running
kubectl get pods
- Expose your external IP address so that it is accessible from everyone.
kubectl expose deployment nginx-deployment --type=LoadBalancer --port=80
- 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.
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.