---
title: 'Infinite Scale: Deploying and Scaling Laravel on Kubernetes by Leo Sjoberg'
source: 'https://youtube.com/watch?v=UTXuslWrH1Q'
video_id: 'UTXuslWrH1Q'
date: 2026-06-14
duration_sec: 1551
---

# Infinite Scale: Deploying and Scaling Laravel on Kubernetes by Leo Sjoberg

> Source: [Infinite Scale: Deploying and Scaling Laravel on Kubernetes by Leo Sjoberg](https://youtube.com/watch?v=UTXuslWrH1Q)

## Summary

Leo Sjoberg shares a story of a disastrous production deployment that took 11 hours, contrasting it with the ease of using Kubernetes. He demonstrates how to deploy and auto-scale a Laravel application on Kubernetes without changing any code, showing a live demo where a slow site recovers from 15-second load times to 0.1 seconds after auto-scaling kicks in.

### Key Points

- **The 11-hour deployment disaster** [00:05] — A routine 30-minute deployment turned into an 11-hour ordeal, motivating the speaker to adopt Kubernetes.
- **Kubernetes as a 24/7 ops team** [01:01] — Kubernetes ensures applications run smoothly and handles failures gracefully, allowing developers to deal with issues on their own time.
- **Auto-scaling example** [01:38] — A service with 5 customers on a $20 VPS gets tweeted by Taylor, causing 4,000 concurrent users. Without auto-scaling, the site slows to a halt; with it, it handles the load seamlessly.
- **Live demo: scaling from 15s to 0.1s** [03:07] — Siege with 25 concurrent requests shows 15-second response times. After applying the Horizontal Pod Autoscaler, a second instance spins up and load time drops to ~0.1 seconds.
- **No code changes required** [05:09] — Kubernetes auto-scaling works with existing code; no need to rewrite tests or add special cases.
- **Deployment resource** [06:09] — A Deployment tracks replicas and specifies Docker containers (FPM + Nginx). Auto-scaling adjusts the replica count dynamically.
- **ConfigMap for Nginx config** [07:52] — ConfigMap stores the Nginx configuration file as a key-value pair, mounted into the Nginx container. The config is identical to a VPS setup.
- **Secrets for environment variables** [09:37] — Secrets are base64-encoded key-value stores for sensitive data like DB passwords. They are automatically decoded when injected as environment variables.
- **Need for Service and Ingress** [11:37] — A Pod has an IP, but for multiple replicas or services, a reverse proxy (Ingress) and load balancer (Service) are required.
- **Service and Ingress YAML** [14:01] — Service forwards port 80 to target port 80 on pods. Ingress routes requests to the service by name.
- **Horizontal Pod Autoscaler (HPA)** [15:54] — HPA scales the number of pod replicas based on metrics like CPU, memory, latency, or custom metrics.
- **HPA YAML breakdown** [17:03] — HPA specifies target reference (deployment), min/max replicas, and metrics. Example: scale when average request time exceeds 1000ms.
- **Setting realistic constraints** [18:41] — If the app cannot load faster than 400ms, setting a target of 300ms will cause infinite scaling and high costs.
- **Full deployment in 3 minutes** [19:52] — Applying Deployment, ConfigMap, Secret, Service, Ingress, and HPA takes about 3 minutes. Live demo shows the process.
- **Not production-ready** [24:11] — The demo is simplified; production deployment requires more research due to Kubernetes' steep learning curve.

### Conclusion

Deploying and auto-scaling Laravel on Kubernetes is achievable with minimal YAML files and no code changes. While the demo is simplified, it demonstrates the core concepts that make Kubernetes powerful for handling traffic spikes.

## Transcript

[Music]
all right so about four months ago it
was a Thursday at 4 p.m. we were doing a
routine production deployment right we
do them every week they take maybe 30
minutes very easy
11 hours later I left the office now
this means one of two things can have
happened either our production deploy
went really well and I was celebrating
until 3:00 in the morning alternatively
everything that could have gone wrong
went wrong with that deployment now you
can probably guess which one it was now
I'm telling you this story because that
wouldn't have been a problem if we'd
been using kubernetes kubernetes is like
having your own dedicated 24/7 ops team
that makes sure your application runs
smoothly and when things do go wrong it
makes sure that that is also handled
smoothly so that you can deal with
problems in your own time and that's the
reason I submitted a talk for being here
today and which is why for the next 27
minutes we're gonna go over how to
deploy and scale laravel and kubernetes
now you can't really talk about
kubernetes without mentioning auto
scaling auto scaling is this fabled
thing that everyone wants right you want
it to scale instantly and automatically
and infinitely and it's really quite
simple
and it's fast so let's take an example
let's say you just deployed a new
service a month ago right you've got it
on like a twenty dollar digitalocean VPS
you've got maybe five customers then
this happens Tayler tweets out that you
just used your service it's awesome
you've got four thousand people there
suddenly hitting your service now that
can go one of two ways either it goes
really well because you have auto
scaling setup and so you can handle
4,000 people and you just got four
thousand new customers it's pretty
awesome alternatively of course you
don't have any order scaling your site
just slowed to a halt and all the
requests are taking 30 seconds no one
can sign up your customers can't even
use it you're getting angry tweets from
people that think everything is terrible
in life so let's look at how this works
now if we just check out our super
awesome service here which I should say
it is the base installation of laravel
which is a great service which I'm
offering entirely free to everyone here
by the way then we're also going to
check we're running one instance there
and then Taylor's tweet comes so we're
gonna run siege for running 25
concurrent requests and I'm not sure if
you can see it you probably can't see it
that well they're actually I can barely
see it but it's about 10 15 second
requests here and in fact if we open up
a new tab you will quickly see or rather
not so quickly that it's loading
incredibly slowly right it's gonna take
about 15 seconds so what if we just
deploy auto scaling just gonna do run
one command here and we're gonna get the
auto scaling running you can see it's
still loading
that request raised getting up to 15
seconds now it's finally loaded and now
the horizontal called autoscaler which
I'm gonna get to far later it's gonna
kick in you can see there in the top
right right we just got a second
instance and in fact if you now go and
refresh that page or in this case open
up a new tab to load it you'll find that
we have orders killing and you might be
thinking oh it's gonna go from like 15
seconds to 3 seconds no that's gonna go
from 15 seconds to about 0.1 seconds so
that's sort of scaling now I know you
all want this right everyone's like I
want that right I don't want my site
just slowed completely that looks
awesome
how do I get it and then there are some
of you will be thinking I don't want to
change my code again I just rewrote all
my tests to run and Travis CI like a
month ago and now you're telling me I
need to do something else no you don't
need to change your code and this is a
really appealing thing nothing needs to
change you set it up once and then you
just run it you code your app just the
way you used to you don't have to think
about special cases and it all just
works so without further ado we're just
gonna jump into deploying laravel on
kubernetes now I do apologize in advance
because there's gonna be a lot of llamo
and I know that llamo is probably most
people's least favorite markup language
here don't worry I hate it too so I feel
you on that ink you burn eddie's we have
something called a deployment deployment
looks pretty scary and don't worry
you're not meant to be able to read this
but it really just does two things right
the first thing
is they tracked how many copies of our
application is running which you can see
by the number of replicas right and this
is the only thing that we care about
when we're auto-scaling when we're
auto-scaling we're just adjusting this
number dynamically right so it's being
changed on the fly the second thing it
does of course is it specifies what code
we're running specifies the docker
containers so there's a section in there
called spec and I'm gonna go through
this reasonably quickly to not bore you
with llamó so you had your containers
you start off with an application
container now i've already published a
container on docker hub which contains
FP m and the base level installation
that's all that's in there secondly you
had nginx right this is just as if
you're deploying on a regular VPS you're
adding FP m with your application code
guarding nginx and of course we need to
expose the container port as well right
we're running on port 80
this week's post port 80 but there's
another thing you need when you're
deploying on a regular VPS as well right
you don't just need FP m and nginx
installed but you need an internet
connection at ease there's something
called a config map config map is really
straightforward it is a key value store
you literally just insert keys and
values when you store files you will
usually use the file name as the key and
then the content as the value now I have
no reason at all to even show you the
contents of this because this is the
exact same nginx config file that you
would use when you're deploying on a
regular VPS that's what I'm saying right
there's no changes that you need to make
you deploy the same code
so let's jump back to the deployment and
we don't get this config map right our
nginx configuration we need to get that
into the nginx container somehow so in
queue Bernays you just declare a volume
at the top here of the spec and then you
give it a name you're saying I want to
load a volume from this config map that
we just created and you had a mount I
know this can be a bit confusing but
it's quite straightforward right you're
mounting this nginx configuration and
you're mounting it into the path et Cie
nginx and your next or conf now we have
fpm and our code bundled in that we have
nginx and the nginx config but if you
were deploying on a regular server
there's still one more thing you need
but you need your environment variables
in there you need your app peer database
password and all of that and of course
kubernetes has a way to do with this
it's called a secret despite the name a
secret isn't as secret as it sounds a
secret is effectively a config map
that's just basic ste 4 encoded so as
you can see all the values here are just
basic ste 4 encoded values right and so
Kuban edits will automatically decode
that when it puts it into your
environment variables but this means
don't commit secrets now what I mean by
this is you can still totally commit the
turbinates resource called a secret but
don't commit your secret values don't
commit your API keys don't commit your
passwords don't commit any credentials
or an T from the talk yesterday is gonna
come shouting at you for security flaws
but you can still commit the secret
resourcing kubernetes right you can use
environment substitution or something
similar so if we were deploying on a
regular VPS now we'd be ready right so
if we just deploy it or work naturally
so to deploy in cuber Nettie's you use
the cube CTL command which is the
command-line interface for interacting
with kubernetes and you call apply and
then you use the dash F argument which
passes a file or you can pass a
directory of files and so in this
cubanelles directory I just have the
config map
I have the secretly created and the
deployment next we can just open up our
website right and it's gonna be there
and everything can be awesome nope
unfortunately it's not quite that simple
if you made a request with our current
set up what happens is basically this
right we get what's called a pod which
contains fpm and nginx that's what we
specified kubernetes assigns an IP
address to it and so your natural
instinct will be let's just point the
internet at it right how you would
normally do it just put DNS there but
what happens if you deploy a second
service right what if you want to split
your app into an off service and your
primary service well you can't point it
at both at once
and so we basically need a reverse proxy
right and so kubernetes has that built
in which is really awesome and it's
called the ingress controller the
ingress controller for all intents and
purposes right now anyway it's just a
reverse proxy and so you can just create
an ingress resource and you tell it to
write to where you want it to go
and that's all good and well so if we do
that now we should have a production
environment right but there's still one
thing missing the problem is what if we
start auto scaling it
now we've got three IP addresses for one
service and we got two for the other we
need some form of load balancing here
and our reverse proxy the ingress
control that can't handle load balancing
so we need some way of handling load
balancing as you use a service for that
now this is all a big massive theory
lesson about kubernetes networking which
can't get a bit involved so let's jump
back to where we're at now this is what
we have we've a single port with an IP
address and we have an ingress
controller now of course the ingress
controller is a reverse proxy and if you
don't tell you where to go what service
to hit you get it 404 so unfortunately
we're gonna have to dig in and create
the service and the ingress the service
is fairly straightforward you only
specify really one thing you're saying
if a request comes in to port 80
that's the port then forward it to the
target port 80 in the port that is being
targeted right which is the level
application that we just deployed lark
on 2019
[Music]
next you give it a name so that the
ingress controller can then find the
service right next more gamal I
apologize we go through the ingress
again this is might be a bit confusing
because it is very indented but there's
actually only two things that you need
right you need to have the path and you
need to have a service name which we
just created with the service
so now we've created all this service
and ingress stuff you've probably grown
really tired of llamó by now and you
know when you go back to try this on
your own you'll be spending you know 20
hours writing llamó files and being
frustrated fortunately that's all there
is we've deployed laravel we've deployed
level and kubernetes and it all works
so we're basically done right we're
still missing the the order scaling so
with all this done right our application
is deployed we just have auto scaling
left let's dig into that in kubernetes
you have what's called horizontal pod
order scalar which is a really long name
and a really convoluted way of saying
this thing just keeps track of how many
copies of your application are running
all it does is it scales this pod right
with fpm and nginx scale start up and
down based on whatever metrics you
choose in fact you can scale it based on
any metrics you can scale it based on
latency or you could scale it on CPU or
memory or you could scale it based on
how many people are in your office right
now if you set up a custom metric to
track that now we don't want our site to
be slow that's why we added order
scaling in the first place that's why we
want it and so a natural thing to do is
of course you scale on latency right you
want to make sure that your site loads
quickly so you can scale on a request
time this is what a horizontal pod
autoscaler looks like I know it's a lot
of llamó unfortunately this is also the
most important llamó file of in
tired talk which means we're gonna have
to go through it so I'm gonna try to
simplify this and only highlight the
important parts here so you start with a
target reference and even though it's
like four attributes and nested three
levels deep it does one thing it tells
you what it is you want to scale so we
deployed a deployment that's what we
created that contains our containers
that's really awkward to say and we just
say we're targeting the deployment
let's named Larkin 2019 after that
you've got the rest of it right so you
specify the minimum and maximum number
of copies would you want to run that's
the minimum replicas and the maximum and
then last but not least the most
important part you specify what you're
scaling on you specify the metrics that
you want to scale based on now in this
case I have a metric that's called
average request time in milliseconds but
you could use any metrics now you'll
notice here I've set a constraint of a
thousand milliseconds so what I'm saying
is I don't want my site to load slower
than one second but what if you reduce
that to 500 right we don't want our
sites to load and a second really we
want it to load in 0.1 second so you
need to know your constraints because if
you know that your allowable application
no matter how much power you give it
will never load faster than 400
milliseconds if you set your target to
be 300 milliseconds the order scalar is
going to see but we're not at 300
milliseconds yet I'm gonna scale up and
then it's gonna scale up and as you can
see what's it's still 400 milliseconds
so it's gonna keep scaling up
and then you'll end up at your maximum
number of replicas and you're probably
gonna end up using effectively all the
resources you have and you'll end up
with a massive massive bill so make sure
you don't set your constraints too tight
now then let's go through what this all
looks like the whole thing start to
finish in three minutes
now that sounds fast but it doesn't take
more than three minutes to deploy to
kubernetes and have order scaling
running so first of all is just double
check of course that we don't have
anything deployed yet and so we're
getting at 4:04 justice were supposed to
and so we can also just start watching
these pods right so we're gonna check if
we have any pods at all and as you'll
see we don't have any pods running right
because we haven't deployed anything yet
so we've got nothing there so then we
can jump in and we can just deploy the
deployment first right we run cube CTL
apply onto the deployment and in the top
right you can see it's starting to
create that container next we're just
creating the nginx configuration and
follow that up by of course creating the
secret with our environment variables
now with all that applied we're
basically at the first step right we
have the setup that you need for
deploying on a VPS and as we went
through before you're gonna get it for
four on this see if you're refresh it
you're still getting it for four but we
already know how to fix this right you
just add the service you have the
ingress and it should work so let's pray
and also if there I can type correctly
so if we apply the service
it should still 404 because we don't
have an ingress yet but then as soon as
we do add our ingress so again right now
still 404
though you add the ingress you go back
and reload the page and behold you've
got the most awesome service which
Taylor tweeted about now of course we
still have one thing left we have the
auto scaling so we're gonna do what we
did before we're gonna simulate this
Taylor tweet we're doing 25 concurrent
requests and just double check that
everything is running incredibly slowly
as you can see it's gonna keep loading
that for a good good 15 seconds maybe up
to 20 and then of course we apply the
autoscaler now as you apply the
autoscaler it's gonna start taking in
those metrics and then after a few
seconds it's gonna decide whether or not
it should scale up and so in this case
because it can detect that it's running
so slowly right it's not responding
faster than a second you'll see that
it's gonna scale up in just a moment
there we go
so now if we go and reload the page
again or rather open it up in a new tab
just so he can see that I'm not using a
cached version or anything you'll see
that it's gonna load pretty fast it's
not gonna load in 15 seconds it's gonna
load in less than a second and so we
don't need to keep scaling out and
that's all there is to deploy in kubera
Nettie's sorry deploying laravel on
kubernetes and auto scaling it
that just took three minutes of applying
a few files which are all I believe less
than a grand total of a hundred lines of
llamó now I know 100 lines of llamó is
like the equivalent of writing a
thousand lines of PHP but it's still not
bad so that's all there is to it now I
should mention of course before you
deploy to production right before you go
back and sit down with your laptop's now
and you're like I'm going to deploy in
kubernetes this was great I just learned
how to do it I shouldn't mention of
course this is not production ready
right and before you deploy to
production make sure that you do all
your research because there is a lot to
learn unfortunately there is a steep
learning curve to kubernetes but in this
talk I just wanted to show that can be
easy you don't need all the bells and
whistles sometimes you can just get it
done with five files also if you're not
that comfortable with docker then I
highly recommend that you go and watch
David McKay's talk from last year didn't
excellent talk on effectively how docker
works and how to write docker files and
docker images with laravel as an example
as that was last year's Larrick on but
now I'm going to provide you all a break
from llamó let you download the cube CTL
and hopefully enjoy the next talk thank
you
[Applause]
you
you
