Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

thusfar's avatar

Laravel on Kubernetes?

Hello,

can someone tell me if there are any good tutorials on how to deploy Laravel application to work with Kubernetes? Perhaps on Digital Ocean?

Best Regards

0 likes
11 replies
ellisio's avatar

We have been working on doing this for the last month with our application. If you want to take a look at our containers to play with you can. Things are rapidly changing, and once this is production ready we will be posting an article on our tech blog.

https://hub.docker.com/u/kicka

We are deploying on Google Container Engine though... We have a few different Deployment objects.

beanstalkd

---
  apiVersion: v1
  kind: Service
  metadata:
    name: beanstalkd
    labels:
      run: beanstalkd
  spec:
    ports:
    - port: 11300
    selector:
      run: beanstalkd
---
  apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: beanstalkd
    labels:
      run: beanstalkd
      version: "1.10"
  spec:
    replicas: 1
    template:
      metadata:
        labels:
          run: beanstalkd
          version: "1.10"
      spec:
        containers:
        - name: beanstalkd
          image: kicka/beanstalkd:1.10
          imagePullPolicy: Always
          ports:
          - containerPort: 11300
          livenessProbe:
            tcpSocket:
              port: 11300
            initialDelaySeconds: 15
            timeoutSeconds: 5
          readinessProbe:
            tcpSocket:
              port: 11300
            initialDelaySeconds: 5
            timeoutSeconds: 1

beanstalkd-console

---
  apiVersion: v1
  kind: Service
  metadata:
    name: beanstalkd-console
    labels:
      run: beanstalkd-console
  spec:
    type: NodePort
    ports:
    - port: 2080
    selector:
      run: beanstalkd-console
---
  apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: beanstalkd-console
    labels:
      run: beanstalkd-console
      version: "1.7.4"
  spec:
    replicas: 1
    template:
      metadata:
        labels:
          run: beanstalkd-console
          version: "1.7.4"
      spec:
        containers:
        - name: beanstalkd-console
          image: kicka/beanstalkd-console:1.7.4
          imagePullPolicy: Always
          ports:
          - containerPort: 2080
          livenessProbe:
            tcpSocket:
              port: 2080
            initialDelaySeconds: 15
            timeoutSeconds: 5
          readinessProbe:
            tcpSocket:
              port: 2080
            initialDelaySeconds: 5
            timeoutSeconds: 1

cache (redis)

---
  apiVersion: v1
  kind: Service
  metadata:
    name: cache
    labels:
      run: redis
  spec:
    ports:
    - port: 6379
    selector:
      run: redis
---
  apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: cache
    labels:
      provider: redis
      version: 3.2.1
  spec:
    replicas: 1
    template:
      metadata:
        labels:
          run: redis
          version: 3.2.1
      spec:
        containers:
        - name: redis
          image: redis:3.2.1-alpine
          imagePullPolicy: Always
          ports:
          - containerPort: 6379
          livenessProbe:
            exec:
              command:
              - redis-cli
              - ping
            initialDelaySeconds: 5
            timeoutSeconds: 5
          readinessProbe:
            exec:
              command:
              - redis-cli
              - ping
            initialDelaySeconds: 5
            timeoutSeconds: 1

php-fpm

---
  apiVersion: v1
  kind: Service
  metadata:
    name: php-fpm
    labels:
      run: php-fpm
  spec:
    ports:
    - port: 9000
    selector:
      run: php-fpm
---
  apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: php-fpm
    labels:
      run: php-fpm
      version: "7.0.8"
  spec:
    replicas: 1
    template:
      metadata:
        labels:
          run: php-fpm
          version: "7.0.8"
      spec:
        containers:
        - name: php-fpm
          image: kicka/php-fpm:7.0.8
          imagePullPolicy: Always
          ports:
          - containerPort: 9000
          livenessProbe:
            tcpSocket:
              port: 9000
            initialDelaySeconds: 5
            timeoutSeconds: 5
          readinessProbe:
            tcpSocket:
              port: 9000
            initialDelaySeconds: 5
            timeoutSeconds: 1

nginx

---
  apiVersion: v1
  kind: Service
  metadata:
    name: nginx
    labels:
      run: nginx
  spec:
    type: NodePort
    ports:
    - port: 80
    selector:
      run: nginx
---
  apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: nginx
    labels:
      run: nginx
      version: "1.11.1"
  spec:
    replicas: 1
    template:
      metadata:
        labels:
          run: nginx
          version: "1.11.1"
      spec:
        containers:
        - name: nginx
          image: kicka/nginx:1.11.1
          imagePullPolicy: Always
          ports:
          - containerPort: 80
          livenessProbe:
            tcpSocket:
              port: 80
            initialDelaySeconds: 5
            timeoutSeconds: 5
          readinessProbe:
            tcpSocket:
              port: 80
            initialDelaySeconds: 5
            timeoutSeconds: 1

ingress (HTTP(s) Load Balancer)

---
  apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    name: ingress
  spec:
    tls:
    - secretName: yourdomain-cert
    backend:
      serviceName: nginx
      servicePort: 80
    rules:
    - host: queue.yourdomain.com
      http:
        paths:
        - backend:
            serviceName: beanstalkd-console
            servicePort: 2080

secrets

---
  apiVersion: v1
  data:
    tls.crt: REDACTED
    tls.key: REDACTED
  kind: Secret
  metadata:
    name: yourdomain-cert
    namespace: default
  type: Opaque

The only problem we have right now is linking the containers. For some reason Nginx can't connect to PHP-FPM when using proxy_pass php-fpm:9000 :/

jwohlfert23's avatar

Did you ever figure this out? ^

We are having the exact same issue.

fideloper's avatar

My understanding is that Kubernetes is a bear to configure yourself.

I'd personally try to use it on GCE, where they setup it up for you!

If you want to use Kubernetes yourself, using DO or similar clouds might lead to headaches - for something where you'll be clustering groups of servers, AWS or similar will serve better for the more complex (and secure) network setups you may require.

That being said, how familiar with Dockar are you? A really firm grasp of it will help a lot.

If you're pretty familiar with Docker, check out Rancher - it's simpler and very popular.

samnajian's avatar

You can use "localhost" in proxy_pass and it should work.

eamonkeane's avatar

I just put a step by step guide together which packages everything into a helm chart. In 10 minutes you can get

Website working with SSL and database backend (mysql) Sticky sessions so that the same backened php pod is maintained for the session Automatic seeding and migrations on application updates

If anyone has any tips to improve it, please let me know. You should just be able to replace your custom php image (and corresponding nginx image) in the values.yaml and it will work.

davi5e's avatar

Has anyone figured out how to handle the queue worker and the scheduler?

As in using the same structure described in the following link, but in a Kubernetes environment?

https://laravel-news.com/laravel-scheduler-queue-docker

For some reason, docker-compose has no problem whatsoever to route PHP requests to the right container (backend), whereas in Kubernetes things go vary wrong whenever Nginx sends a request to the wrong Pod (queue or scheduler)...

Please or to participate in this conversation.