TubeSum ← Transcribe a video

Deploying Laravel on Kubernetes with Docker | Part 5

1h 13m video Transcribed Jun 30, 2026 V Vadim Denis
Intermediate 25 min read For: Developers with basic knowledge of PHP/Laravel and familiarity with Docker and Kubernetes concepts who want to deploy Laravel applications in production.
2.0K
Views
40
Likes
1
Comments
0
Dislikes
2.0%
📊 Average

AI Summary

This video provides a comprehensive guide to deploying a Laravel application on Docker and Kubernetes, covering everything from setting up a backend repository and Dockerfile to configuring Nginx, PHP-FPM, and Supervisor. It also demonstrates how to set up CI/CD pipelines with Google Cloud Build, create Kubernetes workloads and services, implement liveness probes, and securely manage credentials using Kubernetes secrets.

[00:10]
Overview of Deployment Steps

The video will cover deploying Laravel on Docker and Kubernetes, including differences between Nginx and Apache, and supporting various Laravel setups like queues, Horizon, and high-load applications.

[01:01]
Creating Backend Repository

Create a private GitHub repository for the backend, enable Google Cloud Build, and clone sample configuration files for Laravel.

[02:04]
Setting Up Project Structure

Create a 'backend' folder, copy configuration files (config production, config staging, gitignore, Dockerfile) from a front-end template, and create the 'src/www/html' directory for Laravel.

[04:43]
Installing Laravel via Composer

Use Composer to create a new Laravel project inside 'src/www/html', then move files out of the 'example' subdirectory and verify installation with 'php artisan serve'.

[07:09]
Dockerfile and Configuration Files

Create a Dockerfile and copy Laravel-specific config files (entrypoint, Nginx config, PHP-FPM config, supervisor config) from example files. Explain each config file's purpose.

[11:07]
Adjusting Dockerfile for Laravel

Modify the Dockerfile: remove Node.js/npm, copy Laravel files, install Composer using multi-stage build, run 'composer install --optimize-autoloader --no-dev --no-interaction --no-progress', and expose port 8080.

[15:32]
Creating Kubernetes Workloads

In Google Kubernetes Engine, create two workloads (backend and backend-staging) using a basic Nginx image, then set up Cloud Build triggers for production and staging branches.

[19:26]
Pushing Code and First Build

Push code to GitHub master branch, triggering Cloud Build. Encounter an error due to leftover Node.js installation; fix by removing that line and recommit.

[24:42]
Deploying and Debugging

After successful build, update workload image. Use 'kubectl logs' and 'kubectl exec' to debug a missing .env file. Add environment files in config/staging and config/production.

[34:48]
Verifying Staging and Production

Both workloads become healthy. Create a staging branch, merge master, and push to trigger staging build. Verify both environments show different app names.

[42:37]
Adding Liveness Probe

Explain liveness probe: if a pod becomes unresponsive, Kubernetes restarts it. Add liveness and readiness probes to both workloads using HTTP GET on port 8080.

[48:46]
Why Nginx Over Apache

Nginx offers better performance under high concurrency. Benchmark shows response times around 36-40 ms. Apache slows down with thousands of concurrent requests.

[52:31]
Securing Credentials with Kubernetes Secrets

Create JSON credential files for production and staging, upload them as Kubernetes secrets, mount them as volumes in workloads, and use an init.php script to inject values into Laravel's .env file.

[67:02]
Final Verification

After fixing init.php not being executed (added call in entrypoint), both workloads deploy successfully with credentials injected. App names and keys are correctly set.

Clickbait Check

95% Legit

"The title accurately promises a full Laravel deployment on Docker and Kubernetes, and the video delivers exactly that with step-by-step instructions."

Mentioned in this Video

Tutorial Checklist

1 01:01 Create a private GitHub repository for the backend and enable Google Cloud Build.
2 02:04 Create a 'backend' folder and copy configuration files (config production, config staging, gitignore, Dockerfile) from a front-end template.
3 04:43 Create 'src/www/html' directory and install Laravel using 'composer create-project laravel/laravel example' then move files to html.
4 07:09 Create a Dockerfile and copy Laravel-specific config files (entrypoint, Nginx, PHP-FPM, supervisor) from example files.
5 11:07 Modify Dockerfile: remove Node.js, copy Laravel files, install Composer via multi-stage build, run 'composer install --optimize-autoloader --no-dev --no-interaction --no-progress', expose port 8080.
6 15:32 In GKE, create two workloads (backend and backend-staging) using a basic Nginx image, then set up Cloud Build triggers for production and staging branches.
7 19:26 Push code to GitHub master branch, fix build errors (remove Node.js install line), and recommit.
8 24:42 After build, update workload image. Debug missing .env file by adding environment files in config/staging and config/production.
9 34:48 Create a staging branch from master, merge, and push to trigger staging build. Verify both environments show different app names.
10 42:37 Add liveness and readiness probes to both workloads using HTTP GET on port 8080 with initial delay 30s, period 1s, failure threshold 4.
11 52:31 Create JSON credential files for production and staging, upload as Kubernetes secrets, mount as volumes, and create init.php to inject values into .env.
12 67:02 Call init.php in the entrypoint script to ensure credentials are injected before Laravel starts.

Study Flashcards (10)

What command is used to create a new Laravel project?

easy Click to reveal answer

composer create-project laravel/laravel example

05:40

Which port does the Dockerfile expose for the Laravel application?

easy Click to reveal answer

8080

14:50

What flags are used with composer install for production?

medium Click to reveal answer

--optimize-autoloader --no-dev --no-interaction --no-progress

14:15

How do you add a liveness probe in a Kubernetes workload YAML?

medium Click to reveal answer

Add a 'livenessProbe' section under the container spec with HTTP GET on port 8080, initialDelaySeconds, periodSeconds, and failureThreshold.

44:34

What is the purpose of the init.php file?

hard Click to reveal answer

To read credentials from a JSON file mounted as a Kubernetes secret and inject them into Laravel's .env file.

62:16

Why is Nginx preferred over Apache for Laravel in this tutorial?

medium Click to reveal answer

Nginx offers better performance under high concurrency, with response times around 36-40 ms, while Apache slows down with thousands of concurrent requests.

48:46

What command is used to create a Kubernetes secret from a JSON file?

medium Click to reveal answer

kubectl create secret generic credentials --from-file=credentials.json

57:04

How do you mount a Kubernetes secret as a volume in a pod?

hard Click to reveal answer

Add a 'volumes' section with the secret name and a 'volumeMounts' section in the container spec.

59:00

What is the initial delay for the liveness probe in this tutorial?

easy Click to reveal answer

30 seconds

44:49

What is the difference between readiness and liveness probes?

medium Click to reveal answer

Readiness probe determines if a pod is ready to serve traffic; liveness probe determines if a pod is healthy and should be restarted if it fails.

44:24

💡 Key Takeaways

💡

Comprehensive Deployment Guide

Sets clear expectations for the entire tutorial covering all use cases.

00:10
🔧

Optimized Composer Install

Shows production-ready flags for composer install to avoid interactive prompts and dev dependencies.

14:15
⚖️

Liveness Probe Explanation

Explains why liveness probes are critical for self-healing Kubernetes deployments.

42:37
📊

Nginx vs Apache Performance

Provides a concrete reason for choosing Nginx over Apache for Laravel in containerized environments.

48:46
🔧

Secure Credential Management

Demonstrates a secure pattern for injecting secrets into Laravel without exposing them in code or GitHub.

52:31

✂️ Creator Tools: Viral Hooks

AI-generated clip ideas for Shorts based on the transcript

Deploy Laravel on Kubernetes in 47 Seconds

47s

Quick, high-value tutorial promise that hooks developers looking for efficient deployment solutions.

▶ Play Clip

Why Nginx Beats Apache for Laravel

60s

Controversial performance comparison that sparks debate among developers about web server choices.

▶ Play Clip

Fix Laravel Deployment Errors Fast

60s

Real-time debugging and error resolution is highly engaging and educational for developers facing similar issues.

▶ Play Clip

Secure Laravel Credentials on Kubernetes

60s

Critical security tip for hiding environment variables, addressing a common pain point in production deployments.

▶ Play Clip

Auto-Restart Laravel with Liveness Probes

60s

Practical Kubernetes feature that ensures app reliability, appealing to DevOps and backend engineers.

