This guide outlines the steps to deploy a Laravel application on a Kubernetes cluster, pulling the Docker image from a private Docker registry.
- Docker Desktop: Ensure Docker Desktop is installed and running on your macOS.
- Minikube: Install Minikube, a tool for running a single-node Kubernetes cluster locally.
- kubectl: Install the Kubernetes command-line tool, kubectl, to interact with your Minikube cluster.
- Docker Account with Private Registry: You need a Docker Hub account (or another private Docker registry) and a private repository containing your Laravel application's Docker image.
- Docker Personal Access Token (PAT): Generate a Personal Access Token from your Docker Hub account settings (or your registry's equivalent) with read permissions for your private repository.
-
Create Dockerfile and Makefile:
-
Ensure you have a
Dockerfile
in the root of your Laravel project to build your Docker image. -
A simple
Makefile
can help with building the image:DOCKER_IMAGE_NAME := "my-laravel-app" build: docker build -t $(DOCKER_IMAGE_NAME) .
-
-
Create Kubernetes Deployment Manifest (
k8s/deployment.yaml
):-
Create a
k8s
directory in your project root and save the following content asdeployment.yaml
:kind: Deployment apiVersion: apps/v1 metadata: name: my-laravel-app spec: selector: matchLabels: app: my-laravel-app-web template: metadata: labels: app: my-laravel-app-web spec: imagePullSecrets: - name: regcred containers: - name: web image: your_dockerhub_username/my-laravel-app # Replace with your Docker Hub username imagePullPolicy: IfNotPresent ports: - containerPort: 8000 --- apiVersion: v1 kind: Service metadata: name: my-laravel-app-service labels: app: my-laravel-app-web spec: type: LoadBalancer selector: app: my-laravel-app-web ports: - port: 80 targetPort: 8000 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-laravel-app-ingress spec: rules: - host: my-laravel-app.local http: paths: - backend: service: name: my-laravel-app-service port: number: 80 pathType: Prefix path: /
Remember to replace
your_dockerhub_username
with your actual Docker Hub username in theimage
field.
-
-
Build and Push Docker Image:
- Log in to Docker:
docker login
- Build your Laravel application's Docker image:
make build
- Tag the image with your Docker Hub username and repository name:
Replace
docker tag my-laravel-app your_dockerhub_username/my-laravel-app
your_dockerhub_username
here as well. - Push the image to your private Docker Hub repository:
Again, replace
docker push your_dockerhub_username/my-laravel-app
your_dockerhub_username
.
- Log in to Docker:
-
Start Minikube:
minikube start
-
Create Kubernetes Secret for Docker Registry Authentication:
- Use your Docker Personal Access Token (PAT) to create a Kubernetes secret:
Replace
kubectl create secret docker-registry regcred \ --docker-server=docker.io \ --docker-username=your_dockerhub_username \ --docker-password=your_pat_token_here \ --namespace=default
your_dockerhub_username
andyour_pat_token_here
with your actual Docker Hub credentials.
- Use your Docker Personal Access Token (PAT) to create a Kubernetes secret:
-
Apply Kubernetes Deployment:
kubectl apply -f k8s/deployment.yaml
-
Enable Ingress Addon in Minikube:
minikube addons enable ingress
-
Access Laravel App via
http://my-laravel-app.local/
:-
To access the application using the hostname, you need to add an entry to your local machine's
hosts
file. -
Open
/etc/hosts
(macOS/Linux) orC:\Windows\System32\drivers\etc\hosts
(Windows) with administrator privileges. -
Add the following line, replacing
<minikube-ip>
with the output ofminikube ip
:<minikube-ip> my-laravel-app.local
-
To make the LoadBalancer service accessible, you might need to run:
minikube tunnel
Keep this running in a separate terminal.
-
Once the tunnel is active, you should be able to access your Laravel application in your browser at
http://my-laravel-app.local/
. -
kubectl scale deployment my-laravel-app --replicas=3
to scale up the pods
-
- Check Deployment Status:
kubectl get deployments
- Check Pod Status:
kubectl get pods
- Scale Deployment:
kubectl scale deployment my-laravel-app --replicas=<desired_number>
- Get Service Information:
kubectl get service my-laravel-app-service
- Get Ingress Information:
kubectl get ingress my-laravel-app-ingress
- View Pod Logs:
kubectl logs $(kubectl get pods -l app=my-laravel-app-web -o jsonpath='{.items[0].metadata.name}') -c web --follow
- Describe a Resource for Detailed Information:
(e.g.,
kubectl describe <resource_type> <resource_name>
kubectl describe pod my-laravel-app-xxxx
,kubectl describe service my-laravel-app-service
,kubectl describe ingress my-laravel-app-ingress
) - Delete Deployment:
kubectl delete deployment my-laravel-app
- Delete Service:
kubectl delete service my-laravel-app-service
- Delete Ingress:
kubectl delete ingress my-laravel-app-ingress
- Delete Secret:
kubectl delete secret regcred -n default
- Restart a Deployment (for code changes):
kubectl rollout restart deployment my-laravel-app
- Get Minikube IP:
minikube ip
- Get Service URL (Minikube):
minikube service my-laravel-app-service --url
- Access Ingress via Minikube URL (if LoadBalancer doesn't get IP):
minikube service my-laravel-app-ingress --url
- ImagePullBackOff: This usually indicates an issue pulling the image from your private registry. Double-check your
regcred
secret, Docker credentials, and the image name in yourdeployment.yaml
. - Pods in
Pending
State: This might indicate insufficient resources in your Minikube cluster or issues with node readiness. Checkkubectl describe pod
for more details. - Application Not Accessible:
- Ensure your
minikube tunnel
is running if you're using a LoadBalancer service. - Verify that your
hosts
file is correctly configured. - Check the logs of your Ingress controller (
kubectl logs -n ingress-nginx <ingress-controller-pod-name>
) for any routing errors. - Use
kubectl get endpoints my-laravel-app-service
to see if your service is correctly pointing to your pods. - Try accessing the service directly using
minikube service --url my-laravel-app-service
to bypass Ingress and see if the application is reachable at the service level. - If you are facing any minikube issues then
minikube stop minikube delete minikube start kubectl apply -f k8s/deployment.yaml minikube addons enable ingress kubectl get pods kubectl get service
- Ensure your