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
Dockerfilein the root of your Laravel project to build your Docker image. -
A simple
Makefilecan 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
k8sdirectory 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_usernamewith your actual Docker Hub username in theimagefield.
-
-
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_usernamehere 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_usernameandyour_pat_token_herewith 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
hostsfile. -
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=3to 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
regcredsecret, Docker credentials, and the image name in yourdeployment.yaml. - Pods in
PendingState: This might indicate insufficient resources in your Minikube cluster or issues with node readiness. Checkkubectl describe podfor more details. - Application Not Accessible:
- Ensure your
minikube tunnelis running if you're using a LoadBalancer service. - Verify that your
hostsfile 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-serviceto see if your service is correctly pointing to your pods. - Try accessing the service directly using
minikube service --url my-laravel-app-serviceto 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