▶ Play Clip

[00:00] foreign

[00:10] I'm going to show you how to deploy PHP

[00:13] laravel on a Docker and kubernetes

[00:16] you'll know exactly how it's done we

[00:20] will tackle all use cases we will

[00:23] discuss the difference between engines

[00:26] and Apache server we will make sure that

[00:29] your Docker container environment is

[00:32] able to support any setup of level

[00:34] whether you're using Quran jobs Horizon

[00:37] whether your application is a really

[00:41] high load and high CPU application or

[00:43] the just API service or a web server you

[00:47] after completing this chapter you will

[00:50] know exactly how to deploy your

[00:53] layerable onto Docker and kubernetes

[00:56] okay let's work on setting up back-end

[00:59] workload for lateral

[01:01] so these are going to be our steps first

[01:03] of all let's go to your GitHub

[01:05] repository right here and let's create a

[01:08] backend Repository

[01:10] so I'm going to select that it's private

[01:12] and enable Google Cloud build right here

[01:16] so let's hit create Repository

[01:20] here you go so the repository is created

[01:23] now let's open the finder or the browser

[01:27] and uh

[01:29] let's go to our folder our learning

[01:32] folder and prerequisite is that you have

[01:35] to download the sample files for a

[01:37] backend because we will be using some

[01:39] level specific some PHP specific

[01:42] configuration files for engines this is

[01:45] why I want to make sure that you have

[01:47] the right files files with you so please

[01:50] download the files before starting this

[01:53] video and you can paste it in here such

[01:55] as backend example files so let's let's

[01:58] begin so let's create a new folder will

[02:01] called Beckett

[02:04] here you go now let's open your PHP

[02:07] store

[02:08] and let's open the repository the the

[02:11] folder

[02:15] here you go

[02:16] this is open so first of all

[02:20] um let's just copy the files that we can

[02:22] from the front-end repository and let's

[02:24] just go

[02:26] back

[02:28] to our front end project

[02:30] let's open it up

[02:36] so I'm gonna open it a new window

[02:44] so remember now we have couple of

[02:46] folders and a couple of files that we

[02:48] have to have so this is config config

[02:51] production config staging and the

[02:53] dashboard really what differs here is

[02:57] that we will be deploying layerable

[02:59] everything else the same however we will

[03:01] deploy a layerable so it's a little bit

[03:03] different

[03:05] so let's let's continue let's drag and

[03:09] drop couple of files so here let's copy

[03:13] config production config staging some

[03:15] some basic

[03:28] let's take a look

[03:33] here you go config production

[03:36] now let's go

[03:38] let's copy config staging

[03:46] now let's

[03:49] let's take these files

[03:51] will they create me a global staging

[03:54] production git ignore

[03:57] and it'll leave Docker file and config

[03:59] for now there

[04:02] let's see okay so in readme let me just

[04:05] change the name just so we have it I'm

[04:07] gonna call it back end

[04:10] and really you can call it any name you

[04:12] want you can call back end you can call

[04:13] it any any way you want

[04:17] so we have copied that

[04:19] let's let's now create the most

[04:23] important directory here where we're

[04:25] going to store level so let's hit here

[04:28] let's create new folder SRC

[04:34] www

[04:36] in HTML so in this folder we will hold

[04:40] variable and let's install the level

[04:43] let's open Terminal

[04:46] and let me go to level's original

[04:47] website and let's

[04:50] take a look installable

[04:55] installation

[04:58] here you go

[05:06] shouldn't be fairly simple

[05:16] okay

[05:20] okay let's do this

[05:26] let me just change them into ninth

[05:28] version to the latest one

[05:31] I'm going to call it example

[05:34] and again as a prerequisite you should

[05:36] have composer installed

[05:40] so now let's go to CD SRC

[05:43] www.html and let's hit composer create

[05:46] project

[05:56] here you go it's installing all the

[05:58] packages right now

[06:00] and most likely we will need to move it

[06:02] back in HTML folder let's take a look

[06:09] here you go so now let's move all files

[06:11] out of example into the HTML

[06:21] okay so as you see it's indexing in the

[06:23] bottom so let's give it one more minute

[06:24] to finish indexing

[06:27] it has finished indexing so now let's

[06:29] just copy these files into HTML

[06:33] let's give it one second to refactor it

[06:39] great so we have moved all the files so

[06:42] now let's delete example

[06:43] and let's put PHP Artisan server to

[06:47] ensure that everything is installed

[06:48] properly

[06:51] I just go here here you go level was

[06:53] installed successfully so V Should Be

[06:56] Alright to continue

[06:58] okay so now a couple of things first of

[07:01] all we will have to begin with the

[07:03] docker file so let's create a new Docker

[07:05] file

[07:09] and we will need to use a config

[07:11] this config will be specific to level

[07:13] application so let's create a folder and

[07:16] now it's the time to open our folder our

[07:20] example files and just go in here go to

[07:23] config directory and just copy all the

[07:27] files and again we're going to go

[07:28] through them so no no worries so let's

[07:31] just copy them here

[07:33] here you go we have copy the files so

[07:36] the entry point this is the

[07:39] so now let me walk you through each file

[07:41] so you have a full understanding there

[07:43] are no files that are not making any

[07:45] sense for you so entry point this is the

[07:48] file that we will use whenever we deploy

[07:51] the docker container and here we are

[07:53] essentially telling level hey

[07:56] create the cache for a config and create

[07:59] the cache for routes because this is

[08:01] what's going to optimize lateral

[08:03] application

[08:04] and now we're passing the command to

[08:06] exits to to be executed now let's take a

[08:10] look on fbm pull not configuration

[08:13] so this is spec this is engine specific

[08:16] configuration that we use for PHP

[08:21] so we we could go in depth here but this

[08:24] is not going to be covered in this

[08:26] lesson so for now just copy them in and

[08:29] in short these are just the

[08:30] configuration files for our engines PHP

[08:33] server really the fpm extension of PHP

[08:37] so now we have engines configuration

[08:40] file

[08:41] and uh right here we have a couple of

[08:44] things here

[08:46] let's let's go to the server this is the

[08:49] 30 second line and here we are listening

[08:52] to the port 8080 and we are exposing the

[08:55] server name as the local server which is

[08:58] fine in production you can put your

[08:59] domain name here so keep a live time of

[09:02] this set for 70 seconds and here we are

[09:06] saying that the raw directory of our

[09:08] application will be located in this spot

[09:12] so VAR www HTML in public because the

[09:15] way light level works as you see here

[09:18] index PHP is located in the public

[09:21] folder

[09:22] and usually if you would deploy it on

[09:24] Apache you would put htxs in this folder

[09:28] right here however in this case and Jinx

[09:30] does not need HD access because it's

[09:32] really slowing down the requests so in

[09:34] this case we can even delete it if you

[09:36] don't need it and here we're just

[09:38] telling the engines that this is the

[09:40] directory and it should be pointing to

[09:42] index PHP right here

[09:44] and here we are saying drive files in

[09:46] index PHP right away

[09:49] and this is the configuration where we

[09:52] are passing down requests to PHP fpm

[09:54] that's listening on 9000 port

[09:58] and let's go right here and this is G

[10:01] sub configuration so this is really very

[10:04] optimized in Jinx configuration

[10:06] and let's go to the PHP e this is

[10:10] another PHP configuration which you can

[10:13] adjust as you need however I'm finding

[10:15] it to be very optimized where it's

[10:17] working very well however you can change

[10:19] it as you need and now let's go to

[10:21] supervisor configuration very important

[10:24] file because this is what's really

[10:27] running our server

[10:29] here we are running supervisor and let's

[10:32] examine this one so we are running PHP

[10:35] fpm this is what we need in order in

[10:38] order to host our PHP application and

[10:40] here we're running engines and this is

[10:43] really the case where you really need to

[10:45] use supervisor configuration because

[10:47] otherwise running both ground jobs on a

[10:50] very optimized Alpine Linux is going to

[10:53] be challenging this and here supervisor

[10:55] is really helping us

[10:58] all right so so we have went through the

[11:01] configuration file let's just close this

[11:03] directory and now let's work on our

[11:06] Docker file

[11:07] so first of all let's open your previous

[11:09] project and we will start with

[11:12] correcting it so so let's go to Docker

[11:14] file in our previous project

[11:17] let's copy paste it

[11:19] and let's set it up here

[11:22] so

[11:26] so now this is the docker file that we

[11:29] were using to run our react.js

[11:32] application however now it will be a

[11:34] little bit different because now we

[11:36] don't need to to have npm we don't need

[11:38] to have node.js we just need to run our

[11:40] lateral application

[11:43] so now let's adjust our Docker file so

[11:46] it would be working fine with lateral so

[11:48] let's just scroll down right here we can

[11:51] actually remove node.js

[11:53] npm

[11:56] so let's just remove that and let's

[11:58] scroll down to line number 17. so here

[12:02] we are entering

[12:04] as a you as a user engines and now let's

[12:07] just change up this part and let's build

[12:09] our lateral application so let me just

[12:12] make a comment so build up

[12:16] and now we're going to copy all our

[12:18] folder SRC www to to the correct

[12:22] location so let's let's do that now

[12:25] so copy

[12:26] Sean

[12:28] equals engines and now we are saying

[12:30] copy the files from WWW folder

[12:33] to this directory okay and now let's

[12:37] just copy our environment file because

[12:39] it will be located in a different

[12:41] directory it can be either in config

[12:43] production or config staging so let's do

[12:46] that right now

[12:47] and you can actually copy this part

[12:50] right here from the bottom

[12:52] in order to be consistent uh consistent

[12:54] I'm just gonna type it

[12:56] so the same rule in jinx let's say now

[13:00] config path

[13:03] environment file and we will place it in

[13:06] the root directory of flyable and now as

[13:09] you see

[13:10] it's even easier to install lateral we

[13:12] can just go ahead and remove this part

[13:15] right here

[13:16] however we need to install the packages

[13:19] for lab for the level so let's install

[13:21] packages right here

[13:23] and first of all

[13:25] we need to install composer because this

[13:27] composer I mean this Docker image does

[13:30] not know what it what composer is it

[13:32] doesn't have it installed so in this

[13:34] case Docker makes it very simple to

[13:37] install it and really if you would be

[13:39] doing it manually you would be launching

[13:41] some scripts and installing it however

[13:43] Docker makes it very simple for it

[13:46] Docker makes it very simple for us so

[13:49] let's say copy from composer latest so

[13:52] we are referencing the composer's

[13:54] directory

[13:55] user

[13:57] bin

[13:58] composer

[14:00] we are just defining a path right now

[14:03] and now let's run the installation

[14:05] because very important part so let's CD

[14:08] to our HTML folder

[14:10] and let's say user bin composer install

[14:15] and now we will use a couple of flags

[14:18] that really we should be using in a

[14:20] production environment so we will say

[14:22] optimize autoloader

[14:25] and it will say no development

[14:29] we don't need no interaction

[14:31] what is interaction it can start asking

[14:34] you are you sure you want to install

[14:35] that package yes or no and that's

[14:38] something we cannot have on when we when

[14:41] we're running Cloud build so here we

[14:43] have it no Dev optimize Auto loader no

[14:46] progress here you go so this is

[14:48] installed and now let's expose the ports

[14:50] so in this case really we will be using

[14:53] just 8080 port

[14:55] however whenever you're running

[14:57] production case scenario you would want

[14:59] to remove 8080 you'd want to keep only

[15:03] 8443 Port so now let's quickly glance

[15:06] through this file to make sure to make

[15:09] sure that everything looks correct

[15:11] because you know whenever you're typing

[15:13] you can make mistakes and that's fine

[15:14] this is why it's always good to go

[15:17] through the code

[15:20] okay though everything looks fine for

[15:23] myself

[15:26] so now before we commit everything to

[15:29] GitHub and set up CI pipeline let's go

[15:32] to our kubernetes and let's create

[15:37] the workload so we can close the lateral

[15:39] documentation you can go to workload and

[15:42] let's press deploy right here

[15:45] okay so but whenever we are deployed we

[15:47] can just deployed the regular regular

[15:49] engines image I'm gonna press continue

[15:51] and I'm gonna say backend

[15:55] and we will keep the fold namespace

[15:57] right here

[15:59] I'm going to say deploy

[16:01] and now I'm going to make another

[16:02] backend instance and then this one will

[16:04] be for the staging environment so let's

[16:06] keep the same engines image which is

[16:09] very basic and here we will say the same

[16:12] thing back end and I'm going to put

[16:14] staging as a namespace okay so

[16:17] everything checks out everything is fine

[16:19] and now we have deployed to work

[16:22] workloads really that was fast

[16:26] so now

[16:28] let's make sure that the repository is

[16:31] connected so first of all let's go to

[16:34] Cloud build let's go to triggers

[16:37] and let's set up two triggers let's

[16:39] press create trigger

[16:43] and I'm gonna say backend

[16:49] and now let's add the repository right

[16:51] here

[16:55] so now you need to connect a new

[16:57] repository in my case I'm going to press

[16:59] continue I'm gonna authenticate

[17:01] and now it will allow me to select

[17:03] repositories

[17:05] here you go I have selected my GitHub

[17:07] account I have created a repository

[17:12] and now let's press connect

[17:15] here you go it was connected so let's

[17:16] just select it right here

[17:18] and let's choose master Branch okay

[17:26] all right and now everything looks fine

[17:29] here

[17:34] okay and now let's just take a look how

[17:37] we called our file so we called it Cloud

[17:40] build production

[17:41] so let's just call it the same way here

[17:46] Cloud build production

[17:48] and let's hit create

[17:51] and now let's create one more back-end

[17:53] trigger for staging environment okay

[18:00] so backend staging

[18:06] right here

[18:08] so let's select our repository once

[18:11] again I'm going to say staging as a

[18:13] branch

[18:15] and here I'm just going to change it to

[18:17] Cloud build staging

[18:20] all right

[18:24] so now let's go back to our workloads

[18:26] right here and now we have two workloads

[18:28] backend and back end uh one is under

[18:31] staging environment another one is under

[18:33] default environment so now let's go to

[18:36] our PHP storm right here

[18:39] and let's go back let's go to Cloud

[18:43] build production

[18:45] so now make make sure that you have

[18:47] proper project ID set up the zone is set

[18:51] up and here we will change

[18:53] front-end deployment to back-end

[18:55] deployment and really this is

[18:58] all we're doing right here

[19:00] so let's go down Cloud build staging

[19:04] and as you as you're really seeing we're

[19:06] using the same thing we use for

[19:07] front-end however changing couple of

[19:09] things

[19:11] and now let's

[19:13] emitted with the GitHub so please go

[19:16] back to your GitHub page right here and

[19:19] now let's

[19:22] let's push our code to production to

[19:25] GitHub

[19:26] so let me just open my terminal

[19:29] I'm gonna go to main directory of the

[19:31] folder

[19:33] of the project okay getting it

[19:37] so I'm gonna add all the files

[19:41] however you want to make sure that you

[19:44] have proper configuration on the git

[19:46] ignore and something you don't you want

[19:49] to ignore

[19:50] is the vendor folder and as you see it's

[19:52] already being ignored so so it's fine

[19:55] all right so now

[19:57] let's add all files

[20:03] let's make sure that there is no GitHub

[20:05] repository initialized under the level

[20:08] so as you see here I just checked the

[20:10] files it's fine

[20:14] so now

[20:15] let's add all the files it's fine

[20:21] so now let's make our first commit

[20:26] and and in this case I'm not copying the

[20:28] whole thing I'm gonna make a master

[20:30] Branch as you see master

[20:33] let's add an origin

[20:36] and let's push everything to the master

[20:38] Branch all right

[20:42] here you go we have submitted our code

[20:44] to this Repository

[20:46] let's take a look

[20:48] here you go and as you see our Cloud

[20:50] build is spending right now so let's

[20:52] take a look what's happening here let's

[20:53] go to Cloud build history

[20:57] and as you see it's Panic right now so

[20:59] really what's happening behind the

[21:00] scenes right now Google is spinning up

[21:02] the worker pull the one that we are uh

[21:06] we created so it's right now bringing it

[21:09] up alive

[21:10] and it will start processing our image

[21:12] on that worker pool

[21:18] and while and while we are waiting for

[21:20] it to spin up let's just go to workloads

[21:22] and let's make sure we have nice

[21:24] configurations there so let's go to the

[21:27] staging one let's press enrolling update

[21:30] let's change it to 75 percent here

[21:33] five percent

[21:35] this is fine so as far as the auto scale

[21:37] we can keep it at one really we don't

[21:39] need Auto scale at this time however

[21:42] however when you're running production

[21:44] environment you could have it

[21:46] I mean you should have that enabled so

[21:49] now I went to backend which is under

[21:51] default namespace and I'm going to do

[21:54] the same thing I pressed as a maximum

[21:56] paths as a maximum replicas one and now

[21:59] here you would want to when you never

[22:02] you're running production environment to

[22:04] set it up for like 60 70 percent

[22:06] so let's just do that as an example

[22:10] so so here we have two metrics CPU 70

[22:13] percent and memory seventy percent as

[22:15] soon as it sees that the CPU is coming

[22:17] high it's going to make new replicas new

[22:19] instances new pods and this is what you

[22:21] want to have

[22:22] all right and let's just quickly do the

[22:25] same thing for our staging

[22:28] workload

[22:31] we are okay here

[22:35] and let's just add it in

[22:43] and really if we are using this we want

[22:46] let's just put it in four three let's

[22:49] keep maximum three three replicas

[22:54] let's just do the same thing here as

[22:56] well

[22:59] okay and now let's go to our Cloud build

[23:02] and let's see what is the progress

[23:06] so here you go we did encounter an issue

[23:08] so let's take a look what was the

[23:10] problem right here so as you see here we

[23:12] were installing node and we don't

[23:15] need this package and really the problem

[23:17] problem is that we removed

[23:21] then pm and node.js however we are

[23:24] installing it here so let's just remove

[23:26] this line right here

[23:28] let's make sure we don't use it no

[23:30] nowhere else

[23:32] and now let's make another commit

[23:34] and I'm gonna say remove

[23:39] note

[23:42] here you go

[23:44] now let's take it look on history and

[23:47] now it should be able to deploy and

[23:49] create this build process much more

[23:51] faster than it did before so let's take

[23:55] a look

[23:58] so now our build is running

[24:01] let's open it

[24:03] and now we can see that it's pulling the

[24:04] latest image now it's running

[24:11] so now let's give it like 30 seconds it

[24:14] should be it should be done by then

[24:18] so here everything went pretty well as

[24:20] you see no errors here it copied the

[24:22] files copy the application really fast

[24:24] and now you can see here that we are

[24:28] running composer install and now it's

[24:30] installing our packages so everything is

[24:32] working as expected it exposed the ports

[24:35] it created the image and now it's

[24:36] pushing it to container registry and

[24:39] when done it's gonna update our workload

[24:42] so let's give it a few more seconds

[24:51] here you go so now it's

[24:54] snug has updated the image of our

[24:56] workload so we can go to kubernetes

[24:58] engine workloads and now we will see

[25:01] this error right here it's really

[25:02] because it's updating

[25:04] the the image

[25:06] as you see it's unschedulable right here

[25:09] so now let's just

[25:11] put it for minimum two instances

[25:13] because this way you really won't

[25:15] experience the downtime because when

[25:16] another instance is built it becomes

[25:18] green it's running it's really healthy

[25:21] only then Google is going to kill the

[25:23] other old instance

[25:26] so now let's hit refresh

[25:29] and as you see currently it's on

[25:30] scheduleable so what's happening is that

[25:33] autopilot cluster is so optimized it's

[25:36] not using resources you don't want to

[25:38] pay for and this is why it's allocating

[25:41] the resources right now and when the

[25:43] resources are allocated it's gonna push

[25:46] these images and they will be healthy

[25:51] and let's press refresh one more time

[25:54] and as you see here it's already

[25:55] creating our cluster so we have two more

[25:58] things we have to do in order to access

[26:00] our backend workload so first of all

[26:02] let's fix up our yaml file so let's just

[26:06] press edit right here and this is so

[26:09] crucial that you know how to use yaml

[26:12] file so here

[26:15] really we don't care about this part we

[26:17] don't care about this part we care only

[26:19] about the part uh after specs so in this

[26:23] case as you see here we have two images

[26:25] one is our image and another one is in

[26:28] Jinx the one we used to make this

[26:30] workload so let's just select it and

[26:33] let's hit delete

[26:36] let's delete this part as well

[26:39] and these resource requests are fine

[26:42] this is okay

[26:44] and let's press save right here

[26:47] as you see it's saying that it's

[26:48] deploying right now another update and

[26:50] let's just force update it it's fine

[26:53] okay

[26:54] so this is okay now let's make the

[26:58] server so in my case uh there is a

[27:00] service already created from before

[27:02] however what you would do in this case

[27:05] you would press expose you would you're

[27:08] gonna say 80 here so this is the outside

[27:11] port and here we will select we will put

[27:15] 8080 because this is the port you're

[27:17] exposing in a Docker image when you go

[27:19] to Docker file and as you see here 8080

[27:21] this is what you're exposing

[27:24] so now let's select it here let's press

[27:27] load balancer right here

[27:29] and just press expose

[27:33] and now it's going to create a new load

[27:35] balancer

[27:38] and usually takes few minutes

[27:41] maybe one minute to spin up so let's

[27:43] just wait it

[27:47] so now after a couple of free verses you

[27:49] can see that you were assigned a load

[27:51] balancer ID so let's make sure that we

[27:54] reserve it as a static IP let's go to

[27:56] our Network Services let's let's go to

[27:58] VPC Network external IP addresses

[28:02] and now let's do Ctrl F and let's search

[28:05] for AP address so here we go it's a

[28:07] thermal so we want to make it static I'm

[28:09] going to call it backend

[28:11] service AP

[28:14] here you go we have reserved it so now

[28:16] let's go back to kubernetes and let's

[28:19] test it out everything should be working

[28:21] now

[28:23] so let's go to back end we're going to

[28:25] go to default right here

[28:28] and let's really open any so this was my

[28:31] old balance this is a new one and as you

[28:33] see here we are getting an error and

[28:36] this is fine the very most important

[28:39] skill is for you to know how to debug it

[28:41] how to access it and this is what we're

[28:43] gonna do right now so let's go back here

[28:46] first of all let's ensure you have only

[28:48] one pad running because this is

[28:50] easier to debug it this way let's press

[28:52] update and now let's open your terminal

[28:56] and now we will try to access it

[29:01] so let's open your terminal right here

[29:09] so first of all you want to authenticate

[29:11] so let's do that let's just copy your

[29:14] email so in my case this is a demon CTO

[29:17] mentorship.com so let's do that gcloud

[29:20] authenticate

[29:29] all right it's not allowing me let's

[29:31] take a look

[29:34] so the problem is that we have to say of

[29:36] login

[29:39] okay this is fine now we want to set the

[29:41] project ID let's copy the ID here

[29:48] and now let's say gcloud

[29:51] config set project

[29:58] for some reason it basted it two times

[30:00] it's okay

[30:02] okay so this this was updated and now

[30:04] let's get access to this cluster so we

[30:07] have autopilot cluster one running on a

[30:09] Zone us yeast

[30:11] for

[30:12] so let's do that let's just say the

[30:14] following in gcloud

[30:18] container

[30:19] clusters

[30:21] get credentials

[30:24] and we will say

[30:26] you can copy the name so it is autopilot

[30:29] cluster one

[30:32] and it's very important to specify the

[30:34] zone so in this case it's Us East 4. all

[30:38] right

[30:41] so now that was successful so now let's

[30:42] just go here

[30:46] so let's open up

[30:51] and first of all let's just examine

[30:53] regular logs

[30:56] Cube CTL logs now you paste in the

[31:00] workloaded workload ID

[31:02] and that's it so now when we look at

[31:04] these logs it's really not helping us

[31:07] much so that's fine so now let's go to

[31:10] actual container so we will say Cube CTL

[31:12] execute the paste in the

[31:18] pod ID

[31:19] and let's say sh

[31:22] so that's the command

[31:24] you're using

[31:27] now let's go to HTML folder and let's

[31:30] take a look what's going on

[31:32] in the configuration file so here see

[31:35] it's very simple you're getting some

[31:37] error here level doesn't like it

[31:40] so now as you see here it was so simple

[31:44] we just messed up both environment file

[31:46] for the lateral because it cannot work

[31:48] with the environment without an

[31:50] environment file

[31:51] so now let's

[31:53] and really you might ask but hey why

[31:55] doesn't use this environment file why

[31:58] the answer is simple it's ignored and we

[32:00] don't push it to GitHub this is the only

[32:02] reason okay so now just going here don't

[32:05] environment file

[32:07] go to config staging and let's just

[32:09] paste it in and you can call you can

[32:12] change the application name from laravel

[32:14] to level staging and you can keep local

[32:18] environment

[32:19] and now let's go to config production

[32:23] and in this case we'll call our

[32:25] application Level production

[32:28] and here you will say

[32:31] the environment is production

[32:33] and the debug is false

[32:36] now let's make this change

[32:41] now added environment files

[32:50] and really in production case you would

[32:52] not be exposing all your environment

[32:54] files just like that and and I'm going

[32:56] to show you a couple of Tricks how you

[32:58] can hide it

[32:59] by using um secrets from the Google

[33:02] Cloud kubernetes engine

[33:05] but now let's take a look on our Cloud

[33:08] build

[33:14] as you see it was cute and now whenever

[33:17] we are done with our Master Branch we

[33:20] will set up our staging Branch so while

[33:22] it's loading let's just go to the

[33:24] staging workload

[33:26] and let's fix up the yaml file as well

[33:28] let's go here

[33:33] and in this case we didn't push anything

[33:34] yet

[33:35] it's fine

[33:37] so in this case let's create a service

[33:40] in my case the service is already

[33:41] created

[33:42] but

[33:44] let's just press expose

[33:47] and let's target the 8084 the same way

[33:50] we did it before it's all right

[33:53] and again for production scenario you

[33:55] would put 443 here eight four four three

[33:58] here and you would not even expose port

[34:00] 80. so let's press expose

[34:04] and now let's give it one more minute in

[34:07] order to

[34:08] in order for it to create

[34:12] here you go it was created

[34:15] so now we have our right B right here

[34:17] let's just make a copy of that let's go

[34:20] to VPC Network external IP addresses

[34:24] and let's make a static IP as well

[34:26] what's reserved

[34:27] and I'm gonna call it back-end staging

[34:31] service IP all right

[34:35] and while we were doing it I'm sure the

[34:37] back end

[34:38] part is already ready

[34:40] take a look if it's still building

[34:44] yep it's done so now let's go here

[34:48] here you go the lateral is working

[34:50] everything is working fine

[34:53] and now

[34:57] you can make sure that this is lay this

[34:59] the image by going to your workload and

[35:01] taking a look when was the bot created

[35:03] it was created at 9 10 pm so this was

[35:06] just now and this is the latest path and

[35:08] it's working so now let's create a

[35:10] staging environment

[35:12] okay so in here we will

[35:16] say that we want to create a new

[35:18] environment okay so create Branch

[35:21] staging from Master okay

[35:23] so now we just created our staging

[35:26] branch and it just copied the master

[35:27] into the stage

[35:30] so now let's go to our Cloud build

[35:33] let's take a look and now as you see

[35:37] it's building our image and the name of

[35:40] the trigger is back and staging

[35:43] so here you go on the back end staging

[35:47] is building so now let's open it and

[35:49] let's say jump to top

[35:53] and as you see here it's installing the

[35:55] packages like the regular stuff

[36:01] and now it installed all our

[36:03] configuration files very quickly and now

[36:05] it's installing the packages

[36:10] see it was very quick it created its

[36:13] creating image right now and then it

[36:15] will push it to the workloads

[36:21] so now let's go to the workload let's

[36:22] open the staging one

[36:24] and now let's give it a few more seconds

[36:26] it shouldn't be able to it should it

[36:29] should update it right now

[36:36] just give it a little bit of time and

[36:38] press refresh

[36:45] here you go it updated it

[36:48] so now we really don't have time and

[36:50] there's no need for us to wait for it to

[36:53] work so now let's just press edit

[36:55] because we have to configure the yaml

[36:58] file and in this case just find all this

[37:01] configuration for engine server

[37:04] starting from termination message policy

[37:07] and now let's remove it

[37:09] and now we have our application right

[37:11] here as you see it's staging

[37:17] I updated everything is fine

[37:20] I'm gonna say that that we have minimum

[37:23] two parts

[37:30] all right so we need to wait for it to

[37:32] finish up

[37:39] now let's hit refresh

[37:45] so here you go everything is working so

[37:47] now let's take a look

[37:49] and whenever we're going to this IP

[37:51] address it is working so we are getting

[37:53] Level and now you might be thinking hey

[37:55] but how do I know it's staging

[37:57] environment really there are many ways

[37:59] but let's just

[38:02] let's make sure that we can change here

[38:04] level and we will call it lateral State

[38:06] staging

[38:07] so now

[38:09] let's say git pull

[38:11] and now

[38:14] and now we got our staging Branch right

[38:17] here

[38:19] and now this is what we want to do we

[38:20] want to put this app name in our

[38:24] um title so now let's open resources

[38:26] views welcome to the blade and now we

[38:29] will change this lateral and we will say

[38:32] config

[38:35] app

[38:37] name

[38:39] let's just test it out quickly

[38:44] to make sure it's working all right

[38:49] see I'm launching the server

[38:52] here you go so in this case it didn't

[38:55] change the title title here for some

[38:57] reason I'm supposing this is really

[38:59] because of the cash

[39:01] so let's try to add some character right

[39:04] here oh no no it's fine because you see

[39:07] it's exposing the name from the local

[39:08] environment and it is

[39:10] layerable as you see here so everything

[39:12] is working properly

[39:14] so now let's just close it out

[39:19] let's make it let's make a comment and

[39:22] update app name

[39:25] and really this is really and really you

[39:28] would not be doing it you will not be

[39:30] changing title you would be using

[39:31] lateral for some other things however

[39:33] this is a really good way for you to see

[39:36] that this is working that the staging

[39:38] name and production name are different

[39:40] so let's get let's say git switch

[39:43] staging

[39:45] okay and now we will say git merge

[39:48] origin master

[39:50] so now we have chain we can push the

[39:52] code from Master Branch to staging

[39:54] branch and now let's say git commit

[39:57] merge

[39:59] in this case we don't need that and we

[40:01] just say git push

[40:03] so now let's go to the Google ROM let's

[40:06] go to our Cloud build

[40:08] and we should be seeing two builds

[40:11] running one for master one for staging

[40:14] here you go both are cute so let's give

[40:16] a couple of minutes for them to build

[40:20] so as you heat as you see here both

[40:22] builds are running right now so let's

[40:24] give it one more minute and we will be

[40:27] refreshing both of our

[40:30] workloads

[40:34] so usually if it doesn't show the

[40:35] duration of the build here you can just

[40:37] go to another page come back and as you

[40:39] see here the duration for this one

[40:43] is one minute 10 seconds for another one

[40:45] 34 seconds and you can take a look what

[40:47] is the usual time for it to build

[40:50] you can see here that this one took

[40:52] three minutes and then it took 50

[40:55] seconds so I'm supposing what happened

[40:57] it just cached

[40:59] and the second build was faster

[41:02] all right so let's take a look if this

[41:04] one is done yet

[41:06] as you see here it's updating so let's

[41:08] go to our workloads

[41:11] and we see that both are currently

[41:13] updating it's fine so you can just hit

[41:16] refer refresh give it a little bit of

[41:18] time

[41:23] let's

[41:24] let's wait for staging one to become

[41:27] available as well

[41:31] as you see it's almost done

[41:40] so here you go the third one is already

[41:41] terminating so no traffic will will be

[41:44] sent to the spot so we can go ahead

[41:47] and refresh it

[41:49] and here you go so you have one level

[41:51] staging and application name is level

[41:53] staging and for the second one it's

[41:56] lateral production

[41:57] so now you have successfully deployed

[42:00] both lateral applications and you have

[42:03] created the CI continuous integration

[42:06] environment for the laravel

[42:08] on the GitHub so now the things that you

[42:12] would want to add

[42:13] let's go back here to front end

[42:16] you would really want that

[42:18] the Readiness probe because this is

[42:21] always a good practice to add Readiness

[42:22] probe

[42:24] for your application however in next

[42:26] video I'm gonna talk about liveness

[42:28] probe and we will add both probes to our

[42:31] lateral application

[42:37] in this video we're gonna talk about

[42:39] liveness probe so first of all what is

[42:42] it what do we need and what is the use

[42:44] case so imagine that your application is

[42:47] running everything is fine and then at

[42:49] some moment it it gets some Deadlocks or

[42:52] something happens and it it just doesn't

[42:55] work and

[42:57] that those things can happen

[42:58] unfortunately ideally you would fix up

[43:00] your application for it to not happen

[43:03] however if that happens there's a way

[43:06] for vocal to be restarted so imagine

[43:09] it's deploying your pods and you have 10

[43:12] parts and one of the Pod really becomes

[43:15] unresponsive it just does not want to

[43:17] work and and we can tell kubernetes hey

[43:21] if this spot doesn't work for x amount

[43:25] of time go ahead and restart it and what

[43:28] it's going to do we're just gonna kill

[43:30] it and it's gonna recreate it and this

[43:33] way it's very good because this way you

[43:35] can ensure that all your workloads all

[43:39] your pods are healthy at all times so

[43:42] now let's install it for a back-end

[43:44] instance so let's press on backhand

[43:47] let's hit edit button

[43:50] and

[43:52] and let's scroll down

[43:55] to this path so resources so first of

[43:58] all you don't want to invent the wheel

[44:00] we are not here to invent the wheel so

[44:03] now let's go to front end

[44:05] so this is your old workload

[44:09] this is where we install the Readiness

[44:11] probe so now let's just copy this part

[44:13] right here

[44:14] and let's paste it here as well

[44:19] and and paste it one more time so

[44:22] imagine that

[44:24] Readiness probe and liveness probe are

[44:27] very similar

[44:28] so in this case we're just going to

[44:30] change the second one and we will call

[44:32] it

[44:34] to see aliveness

[44:37] probe

[44:39] and the configuration file is the same

[44:44] so here we can say if it's failing let's

[44:46] say four times uh initial delay 30

[44:49] seconds and it should be attempting to

[44:51] query our application every second

[44:55] so let's hit save

[44:58] and just in case if in case you're

[45:00] wondering you want to get some

[45:01] documentation on how does it work or or

[45:04] something else you could just go ahead

[45:06] copy it go to Google and here you go

[45:10] Google is going to give you the

[45:11] documentation for kubernetes where they

[45:14] will show you how the liveness probe

[45:16] works and they will show you a couple of

[45:19] more configurations however I find it

[45:22] very useful

[45:24] so by the way let's just copy this one

[45:26] here so we can put it for the staging

[45:29] workload as well let's hit save here

[45:33] so this was ours actually this was our

[45:36] staging workload so now let's go to the

[45:38] master

[45:39] one

[45:42] let's hit edit

[45:47] let's scroll down

[45:50] and after resources we're just gonna

[45:52] paste it in right here okay so just hit

[45:55] save

[45:58] as you see here it's unschedulable

[45:59] that's all right

[46:03] staging one is currently updating it

[46:07] it's okay as you see the the same way we

[46:11] were experiencing the redness probe when

[46:14] we are working on the front end it's

[46:15] very similar here as you see that the

[46:18] Pod is under status running

[46:20] It's really because we added initial

[46:22] delay for 30 seconds so we want to give

[46:25] your application 30 seconds before we

[46:28] start sending requests to your

[46:30] application so let's hit refresh

[46:36] as you see here so this was deployed

[46:38] first pod was deployed and another one

[46:40] is awaiting

[46:43] so now let's go to another instance

[46:45] right here the default one

[46:49] and in this case what I would do I would

[46:51] increase it to two parts two replicas

[46:56] because this way it's going to be able

[46:57] to deploy a little bit faster

[47:04] so just refresh it and you can see that

[47:06] we have two parts that are currently

[47:08] running they're awaiting

[47:11] the delay

[47:12] so let's give them 10 more seconds and

[47:15] they should turn green and this one this

[47:18] old part should be terminated

[47:23] not yet let's wait

[47:33] here you go yep so they are fine so see

[47:36] this old part is being terminated and

[47:38] two new parts are healthy so now let's

[47:42] go back to our instances and we can

[47:43] ensure that everything is working fine

[47:46] here

[47:47] okay so this is how we deploy and use

[47:51] liveness probe

[47:56] you might ask

[47:58] and how does our application is going to

[48:00] use it it's very simple as soon as your

[48:02] application crashes and something

[48:04] happens there it's just gonna restart

[48:06] and how you would see it you can just go

[48:09] to your workload right here and where it

[48:12] says restarts right here zero currently

[48:15] it's zero but if your application

[48:17] decides to restart and Google kubernetes

[48:20] engine restarts it you will see that

[48:23] this number zero is going to increase

[48:25] and look out for those numbers because

[48:28] if your application is constantly

[48:30] restarting most likely it needs more

[48:33] memory or CPU or something is wrong this

[48:36] is why it's so important to look out and

[48:38] monitor your CPU memory in disk risk

[48:42] requests

[48:46] something I wanted to talk about with

[48:48] you is why did we choose engines

[48:51] and this is a very important topic

[48:53] because whenever you're deploying any

[48:55] application whether it's layerable or

[48:57] something else

[48:59] it's always about choosing web server

[49:00] and it's very important question

[49:03] because

[49:04] imagine you build your application and

[49:07] all your response times are quick

[49:09] your queries are quick

[49:11] everything is cached everything is

[49:13] optimized however it's still slow all

[49:15] your users users complaining that your

[49:17] backend is slow the response times is

[49:20] one second and so on and then you start

[49:22] thinking why is it the case I'm using

[49:25] PHP I'm using glarevel everything's fine

[49:27] and as you see it's not always about

[49:31] your applications not always about your

[49:33] code it's also the web server this is

[49:36] why choosing the right web server is so

[49:39] important for you and you might have

[49:42] heard about of Apache I think everyone

[49:44] has heard about Apache and this is

[49:46] really the web server that everybody was

[49:49] using and and

[49:51] think about it it's really great however

[49:53] when you start thinking about

[49:55] performance you want to get the lowest

[49:57] times the lowest response times and get

[50:00] the most performance all out of it you

[50:04] want to use engines

[50:06] because in Jinx is is built with the

[50:10] idea that it's really it's very similar

[50:13] to Apache however it brings the ultimate

[50:16] performance and this is a very simple

[50:19] way how we can test it so let's let's

[50:22] just go to level production or staging

[50:24] doesn't matter and you can take a look

[50:25] how much time does it take in Jinx to

[50:28] return this web page and you see it's

[50:31] 40 milliseconds and the smallest I've

[50:34] seen was 36 milliseconds just now and

[50:36] it's very quick

[50:38] and if you would want to Benchmark you

[50:40] can either go online and take a look on

[50:42] the benchmarks between Apache and

[50:44] engines or you can just deploy Apache on

[50:48] this Docker container and take a look

[50:49] what are going to be response times

[50:52] but even if the response time is fine

[50:55] for this empty project whenever you are

[50:57] running your big application and getting

[50:59] thousands upon thousands of requests at

[51:01] the same time Apache starts slowing down

[51:04] however engines remains very fast and

[51:08] this is the only reason why we used

[51:10] engines in this tutorial

[51:16] something I wanted to mention is you

[51:19] might be thinking why does it take us so

[51:22] much time to deploy a level on a

[51:25] production and staging environment it

[51:27] really took us so much time because we

[51:29] were doing everything from scratch

[51:30] however whenever you're creating

[51:33] multiple lateral applications such as

[51:36] some API some back-end service some

[51:38] robot service some calculation server

[51:42] and so many more apis and servers you

[51:46] would be having some template and really

[51:49] the template I'm talking about is this

[51:51] one so please go to your backend

[51:57] project

[51:58] and take a look right here so you would

[52:00] you would have this configuration file

[52:03] so this is that you are using for your

[52:04] level application you just change your

[52:07] environment files and here you would be

[52:10] having different level application

[52:12] however this wrapper all the production

[52:14] yaml files and so on they would remain

[52:17] the same this is why whenever you will

[52:19] deploy your next level application it

[52:22] will take you maybe five to ten minutes

[52:24] it will be much quicker than that

[52:31] whenever you're deploying your lateral

[52:33] application to production you want to

[52:35] make sure it's as secure as possible and

[52:38] currently the way we have it set up is

[52:41] that all your environment is exposed

[52:44] publicly and that's not the way you

[52:47] should have it so let's work on it so

[52:49] first of all let's make your environment

[52:51] configuration file so in this case I'm

[52:54] going to make a new folder I'm going to

[52:56] call it security or I'm going to say

[52:59] credentials all right

[53:02] and I'm gonna say

[53:05] um I'm gonna create a new file so let me

[53:06] just use

[53:09] a terminal as you see it doesn't allow

[53:11] me to create a new file it's fine let me

[53:13] use a terminal I'm gonna go to security

[53:17] actual credentials and I'm gonna say

[53:20] touch

[53:21] and I'm gonna call them

[53:24] credentials dot Json okay and we will

[53:28] make another credentials which are going

[53:30] to be staging credentials

[53:32] dot Json all right and now we have two

[53:36] files that we have created

[53:40] so now let's open each of the files okay

[53:43] let's open credentials

[53:46] we can use the text edit app it's fine

[53:48] now let's create a Json format and now

[53:53] let's say

[53:56] and now in this file what we're going to

[53:58] use it for we will expose our

[54:00] environment configurations in this file

[54:03] so in this case whatever we want to

[54:05] expose it's really the app app key

[54:10] let me just make a copy of this

[54:14] let me expose that name as well

[54:19] so you have it as an example

[54:23] in this case we will call it I mean it's

[54:26] called level production

[54:28] and really in production case scenario

[54:30] you would put all your database config

[54:34] any other passwords any other

[54:36] credentials you would keep in this file

[54:38] so now we will use only two things one

[54:41] is app name and second one is app key

[54:43] all right so this Json file is fine

[54:46] let's save it

[54:49] and let's open another file the staging

[54:54] credentials file all right

[54:56] so now let's just copy paste it

[54:58] and let's go

[55:00] right here

[55:04] let's just change this name right here

[55:06] and now you see we have a problem that

[55:08] the key is the same so we can go back to

[55:11] our backend instance

[55:13] okay and let's go to level and I'm gonna

[55:16] say PHP artisan

[55:18] key generate

[55:21] it has created the new key for myself

[55:24] I'm gonna go to environment file right

[55:26] here and I'm going to grab this key I'm

[55:29] going to go to config staging

[55:32] as you see we can change it up here

[55:35] it's really what we want to do

[55:37] we want to go here and change it up

[55:40] so now we have created two credential

[55:42] files and obviously we don't want to

[55:45] store these files locally so let's go

[55:48] back to these files and we will upload

[55:51] them as secret credentials on Google

[55:54] Cloud okay

[55:58] let's open the credentials folder and

[56:02] now let's execute the following command

[56:06] and before we can execute the right

[56:08] command in order in order to boost these

[56:10] credentials to your cluster you have to

[56:13] ensure that you have logged in that you

[56:15] did run Google Cloud

[56:18] authentication login your email and you

[56:21] got credentials of your cluster and just

[56:25] in case if yeah

[56:27] forgot the way the way you do it you

[56:30] would set up Google Cloud project set

[56:33] send to your ID and then you would get

[56:35] credentials in the following way you

[56:37] would say Google Cloud container

[56:39] clusters

[56:41] and then you would say your autopilot

[56:44] cluster and you would specify the zone

[56:46] you assist for okay so let's assume

[56:49] you've done that and now we will push

[56:52] these credentials all right

[56:54] it's now we will do the following we

[56:56] will say Cube

[56:58] CTL okay since the command is working

[57:01] create Secret

[57:04] and this is going to be generic type of

[57:06] the secret I mean there are more you

[57:08] could push your DLS SSL certificate to a

[57:11] cluster and more in this case it's

[57:13] really generic credentials that you're

[57:15] pushing and they will be called

[57:18] credentials

[57:24] the way it works you have to save from

[57:26] file

[57:27] you specify credentials the Json

[57:31] and credentials.json all right

[57:38] here you go this was created and now we

[57:41] need to create the same thing however

[57:43] for the staging environment so now

[57:45] what's going to change

[57:47] so here I'm going to change this one to

[57:51] staging credentials and I'm going to

[57:53] specify namespace so the way we do it we

[57:55] just say n

[57:57] and we say staging

[57:59] so now both secrets were created so now

[58:03] let's go to our cluster right here

[58:07] and let's open Secrets and config Maps

[58:12] and as you see here the credentials

[58:14] under default and staging they were

[58:17] created

[58:18] so we did the first part the most

[58:21] important part and now you might be

[58:23] thinking so how do I get these

[58:25] credentials attached to our laravel

[58:28] application so first of all we want to

[58:30] attach them to the workload so let's go

[58:33] here let's open our backend staging

[58:36] workload and at the same time let's open

[58:39] our front-end yam file so you would just

[58:41] open your front-end workload press edit

[58:43] and let's take a look the way these

[58:46] credentials were attached so you're

[58:48] really doing it on the volume level so

[58:51] here let's attach the volume to this

[58:54] workload

[59:00] so you would do it this way volume

[59:04] credentials secret name is credentials

[59:08] and now you want to mount it for your

[59:11] container so now we're doing the same

[59:14] thing so volume outs mounts we are

[59:17] mounting your credentials under this

[59:19] directory and the name of it is

[59:21] credentials all right now I'm gonna hit

[59:24] save right here

[59:25] and let's just do the same thing for the

[59:28] master

[59:35] now let's open it let's press edit

[59:42] all right so now let's do the same thing

[59:44] let's just copy the bottom part the

[59:46] volumes

[59:50] let's rename it to credentials

[59:57] and again you can keep it under any name

[59:59] you want it to be

[1:00:03] so the same thing copy paste

[1:00:07] and we changed it up

[1:00:10] so now before we Implement anything on a

[1:00:13] level let's make sure that you're able

[1:00:16] to access them

[1:00:18] in your image

[1:00:19] in your container so let's open the

[1:00:22] terminal

[1:00:23] let's clear it and I'm going to say Cube

[1:00:26] CTL execute

[1:00:28] e

[1:00:30] and Sh so before I do it I want to make

[1:00:33] sure that the instance is at least

[1:00:34] running

[1:00:36] so now I mean hit refresh

[1:00:38] and you see so it's already running so I

[1:00:41] can go ahead and execute it

[1:00:43] here you go I have accessed

[1:00:46] so now

[1:00:48] I just went to the main folder and now

[1:00:50] I'm going to go to this folder Secrets

[1:00:52] environment okay we are here and let's

[1:00:55] take a look on our credentials so here

[1:00:57] we go here is our Json file

[1:01:01] so now we got that part established that

[1:01:04] we have created the credentials we have

[1:01:06] uploaded them to the cluster and we have

[1:01:09] linked them with the workload and now

[1:01:11] they are accessible from your lateral

[1:01:14] application and you might ask so how do

[1:01:17] I actually exchange the environment file

[1:01:21] so take a look this is what we're gonna

[1:01:23] do

[1:01:24] go back to this part right here let's

[1:01:28] examine config production file right

[1:01:30] here

[1:01:31] okay

[1:01:33] and now let's change this part app name

[1:01:38] let's change it up to app name this way

[1:01:42] and we will do the same thing with the

[1:01:45] app key

[1:01:47] and a lot now let's go to the config

[1:01:49] staging

[1:01:51] let's do the same thing

[1:01:58] and as you see now we're not exposing

[1:02:00] any credentials on GitHub

[1:02:02] now it will be safe no problems however

[1:02:06] now we need to insert the information

[1:02:08] from your Json file into this

[1:02:11] environment file how do we do it

[1:02:13] we can do it the following way

[1:02:16] so we'll go back here's SRC www

[1:02:20] and let's create a new file I'm going to

[1:02:22] call it init .php

[1:02:28] and you want to add it to the GitHub

[1:02:30] location

[1:02:32] okay and now we want to define a couple

[1:02:35] of things right here okay so first of

[1:02:37] all is location of your environment file

[1:02:40] so

[1:02:42] we know it's in this location secrets

[1:02:44] environment and credentials that Json

[1:02:51] and the environment file is is located

[1:02:54] in this location

[1:02:58] and now you want to take these

[1:03:00] credentials and insert them right here

[1:03:03] and we can do it the following way so

[1:03:05] first of all let's let's get the

[1:03:07] credentials

[1:03:09] so we can do it the following way okay

[1:03:12] array

[1:03:15] Json code

[1:03:17] and we are getting the contents of the

[1:03:20] file

[1:03:24] so now we have your connection files in

[1:03:27] Array and

[1:03:29] we make a comment and we will say here

[1:03:31] so first of all we want to open your

[1:03:34] file

[1:03:35] get contents

[1:03:38] environment file

[1:03:42] and so usually it's better to specify

[1:03:45] that it's file so environment file

[1:03:49] and let's open it up right here

[1:03:52] open

[1:03:56] in a right mode

[1:04:02] now take take a look on this so now we

[1:04:05] are iterating our credentials as Keen

[1:04:07] value

[1:04:09] and now we are replacing

[1:04:13] let's take a look

[1:04:15] we are replacing

[1:04:17] this part

[1:04:20] but this part that you have defined in

[1:04:23] your Json file

[1:04:25] so whenever you understand it it becomes

[1:04:28] very simple so in this case we are

[1:04:31] searching

[1:04:33] for key

[1:04:36] and we are replacing it with the Valor

[1:04:40] so in this case you can see that I'm

[1:04:42] adding extra apostrops this is to make

[1:04:45] sure if credentials are long or they

[1:04:48] have special characters they're not

[1:04:49] gonna break the environment file this is

[1:04:52] a good practice

[1:04:53] okay so this is done now let's

[1:04:58] write

[1:05:00] B

[1:05:02] here and now let's close the file

[1:05:05] okay and this file again it's going to

[1:05:08] take all your credentials and they're

[1:05:10] gonna insert them in the environment

[1:05:11] file okay so as you see we are receiving

[1:05:15] some errands something is off here so

[1:05:17] let's take a look

[1:05:19] what is the problem okay

[1:05:28] so as you may know PHP might be acting

[1:05:30] sometimes so in this case I just remove

[1:05:32] this line I put it back and there are no

[1:05:34] errors right here all right so now let's

[1:05:38] go back to our backend instance right

[1:05:40] here

[1:05:41] let's

[1:05:43] make a comment

[1:05:45] so I'm gonna say initialize

[1:05:48] credentials the right way

[1:05:54] and now we're pushing it to the staging

[1:05:59] okay

[1:06:00] so everything should turn the blue color

[1:06:03] disappeared so now let's do the same for

[1:06:05] the master let's go to master get switch

[1:06:08] Master get the merge origin staging

[1:06:14] and

[1:06:16] let's just say git push

[1:06:19] all right

[1:06:20] and now let's just go to your GitHub

[1:06:22] real quick

[1:06:24] and let's take a look on something

[1:06:28] so now here as you see the way the

[1:06:32] credentials are stored config production

[1:06:33] config staging whenever you go to your

[1:06:36] environment file you will see that the

[1:06:39] name of the application app name and app

[1:06:41] key they are not exposed and now you're

[1:06:43] really safe because the only place where

[1:06:46] your credentials are stored at is on the

[1:06:49] cluster level and they are not stored on

[1:06:51] a cold level not in GitHub therefore

[1:06:53] you're safe now and this is really the

[1:06:56] way you should be deploying lateral

[1:06:58] always have to keep credentials safe

[1:07:02] so now let's wait for the build to

[1:07:05] create and then we will test it and make

[1:07:07] sure that the proper keys and proper

[1:07:10] application names are on each side

[1:07:13] so you see the mess the staging branch

[1:07:15] is already building and the master

[1:07:17] branch is currently waiting for the

[1:07:19] build

[1:07:21] so now let's go to the workloads

[1:07:28] so as you see here the master is already

[1:07:31] working

[1:07:32] it was deployed just now

[1:07:36] and now let's go back to the staging

[1:07:39] workloads

[1:07:41] and let's take a look right here

[1:07:44] all right

[1:07:47] so as you see here it's getting

[1:07:49] restarted and what this means that there

[1:07:52] is some error and there is the following

[1:07:56] now I wanted to show you the way restart

[1:07:58] Works actually because whenever larval

[1:08:01] starts running it gets some fatal error

[1:08:03] and

[1:08:04] it gets restarted okay so in this case

[1:08:07] as you see the radio started four times

[1:08:09] and really the problem is yes we created

[1:08:12] in that PHP however if you are not

[1:08:14] running this file nowhere in our code

[1:08:17] and that's a problem

[1:08:19] because now if it doesn't know that it

[1:08:22] has to run

[1:08:24] Laro will see this

[1:08:26] in environment configuration and it's

[1:08:28] just not gonna known it's gonna throw

[1:08:30] never so now let's do the following

[1:08:32] let's go to our entry point and entry

[1:08:34] point this is a very good place to

[1:08:36] initialize some scripts that you want to

[1:08:38] run before your laravel application

[1:08:40] starts so let's

[1:08:42] call the script PHP

[1:08:46] and location of your init PHP file

[1:08:49] and let's ensure

[1:08:51] and actually in the PHP will be copied

[1:08:54] because the way we are doing it here

[1:08:56] whenever we are copying the files we are

[1:08:58] copying the whole WWE directory this is

[1:09:01] why this file will be copied right there

[1:09:04] all right so now let's make a comment

[1:09:06] right here

[1:09:10] call in PHP

[1:09:20] all right now let's switch to staging

[1:09:23] and let's merge

[1:09:25] Master into the staging

[1:09:30] now let's go back to master

[1:09:39] okay

[1:09:40] so now we should have two Cloud builds

[1:09:44] running so let's give them two more

[1:09:45] minutes and then we'll try again and see

[1:09:47] if it works then

[1:09:49] and by the way uh you see because they

[1:09:52] are crashing this Cloud build is not

[1:09:53] going to stop because it's waiting for

[1:09:55] for them to deploy and become

[1:09:58] like become green become healthy and

[1:10:00] it's not going to happen so in this case

[1:10:02] we can just press cancel usually takes

[1:10:04] 30 seconds to be canceled so give it a

[1:10:07] little bit of time

[1:10:08] don't

[1:10:09] exit this page yet

[1:10:12] so here you go it's canceled

[1:10:16] let's just cancel this one as well

[1:10:22] all right and now let's wait for these

[1:10:25] two

[1:10:27] images to be deployed

[1:10:30] it's not their building let's take a

[1:10:32] look if they are done yet

[1:10:36] he doesn't want to load it's all right

[1:10:41] okay so it's pushing the image it's

[1:10:43] almost done

[1:10:45] see one minute usually at one minute 40

[1:10:47] seconds and deploys so give or take 30

[1:10:50] more seconds

[1:10:52] so let's go to our workloads

[1:11:01] and as you see here it's currently

[1:11:03] deploying the new image okay

[1:11:17] it does the same for the staging okay so

[1:11:19] it seems like it's working there are no

[1:11:21] restarts right here and let me do the

[1:11:25] following let's just go to

[1:11:29] this instance default one

[1:11:35] and now let's go ahead and connect to

[1:11:37] this instance and let's take a look if

[1:11:39] the credentials were initialized

[1:11:41] properly

[1:11:47] such as connected I'm going to the root

[1:11:50] directory

[1:11:52] and I'm getting information of the

[1:11:54] environment file and right here as you

[1:11:57] see everything worked fine the

[1:11:59] application names level production and

[1:12:01] level has app key right here so let's

[1:12:04] take a look if our pod became healthy

[1:12:07] yet

[1:12:11] as you see hasn't killed the seventh one

[1:12:13] so so let's not refresh it yet because

[1:12:15] the result might be 4C

[1:12:20] okay so the most important thing that

[1:12:22] this one is working it's replacing your

[1:12:26] your labels your placeholders

[1:12:30] so now let's

[1:12:33] just wait few more seconds

[1:12:36] okay so the staging is already working

[1:12:38] as you see as you see here it's

[1:12:40] refreshed everything is going through

[1:12:44] and let's wait for the production to

[1:12:46] remove the old instance as you see here

[1:12:48] it has removed

[1:12:49] and whenever you hit refresh it's

[1:12:52] working fine so so this is how you can

[1:12:56] ensure that your level application is

[1:12:58] very safe it's really by putting these

[1:13:01] special names and and hiding your data

[1:13:05] and exposing it and saving it on a

[1:13:07] cluster level level I hope you found

[1:13:10] this lesson very productive because

[1:13:13] security is one of the most important

[1:13:15] things and kubernetes engine cluster

[1:13:18] allows us to be extremely secure because

[1:13:22] you can manage all your credentials and

[1:13:24] you can save them on this cluster

⚡ Saved you 1h 13m reading this? Transcribe any YouTube video for free — no signup needed.