<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Bruno</title>
    <description>The latest articles on Forem by Bruno (@brunoa19).</description>
    <link>https://forem.com/brunoa19</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F599399%2F04b3c5c5-afd1-4d3d-9a19-b9769213053d.png</url>
      <title>Forem: Bruno</title>
      <link>https://forem.com/brunoa19</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/brunoa19"/>
    <language>en</language>
    <item>
      <title>Deploying Remix apps on Kubernetes</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Tue, 23 Aug 2022 17:00:00 +0000</pubDate>
      <link>https://forem.com/brunoa19/deploying-remix-apps-on-kubernetes-2gd1</link>
      <guid>https://forem.com/brunoa19/deploying-remix-apps-on-kubernetes-2gd1</guid>
      <description>&lt;p&gt;Remix, as stated in their website, is a JavaScript full stack web framework that lets you focus on the user interface and web standards to deliver a fast, slick, and resilient user experience. &lt;/p&gt;

&lt;p&gt;As the framework is getting a lot of attention from the community (over 18k stars on Github), I decided to try it out myself for fun, and deploy the end result to Kubernetes using Shipa to demonstrate how easy it would be for those migrating to Remix to deploy their apps to an actual Kubernetes cluster without hassle.&lt;/p&gt;

&lt;p&gt;For those who don’t know what Shipa is or does, it is a tool that simplifies the way you deploy, secure, and manage applications across cloud-native infrastructures. In the same way that Remix abstracts a lot of complex concepts from modern web development (routing,  hydration, cache, server side rendering, etc.), Shipa abstracts all the hard concepts from the Kubernetes world, so you can focus your time and energy into building your actual application rather than learning Kubernetes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basics
&lt;/h2&gt;

&lt;p&gt;Instead of learning about all the objects you need to define to get your app up and running in a K8 cluster (deployments, services, ingress, secrets, helm charts, etc.), the only thing you really need from your app is a Docker image. With that on hand, Shipa will take care of the rest. It will generate all the underlying definitions required to deploy your app, and it will even create a public URL endpoint you can visit to access your running/test application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is that magic? How can I do that?
&lt;/h2&gt;

&lt;p&gt;For the sake of this example, I followed one of Remix’s &lt;a href="https://remix.run/docs/en/v1/tutorials/jokes"&gt;starting tutorials&lt;/a&gt; and created a Docker image for it. &lt;a href="https://github.com/remix-run/remix/tree/main/examples/jokes"&gt;The final code&lt;/a&gt; is actually available in their official repo, even with the right Dockerfile, so all the credit really goes to the Remix team 🙂. With that in my hands, the rest is a piece of cake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.docker.com/get-started/"&gt;Install &lt;code&gt;docker&lt;/code&gt;&lt;/a&gt; on your computer and &lt;a href="https://hub.docker.com/"&gt;create a free account&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow the Remix tutorial and create your own app (the framework it’s really impressive and easy to use, so have some fun there if you have more time!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the Dockerfile available at &lt;a href="https://github.com/remix-run/remix/blob/main/examples/jokes/Dockerfile"&gt;https://github.com/remix-run/remix/blob/main/examples/jokes/Dockerfile&lt;/a&gt; to generate your container image&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;The only change I did for the sake of this example is to actually generate a new empty DB on every build of the image. This is not something you should do when using an actual production DB, but I intentionally did it just to load the file as part of the container for testing purposes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G8D7cK9Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77pow99b857sg9d8zyku.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G8D7cK9Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77pow99b857sg9d8zyku.png" alt="Build the app" width="418" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; I forced an ENV variable with the DATABASE_URL where I intent to store the DB and ran the prisma commands to generate a new empty database from the schemas the code has.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://apps.shipa.cloud/"&gt;Sign up in Shipa Cloud&lt;/a&gt; &lt;strong&gt;(it is free)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a Kubernetes cluster in the provider of your preference (GKE, EKS, AKS, etc.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;You could even use minikube or k3s, but you will need to expose your local cluster to the internet to be able to connect them to Shipa (out of the scope of this quick test)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Now it is your turn:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;With the codebase on your machine, Go to the Terminal and &lt;code&gt;cd&lt;/code&gt; into the folder with the project. In my case &lt;code&gt;cd ~/remix-blog&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build the Docker image locally by running &lt;code&gt;docker build . -t NAME:TAG&lt;/code&gt;. In my case, &lt;code&gt;docker build . -t dechegaray/remix-blog&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;.&lt;/code&gt; provides the context to the command from where to look the Dockerfile. If a different path is needed, just adjust that relative path there &lt;code&gt;docker build ./deploy/Dockerfile -t NAME:TAG&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The  &lt;code&gt;-t&lt;/code&gt; command just gives a tag name to your image, so you can locate it easier.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2-9-fsNN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhx3pjmsmwtazpg65ox0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2-9-fsNN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhx3pjmsmwtazpg65ox0.png" alt="Docker Build" width="624" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The build process is really fast compared to other frameworks I have used in the past, so Kudos to the Remix team for having a keen eye there.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Push the built image to your docker hub by running &lt;code&gt;docker push REPO/IMAGE_NAME:TAG&lt;/code&gt;, making it publicly available. In my case &lt;code&gt;docker push dechegaray/remix-blog&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oAB5abuA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c78nh7h45rptga74sco0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oAB5abuA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c78nh7h45rptga74sco0.png" alt="Docker Push" width="624" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to your &lt;a href="https://apps.shipa.cloud/"&gt;Shipa account using the dashboard&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bJVA1Xto--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qn58br0nh1knqo3edld.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bJVA1Xto--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qn58br0nh1knqo3edld.png" alt="Shipa Cloud" width="611" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connect your cluster to Shipa (&lt;a href="https://learn.shipa.io/docs/connecting-clusters"&gt;instructions here&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hXTm1SD0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wbpyhx00rrje6n4fp9v6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hXTm1SD0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wbpyhx00rrje6n4fp9v6.png" alt="Shipa Cloud" width="624" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an app on Shipa and provide your container image’s URL. In my case, &lt;code&gt;docker.io/dechegaray/remix-blog&lt;/code&gt; (you can use container images from any registry, I am using Docker as an example in this case)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Eyr8Q6AX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqqmlgt7p1axb260b1bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Eyr8Q6AX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqqmlgt7p1axb260b1bg.png" alt="Shipa Cloud" width="624" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J62yBJFf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0ikchzelcjvk2r3gpaf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J62yBJFf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0ikchzelcjvk2r3gpaf.png" alt="Shipa Cloud" width="624" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the required environment variables for this application (if any). If you were using a real database running on an external service (i.e. Mongo Atlas , AWS, Google Cloud, etc), you could just pass the auth information as environment variables here.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qAtzu32L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2cn7tg37zt8yi37knemr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qAtzu32L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2cn7tg37zt8yi37knemr.png" alt="Shipa Cloud" width="624" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;**NOTE: **This application uses a SQLite database to persist jokes and users created by the application. In an actual production setup, this DB should be stored in a separate volume or service; however, just for the sake of the demonstration, I decided to load the DB file into the container running the app, which means that every time the pod of the app is created, the DB will appear as it is initially loaded into the container “empty”.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click “deploy” and wait for Shipa to complete the process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zMfF4nXs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/keiaed4lx051hwiwwmop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zMfF4nXs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/keiaed4lx051hwiwwmop.png" alt="Shipa Cloud" width="624" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;That’s it! Your app should appear as running, and if you click on it, you should see all the information that Shipa prepared for you. Easy, right?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ley5CF9k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npl30cpmh4iswad4aq4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ley5CF9k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/npl30cpmh4iswad4aq4r.png" alt="Shipa Cloud" width="624" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your app is already deployed to your cluster, and you should have enough information to monitor/debug it from Shipa (without the need to use &lt;code&gt;kubectl&lt;/code&gt;). Visit the app’s details and have fun seeing all the details Shipa provides. Some of those details are listed below:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Instantly accessible URL endpoint (click on it to actually see your app running)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iHDzNuyZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0wniq37ab4hhw0iy79a7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iHDzNuyZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0wniq37ab4hhw0iy79a7.png" alt="Shipa Cloud" width="624" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--50olIjfv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ebxdl8ud1h1x2ih13yb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--50olIjfv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ebxdl8ud1h1x2ih13yb.png" alt="Remix App" width="624" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;**Hack: **As you can see, Shipa generates a URL served through &lt;code&gt;http&lt;/code&gt; not &lt;code&gt;https&lt;/code&gt; by default, so because of it, the original code that creates your cookie session on Remix won’t work, as it is requesting only &lt;code&gt;secure&lt;/code&gt; sites on production. To bypass that behavior, you can do 2 things: &lt;/p&gt;

&lt;p&gt;1) Add a CNAME on shipa using &lt;code&gt;https&lt;/code&gt; if you have one available, OR &lt;/p&gt;

&lt;p&gt;2) For testing purposes, disable the secure cookies when creating your session:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LFgARoDv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r5hgrlwk2q1j3bngogo6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LFgARoDv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r5hgrlwk2q1j3bngogo6.png" alt="Code change" width="376" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I did it by adding an extra condition that forces the &lt;code&gt;secure&lt;/code&gt; property to be &lt;code&gt;false&lt;/code&gt; if intended. Then, I added the environment variable to my app on Shipa to make the condition truthy, and that’s it. My app is now fully ready to accept sessions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cGzOcbXS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aawfc10tsx4dxx7dw3hp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cGzOcbXS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aawfc10tsx4dxx7dw3hp.png" alt="Remix App" width="624" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resource and Transaction metrics!!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ossX5k1h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ucbkht10xyb7q9f75k0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ossX5k1h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ucbkht10xyb7q9f75k0.png" alt="Shipa Cloud" width="624" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logs directly from Kubernetes (say what???). Start using your app and see how logs start appearing there.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HoTxCEdq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f87krom6hlskx3z73ztk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HoTxCEdq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f87krom6hlskx3z73ztk.png" alt="Shipa Cloud" width="624" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Even a timeline with the history of your app (if you redeploy your image with new changes, you will see them there as well).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nuj8kDUO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ws1pakc93mw5x8jfcqk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nuj8kDUO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ws1pakc93mw5x8jfcqk.png" alt="Shipa Cloud" width="624" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a LOT more to see there, so feel free to explore your app and see all the info Shipa has captured for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CUAaQb8F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzqzxbr7f8300ayl798v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CUAaQb8F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzqzxbr7f8300ayl798v.png" alt="Shipa Cloud" width="515" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simple, right? Your first Remix application actually deployed to a Kubernetes cluster without any hassle. And you didn’t have to learn anything about Kubernetes (maybe just figuring out how to create a cluster, but other than that, everything seems pretty simple)&lt;/p&gt;

&lt;p&gt;You might wonder, “Yep, this is cool, but how do I integrate this into my development flow?”. Well, it is really up to you and your development processes, but we have done a lot of work to support the most common CIs out there, so you could create a Github action that builds your Docker image (as you are probably already doing), and then use &lt;a href="https://learn.shipa.io/docs/github-action"&gt;Shipa’s Github Action provider&lt;/a&gt; or &lt;a href="https://learn.shipa.io/docs/downloading-the-shipa-client"&gt;Shipa’s CLI&lt;/a&gt; to deploy it to your cluster.&lt;/p&gt;

&lt;p&gt;Just so you can picture it better, imagine having your Docker image ready in your registry of preference and just doing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;// Install shipa CLI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl -s https://storage.googleapis.com/shipa-client/install.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;// Adding shipa API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shipa target add shipa-cloud https://target.shipa.cloud -s&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;// Signing into your account&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shipa login ${{ secrets.SHIPA_USERNAME }} ${{ secrets.SHIPA_PASSWORD }}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;//Deploying your app&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shipa app deploy -a ${{APP_NAME}} -i ${{APP_IMAGE}} -k framework&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And that’s it. Every new version of your image will be deployed to a specified cluster (&lt;code&gt;staging&lt;/code&gt; or &lt;code&gt;prod&lt;/code&gt;), so you can already imagine the endless possibilities there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://shipa.io/blog/"&gt;Check our blog&lt;/a&gt; for more examples of running Shipa from a CI &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If you have the time and haven’t done it yet, take a look at Remix, it is definitely an interesting JavaScript framework that’s worth checking out, as I believe it is there to improve our lives as developers and create pretty interesting users experiences. AND you already know how to deploy it to Kubernetes 🙂&lt;/p&gt;

&lt;p&gt;Similarly, if you are struggling with Kubernetes, or want to have a solid developer platform that simplifies a lot of hard concepts and scales properly, take a look at Shipa. We are confident that once you try it out, you will be able to focus more on actually building your application rather than adapting to all the numerous changes of the cloud industry.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>docker</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Rolling out a 3-tier app as SaaS</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Wed, 15 Jun 2022 15:48:35 +0000</pubDate>
      <link>https://forem.com/brunoa19/rolling-out-a-3-tier-app-on-kubernetes-27lf</link>
      <guid>https://forem.com/brunoa19/rolling-out-a-3-tier-app-on-kubernetes-27lf</guid>
      <description>&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;I wanted to launch an application and offer it as SaaS&lt;/li&gt;
&lt;li&gt;I chose Kubernetes for its scalability, but I didn’t want to deal with its complexities&lt;/li&gt;
&lt;li&gt;My goal was to launch my service as fast as possible and operationalize it easily without letting infrastructure related complexities get in the way.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Background
&lt;/h1&gt;

&lt;p&gt;I love what we are working on here at Shipa, and I couldn't be more proud of all the great things the team is constantly delivering, but one thing I like is having personal projects. These help me keep up to date with technology and learn new things.&lt;/p&gt;

&lt;p&gt;I try to keep the investment in those projects at a minimum and under control. That goes across both the timing and the resources invested.&lt;/p&gt;

&lt;p&gt;My most recent project is related to the experience when defining cloud-native applications. I see so many DevOps teams spending time having to create and manage templates for developers to deploy their applications. In my opinion, this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates toil for the DevOps team.&lt;/li&gt;
&lt;li&gt;Slows down the onboarding of new applications.&lt;/li&gt;
&lt;li&gt;Shift left won’t effectively happen because creating infrastructure-level definitions is often complex for developers and diverts time from where they add value.&lt;/li&gt;
&lt;li&gt;Too many duplicated charts because there is no practical way to share application definitions with other teammates or teams.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The list goes on, so I decided to put together a product that people could use to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build their application definition without dealing with any underlying Kubernetes complexity&lt;/li&gt;
&lt;li&gt;Save it and share it with their teammates or publicly&lt;/li&gt;
&lt;li&gt;Export that application design to be used with different IaC tools or pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Application Architecture
&lt;/h1&gt;

&lt;p&gt;The application is initially simple, and I have broken it down into different components:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7zXZGkJh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/smppe5128gr56bpunism.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7zXZGkJh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/smppe5128gr56bpunism.png" alt="Application Architecture" width="880" height="789"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; A React application with a drag and drop interface. The interface allows users to define applications and policies using a drag and drop experience. In addition, users can save, share, and search for saved definitions in a global repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; A Golang service exposed through an API. Calls are received from the frontend service and, based on the payload, generate the application or policy definition based on the provider selected. The Backend service also manages the saving and sharing of definitions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; I chose MongoDB to store and serve the necessary data because I wanted to learn MongoDB (one of the advantages of personal projects!)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auth:&lt;/strong&gt; I’m using Shipa to serve the authentication. As long as users have a Shipa account, they can log in to save and share their definitions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Hosting My Application
&lt;/h1&gt;

&lt;p&gt;I wanted a scalable infrastructure to host my application and its different services, so I chose Google Kubernetes Engine (GKE).&lt;/p&gt;

&lt;p&gt;While spinning up a GKE cluster is effortless, deploying multiple services, exposing them to external users, securing them, and monitoring them can be daunting. As mentioned before, I aim to launch as quickly as possible and spend the least amount of time dealing with infrastructure.&lt;/p&gt;

&lt;p&gt;I will also need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure network policies so my backend API only accepts requests from the frontend service&lt;/li&gt;
&lt;li&gt;Set up monitoring, so I can quickly identify potential issues and security violations&lt;/li&gt;
&lt;li&gt;Integrate activities and events into Slack, so I can know quickly if something happens.&lt;/li&gt;
&lt;li&gt;Set up dev and a production environment, so people see less of the bugs I introduce :) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---7FbZW9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qqu6zbes988rt3f42nt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---7FbZW9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qqu6zbes988rt3f42nt.png" alt="Infrastructure" width="880" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setting up all the above directly with Kubernetes would be time-consuming because I would be dealing with ingress controllers, deployment definitions, setting up Prometheus, exposing services, complex network policies using Calico, certificate generation, and more.&lt;/p&gt;

&lt;p&gt;I would be spending time on infrastructure rather than on my application, releasing it, getting feedback, pushing fixes, and monitoring utilization. That’s less than ideal.&lt;/p&gt;

&lt;p&gt;To remove that, I decided to use Shipa to host my application, which means I’m my own customer!&lt;/p&gt;

&lt;h1&gt;
  
  
  Deploying My Application
&lt;/h1&gt;

&lt;h2&gt;
  
  
  GKE Cluster
&lt;/h2&gt;

&lt;p&gt;I already have a Google Cloud account and gcloud configured on my terminal, so creating a cluster is straightforward. Here is a sample command you can use:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gcloud beta container --project "project-name" clusters create "appcluster" --zone "us-west1-a" --no-enable-basic-auth --cluster-version "1.22.8-gke.201" --release-channel "regular" --machine-type "e2-standard-2" --image-type "COS_CONTAINERD" --disk-type "pd-standard" --disk-size "100" --metadata disable-legacy-endpoints=true --scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" --max-pods-per-node "110" --num-nodes "3" --logging=SYSTEM,WORKLOAD --monitoring=SYSTEM --enable-ip-alias --network "projects/project-name/global/networks/default" --subnetwork "projects/project-name/regions/us-east1/subnetworks/default" --no-enable-intra-node-visibility --default-max-pods-per-node "110" --enable-network-policy --no-enable-master-authorized-networks --addons HorizontalPodAutoscaling,HttpLoadBalancing,GcePersistentDiskCsiDriver --enable-autoupgrade --enable-autorepair --max-surge-upgrade 1 --max-unavailable-upgrade 0 --enable-shielded-nodes --node-locations "us-west1-a"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command above will create a cluster with 3 nodes with 2 vCPU and 8GB of memory each. The command also enables network policy for the cluster.&lt;/p&gt;

&lt;p&gt;If you copy the code above, make sure you change it to use your project name.&lt;/p&gt;

&lt;p&gt;Once the cluster is running, you can use the command below to configure kubectl:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gcloud container clusters get-credentials cluster-name --zone us-west1-a --project project-name&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting Shipa
&lt;/h2&gt;

&lt;p&gt;With my cluster running and my Kubectl configured. It’s now time to connect it to Shipa.&lt;/p&gt;

&lt;p&gt;I already have my Shipa Cloud account, but if you don't have one yet, you can sign up for free here.&lt;/p&gt;

&lt;p&gt;Because I used Shipa as my application management platform, I don't need to worry about installing ingress, Prometheus, RBAC, and more. Once you connect Shipa to the cluster, those will be taken care of automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating my framework
&lt;/h3&gt;

&lt;p&gt;Shipa uses the concept of Policy Frameworks to connect to your cluster, so head over to &lt;a href="https://apps.shipa.cloud/frameworks"&gt;Frameworks&lt;/a&gt; to create the first one and click on Create.&lt;/p&gt;

&lt;p&gt;To keep the initial setup simple, keep the default setting of “Deploy applications with reasonable defaults” and click Next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qvbvqm0p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c4i7bykuuwld15c8pvo7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qvbvqm0p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c4i7bykuuwld15c8pvo7.png" alt="Creating a Framework" width="752" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the framework name, select the available Plan, and the pre-created team shipa-team. Click on Create&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6pgHOVLf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urur8ayczivoqhwc8rjj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6pgHOVLf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urur8ayczivoqhwc8rjj.png" alt="Creating Framework" width="751" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can customize these settings by creating a new resource limit plan or adding more teams and users to your account. I’m the only one managing this project, so the default options work for me.&lt;/p&gt;

&lt;p&gt;Shipa automatically creates a namespace for each framework you connect to a cluster, so when I deploy my application, Shipa will use the namespace based on the policy framework I select.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting to my cluster
&lt;/h3&gt;

&lt;p&gt;With your framework created, click on &lt;a href="https://apps.shipa.cloud/clusters"&gt;Clusters&lt;/a&gt; and then Create.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_AQOL-T4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l61ffh6xbhqe569s4dmx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_AQOL-T4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l61ffh6xbhqe569s4dmx.png" alt="Connecting a Cluster" width="456" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here I selected the frameworks I created and entered my Kubernetes control plane address. Click on Generate Command&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UxwYEycV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d3bjyvtf7lmno7sgiiey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UxwYEycV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d3bjyvtf7lmno7sgiiey.png" alt="Connecting a Cluster" width="458" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shipa generated a kubectl command. Once I ran it on my terminal, Shipa installed an agent in my cluster, created the namespace for each framework, and started showing up on my Shipa dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying MongoDB
&lt;/h3&gt;

&lt;p&gt;Connecting my cluster to Shipa only took me a couple of minutes and saved me an enormous amount of time because I didn't need to deal with ingress install, config, Prometheus, RBAC, and more.&lt;/p&gt;

&lt;p&gt;I click on &lt;a href="https://apps.shipa.cloud/applications/apps"&gt;Applications&lt;/a&gt; and then Create to deploy the first service.&lt;/p&gt;

&lt;p&gt;I deployed my MongoDB service first, and it was pretty easy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RfA52tHZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqor1tyytl30d0f70t70.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RfA52tHZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqor1tyytl30d0f70t70.png" alt="Deploying MongoDB" width="755" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I entered the application name, the MongoDB image URL (mongo:latest), and picked the framework I wanted to use to deploy my application. There were more options I could use, such as binding a volume to it, but I wanted to keep things simple and release fast.&lt;/p&gt;

&lt;p&gt;The deployment only took a few seconds, and I got some great info immediately, such as logs and the Internal DNS my other services can use to communicate with MongoDB, all without having to kubectl my way to configure things.&lt;/p&gt;

&lt;p&gt;I also got the complete Metadata of my MongoDB application, some initial monitoring information, and the dependency map of my deployment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--moIDZPc3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/koaorxlar286g7cxe6mi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--moIDZPc3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/koaorxlar286g7cxe6mi.png" alt="MongoDB App Management" width="880" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MYhjbcB3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tiixdv1406wkarjofoyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MYhjbcB3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tiixdv1406wkarjofoyn.png" alt="MongoDB App Management" width="880" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying the Backend
&lt;/h3&gt;

&lt;p&gt;I clicked again on &lt;a href="https://apps.shipa.cloud/applications/apps"&gt;Applications&lt;/a&gt; and Create.&lt;/p&gt;

&lt;p&gt;Once again, I entered my application name (backend), the image URL, and picked a framework. Now, I need to enter an environment variable so my backend application can connect to my MongoDB service.&lt;/p&gt;

&lt;p&gt;I had to select the “Set environment variables” option in the deployment screen and hit Next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9WEn7kFG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zdcy977fwyy6kau0ck75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9WEn7kFG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zdcy977fwyy6kau0ck75.png" alt="Backend Deployment" width="748" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I created 2 env variables and entered the values for each. Once done, I clicked on Deploy&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5WAKFGUl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xbsitttdwdbotshqjn0j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5WAKFGUl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xbsitttdwdbotshqjn0j.png" alt="Backend Deployment" width="754" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One point to notice is that because Shipa gives me the MongoDB service Internal DNS, it was just a couple of clicks to copy the address and paste it here as a value for one of my variables!&lt;/p&gt;

&lt;p&gt;In the same way as before, I get all the necessary information about my application.&lt;/p&gt;

&lt;p&gt;So lets now head to the last service&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying the Frontend
&lt;/h3&gt;

&lt;p&gt;I clicked on Applications and followed the same process as the steps before for my frontend application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mcT118DW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8a4epz48zwys9fu51mse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mcT118DW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8a4epz48zwys9fu51mse.png" alt="Frontend Deployment" width="752" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Exposing My Application
&lt;/h1&gt;

&lt;p&gt;Even though Shipa creates an external URL you can give to users to access your application, that was not what I had in mind to provide my users with.&lt;/p&gt;

&lt;p&gt;I then created a Domain using Google called defineyour.app and added a CNAME for my application called &lt;a href="//you.defineyour.app"&gt;you.defineyour.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connecting this to my frontend application was easy. In the &lt;a href="https://apps.shipa.cloud/applications/apps"&gt;Applications&lt;/a&gt; page, I clicked on my frontend service, Configure, and CNAME.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iyQjtwNc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ocxw1qkm5e7jsgdyzkvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iyQjtwNc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ocxw1qkm5e7jsgdyzkvx.png" alt="Adding a CNAME" width="601" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All I had to do was select HTTPS and enter the CNAME I created on Google Domains. Shipa automatically generated the certificate and added that endpoint to my frontend service.&lt;/p&gt;

&lt;p&gt;In just a few minutes, the CNAME was propagated, and I could access my application through that CNAME. All without dealing with cert-manager, certificate generation, and more, which is usually a pain.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting Up Alerts
&lt;/h1&gt;

&lt;p&gt;I wanted to quickly set up alerts for my services so if anything goes wrong, I can act fast.&lt;/p&gt;

&lt;p&gt;I could create an alert by clicking on the service name and selecting the Integrations tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1gor9fbA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bei3egnge73w2zggh312.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1gor9fbA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bei3egnge73w2zggh312.png" alt="Setting up alerts" width="715" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eWZ7idiu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o2sojh73059nsq4k44ga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eWZ7idiu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o2sojh73059nsq4k44ga.png" alt="Setting up alerts" width="717" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I selected Slack as a provider, but if whatever you use is not on the Provider list, you can use Shipa’s CLI to create a webhook for your incident tool. Here is an excellent example of how to &lt;a href="https://shipa.io/development/first-shipa-webhook/"&gt;create a webhook to Microsoft Teams&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Releasing my Service
&lt;/h1&gt;

&lt;p&gt;Now that I have all my services running, the frontend is accessible through a custom CNAME, and I have my alerts in place, it was time to give people the address of my app so that they could give it a try.&lt;/p&gt;

&lt;p&gt;As people access my services, I can see the app's performance, logs, history, and more. Again, all without dealing with Kubernetes complexity and focusing all the time I have on my applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KVWc5YFz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d532o9w70wus8rygg3n1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KVWc5YFz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d532o9w70wus8rygg3n1.png" alt="Application Management" width="880" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Moving Forward
&lt;/h1&gt;

&lt;p&gt;The next step for me now is to set the &lt;a href="https://shipa.io/development/untangling-network-policies-on-k8s/"&gt;Network Policies&lt;/a&gt;, which I can do through Shipa, and integrate this into a pipeline, which I will probably use &lt;a href="https://shipa.io/development/a-developer-focused-ci-cd-pipeline-for-kubernetes/"&gt;GitHub Actions&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I went from having a few container images to launching a complete service as SaaS in just a few minutes without dealing with underlying infrastructure complexities. It was amazing to see how far Shipa has come as a product and how awesome of a product the team is delivering.&lt;/p&gt;

&lt;p&gt;As we enter a weird period in the market and companies focus on doing more with less, enabling application teams to deliver faster, manage applications better, and keep those applications secure without complexities will make you an essential resource in your organization and being my own customer, has proven to me again that this is a much easier and better way to do it.&lt;/p&gt;

</description>
      <category>node</category>
      <category>reactnative</category>
      <category>go</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Deploying WordPress on Kubernetes</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Mon, 13 Jun 2022 21:00:17 +0000</pubDate>
      <link>https://forem.com/brunoa19/deploying-wordpress-on-kubernetes-18ao</link>
      <guid>https://forem.com/brunoa19/deploying-wordpress-on-kubernetes-18ao</guid>
      <description>&lt;p&gt;Onboarding applications on Kubernetes can be complex. &lt;/p&gt;

&lt;p&gt;Understanding how deployment sets work, volumes, env variables, services, and networking works on Kubernetes can often take away the time from developers and impact application delivery.&lt;/p&gt;

&lt;p&gt;Also, sharing application definitions with other teams can help speed up onboarding of new applications, new developers, and more.&lt;/p&gt;

&lt;p&gt;Because of that, I started a personal project to help developers onboard their applications on Kubernetes, share those definitions with their teams, and publicly if desired.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gg85RUV6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5koof70bg7kv1r8uqjjo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gg85RUV6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5koof70bg7kv1r8uqjjo.png" alt="Searching saved app definitions" width="880" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tyWx4XwI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ve52rxezjqyticojwgt6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tyWx4XwI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ve52rxezjqyticojwgt6.png" alt="Exporting app definitions for a provider" width="880" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m building the project on top of shipa.io APIs. The purpose is to give developers a way to go from application definition to management without dealing with the underlying Kubernetes complexity. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---qTn0IGK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3s0kas38o2i0g5qty1to.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---qTn0IGK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3s0kas38o2i0g5qty1to.png" alt="App management with Shipa" width="880" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m just starting with this (I don’t even have a name for it yet), and bugs will be found :) but I wanted to get it out there early, get feedback, and see what could be added to help solve a big problem for different teams.&lt;/p&gt;

&lt;p&gt;You can find the application available here: &lt;a href="https://you.defineyour.app/search"&gt;https://you.defineyour.app/search&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please, give it a try, share some feedback, and share it with your teammates!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>wordpress</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Application deployment design</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Mon, 16 May 2022 23:48:47 +0000</pubDate>
      <link>https://forem.com/brunoa19/application-deployment-design-353</link>
      <guid>https://forem.com/brunoa19/application-deployment-design-353</guid>
      <description>&lt;p&gt;Hey folks&lt;/p&gt;

&lt;p&gt;I have heard many times that deploying applications on Kubernetes can be a complex task for developers because it involves a lot of infrastructure related knowledge.&lt;/p&gt;

&lt;p&gt;Because of that, I started building this side project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=eV1KIBlFjQk"&gt;Project Demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would you use something like this in your team?&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>microservices</category>
      <category>docker</category>
    </item>
    <item>
      <title>From 0 to Hero on Kubernetes with Nana Janashia</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Wed, 04 May 2022 00:49:54 +0000</pubDate>
      <link>https://forem.com/brunoa19/from-0-to-hero-on-kubernetes-with-nana-janashia-pe9</link>
      <guid>https://forem.com/brunoa19/from-0-to-hero-on-kubernetes-with-nana-janashia-pe9</guid>
      <description>&lt;p&gt;Join Nana Janashia and Bruno Andrade on &lt;strong&gt;May 11th at 10 AM PT / 1 PM ET&lt;/strong&gt; as they discuss how you can go from 0 to Production-ready clusters without all the Kubernetes and infrastructure-related complexity&lt;/p&gt;

&lt;p&gt;Sign up is free and available here: &lt;a href="https://devrel.shipa.io/application-ready-with-nana"&gt;https://devrel.shipa.io/application-ready-with-nana&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Developer led Kubernetes experience</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Wed, 04 May 2022 00:43:42 +0000</pubDate>
      <link>https://forem.com/brunoa19/developer-led-kubernetes-experience-no-devops-experience-needed-319m</link>
      <guid>https://forem.com/brunoa19/developer-led-kubernetes-experience-no-devops-experience-needed-319m</guid>
      <description>&lt;p&gt;It’s no secret that Kubernetes is complex, and hence, many organizations rely heavily on building a DevOps team to implement and manage it.&lt;/p&gt;

&lt;p&gt;While Kubernetes enables you to build a scalable infrastructure where you can run your applications at scale, it introduces a dependency on the DevOps team, poor developer experience, and an increase in costs. &lt;/p&gt;

&lt;p&gt;These are points that many development-led teams don’t want to deal with, especially in organizations where delivering your application is the top priority, you need a developer self-service model, and you want to make sure both complexity and costs are under control.&lt;/p&gt;

&lt;p&gt;You can do that today by implementing an Internal Developer Platform. We will use Shipa as the Developer Platform, and you can create a free account here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://apps.shipa.cloud"&gt;A Shipa Cloud account&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Kubernetes cluster&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;You can get started by creating a Framework. This is how Shipa will connect to your cluster and allow you to deploy applications without all the complexity Kubernetes introduces.&lt;/p&gt;

&lt;p&gt;Create a Framework by clicking on the &lt;strong&gt;Frameworks&lt;/strong&gt; option on your left menu, then click on &lt;strong&gt;Create&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G63BI0po--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kyud2hiorhh6xrbbuoeu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G63BI0po--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kyud2hiorhh6xrbbuoeu.png" alt="Creating a Framework" width="758" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although you can use Frameworks to enforce policies, we will keep things simple for this example. Choose the &lt;strong&gt;Deploy applications with reasonable defaults&lt;/strong&gt; option and click on &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can later create multiple frameworks to help you isolate applications, which is excellent if you plan to build a multi-tenant environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Enter the Framework name and the resource limit plan (you can use the pre-created &lt;em&gt;shipa-plan&lt;/em&gt;), and choose the default team (&lt;em&gt;shipa-team&lt;/em&gt;). Click on &lt;strong&gt;Create&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jepLP4rN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ppcukhr4hsz715m0o99a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jepLP4rN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ppcukhr4hsz715m0o99a.png" alt="Creating a Framework" width="759" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With your Framework created, connect it to your Kubernetes cluster. &lt;/p&gt;

&lt;p&gt;Click on the &lt;strong&gt;Clusters&lt;/strong&gt; menu option and then on &lt;strong&gt;Create&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Tstu6pBO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j7332a01izn1vio9n4d6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Tstu6pBO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j7332a01izn1vio9n4d6.png" alt="Connecting to a Cluster" width="459" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the Framework (or Frameworks) you created and enter your Kubernetes API endpoint, which you can get by running the following command from your terminal (assuming you are connected to your cluster):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl cluster-info | grep 'Kubernetes' | awk '/http/ {print $NF}'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That’s it! You have a developer platform connected to your Kubernetes cluster without dealing with any Kubernetes complexity. Let’s deploy an application. Click on the &lt;strong&gt;Applications&lt;/strong&gt; menu option and then on &lt;strong&gt;Add Application&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CR_iCLjO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sy4sqwyz1lzhbu3ss7jk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CR_iCLjO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sy4sqwyz1lzhbu3ss7jk.png" alt="Deploying an Application" width="880" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can quickly test the application process and experience by entering an application name and selecting the default team and framework you just created.&lt;/p&gt;

&lt;p&gt;You can use a sample image for the application image by clicking on the &lt;em&gt;TEST WITH SAMPLE IMAGE&lt;/em&gt; button.&lt;/p&gt;

&lt;p&gt;Clicking on &lt;strong&gt;Deploy&lt;/strong&gt; will get the deployment process started, and, in a few seconds, you will see your application available and running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dvpZBemC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/txhac7mx7h29hh56bba2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dvpZBemC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/txhac7mx7h29hh56bba2.png" alt="Application Dashboard" width="880" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By clicking on the application name, Shipa will give you complete information about your application, status, metrics, history, and more:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uMDmIN4---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e0khxdl9oe9j16c3nod8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uMDmIN4---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e0khxdl9oe9j16c3nod8.png" alt="Application Dashboard" width="880" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shipa automatically creates a URL endpoint you can use to access your application.&lt;/p&gt;

&lt;p&gt;That’s it. In just a few minutes, you can connect to any Kubernetes cluster and start deploying and managing applications without dependency on a large and specialized Kubernetes team!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Free session on JavaScript apps on Kubernetes</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Wed, 23 Mar 2022 19:13:36 +0000</pubDate>
      <link>https://forem.com/brunoa19/free-session-on-javascript-apps-on-kubernetes-5bmd</link>
      <guid>https://forem.com/brunoa19/free-session-on-javascript-apps-on-kubernetes-5bmd</guid>
      <description>&lt;p&gt;Hey folks&lt;/p&gt;

&lt;p&gt;On &lt;strong&gt;March 24 at 10 AM PT / 1 PM ET&lt;/strong&gt; we will have a free tech session to show how you can &lt;strong&gt;easily deploy and manage your JavaScript apps on Kubernetes&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The following topics will be covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Building a developer-friend pipeline to deploy your JavaScript application&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monitoring, managing, and alerting for your applications&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manage access and communication to your application and in-between services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Breakthrough the dependency on the DevOps team to manage your apps through a self-service model.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://devrel.shipa.io/kubernetes-for-javascript-developers"&gt;You can sign up here:&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>kubernetes</category>
      <category>docker</category>
      <category>java</category>
    </item>
    <item>
      <title>A Developer focused CI/CD pipeline for Kubernetes</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Tue, 30 Nov 2021 01:54:38 +0000</pubDate>
      <link>https://forem.com/brunoa19/a-developer-focused-cicd-pipeline-for-kubernetes-5h9f</link>
      <guid>https://forem.com/brunoa19/a-developer-focused-cicd-pipeline-for-kubernetes-5h9f</guid>
      <description>&lt;p&gt;As Kubernetes becomes the key target environment across many organizations, it automatically becomes an essential topic for developers.&lt;/p&gt;

&lt;p&gt;However, Kubernetes was created for operations and, unless you spend a considerable amount of time learning and specializing yourself, it is still challenging to use. Developers should rather focus on delivering applications instead, and a developer or application-focused platform is needed to enable that.&lt;/p&gt;

&lt;p&gt;This quick tutorial will teach you how to set up a developer-focused pipeline you can use to deploy and manage your applications on Kubernetes without dealing with the underlying infrastructure-related complexities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For this tutorial, you will need:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A GitHub repository (&lt;a href="https://github.com/brunoa19/estabilis-gha"&gt;you can fork this example repo&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Shipa Cloud account (&lt;a href="https://apps.shipa.cloud/auth/login"&gt;you can sign up for free here&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Kubernetes cluster (&lt;a href="https://learn.shipa.io/docs/installation-requirements#kubernetes-clusters"&gt;You can see the list of supported cluster providers here&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GitHub Actions
&lt;/h3&gt;

&lt;p&gt;GitHub Actions is an event-driven automation platform that allows you to run a series of commands after a specified event has occurred. For example, when a commit is made to your staging branch, you want to build, test, and deploy the changes to your staging environment. With Actions, you can automate tasks within your development lifecycle, all within GitHub.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shipa
&lt;/h3&gt;

&lt;p&gt;Shipa is an application platform that enables developers to deploy and manage cloud-native applications. It has a free tier. Developers from small to large enterprises use Shipa today to manage their cloud-native application lifecycle and is quickly becoming the application platform of choice for Kubernetes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kubernetes
&lt;/h3&gt;

&lt;p&gt;Kubernetes is an open-source container-orchestration system for automating computer application deployment, scaling, and management. It was originally designed by Google and is now maintained by the Cloud Native Computing Foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting Shipa to your cluster
&lt;/h2&gt;

&lt;p&gt;We will use Shipa as our application platform. You can create a free account on Shipa here.&lt;/p&gt;

&lt;p&gt;Once you sign up, you can connect Shipa to your Kubernetes cluster. Shipa uses a policy framework to connect to different clusters.&lt;/p&gt;

&lt;p&gt;These policies can be as detailed as we want and cover topics such as ingress, networking, container registry control, and more. For our example, we will keep it to a minimum.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Policy Framework
&lt;/h3&gt;

&lt;p&gt;Once you log into your Shipa Cloud dashboard, go to Frameworks and click on “Create Framework”. This will open up a modal where you can create your first policy:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AFdr6qvt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwj7c7tihq6iwly771gt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AFdr6qvt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uwj7c7tihq6iwly771gt.png" alt="Policy Framework" width="756" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep the selection on “Basic” and click on Next.&lt;/p&gt;

&lt;p&gt;Here, just enter the name you want to give this policy framework. For Plan, you can select the pre-created “shipa-plan” option.&lt;/p&gt;

&lt;p&gt;You can also select the pre-created and available Team “shipa-team”. Click on Create&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NIVHvthj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a35rwdx7y61znbjcorys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NIVHvthj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a35rwdx7y61znbjcorys.png" alt="Policy Framework" width="753" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting the policy framework to your cluster
&lt;/h3&gt;

&lt;p&gt;Now, click on Clusters, and then “Add Cluster”. This will open up a new modal.&lt;/p&gt;

&lt;p&gt;Here, you just need to enter the cluster name and select the framework you created in the previous step:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PgMHmngG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8olllxt0ss39q10t5m1e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PgMHmngG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8olllxt0ss39q10t5m1e.png" alt="Cluster Connection" width="717" height="651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking on “Next” will prompt you to enter your cluster information, so Shipa can connect to it and bind the policy to your cluster.&lt;/p&gt;

&lt;p&gt;For Shipa to connect to your cluster, you will need to enter:&lt;br&gt;
The Cluster IP&lt;br&gt;
A service account token. You should use one created specifically for Shipa&lt;br&gt;
The CA Certificate Shipa should use to connect to your cluster &lt;/p&gt;

&lt;p&gt;You can get the information above by following the documentation available here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/brunoa19/25505efd56d46472b092adaf83fe56dd"&gt;Another (quicker) option is to copy and run this script&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The script above will create the required service account and display both the token and the CA certificate you can copy and paste into the modal.&lt;/p&gt;

&lt;p&gt;You don’t need to enter any information on step 3 of the “Add Cluster” modal. Shipa will automatically install and configure an ingress controller in your cluster for you.&lt;/p&gt;

&lt;p&gt;Click on “Create”&lt;/p&gt;

&lt;p&gt;The cluster connection process will take approximately 60 seconds to complete. Once complete, you will see your cluster available on the Shipa dashboard.&lt;/p&gt;
&lt;h2&gt;
  
  
  GitHub Actions
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Configuring Secrets
&lt;/h3&gt;

&lt;p&gt;For GitHub Actions to leverage Shipa to deploy your applications to Kubernetes, you will need to enter 2 GitHub Secrets. To create a secret, just click on the “Settings” menu in your GitHub repository and then “Secrets” on the left menu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2VOef1e3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rhisg6rbg9mzxycio0rg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2VOef1e3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rhisg6rbg9mzxycio0rg.png" alt="GitHub Secrets" width="880" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will need to create 2 secrets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SHIPA_HOST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SHIPA_TOKEN&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For &lt;strong&gt;SHIPA_HOST&lt;/strong&gt;, you can enter: &lt;a href="https://target.shipa.cloud:8081"&gt;https://target.shipa.cloud:8081&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;SHIPA_TOKEN&lt;/strong&gt;, you need to use the Shipa CLI to find your token. You can install the Shipa CLI by running the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl -s https://storage.googleapis.com/shipa-client/install-cloud-cli.sh | bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With the Shipa CLI installed, you should add your Shipa target and log in. You can do it by using the following commands:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding target:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;shipa target add cloud-production target.shipa.cloud -s&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Logging in:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;shipa login&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Display token:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;shipa token show&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Defining the Application
&lt;/h3&gt;

&lt;p&gt;With your GitHub Secrets defined, we can then define a sample application to test the deployment.&lt;/p&gt;

&lt;p&gt;If you forked the sample repository, you can see the following sample application definition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app:
  name: app1
  teamowner: shipa-team
  framework: estabilis-dev

app-env:
  app: app1
  envs:
    - name: CR_ENV1
      value: test-1
    - name: CR_ENV3
      value: test-3
  norestart: true
  private: false

network-policy:
  app: app1
  ingress:
    policy_mode: allow-all
  egress:
    policy_mode: allow-all
  restart_app: false

app-deploy:
  app: app1
  image: ghcr.io/stefanprodan/podinfo:6.0.3
  port: 9898
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Deploy an application named &lt;strong&gt;app1&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assign it to &lt;strong&gt;shipa-team&lt;/strong&gt; as the owner of the application&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the policy framework to enforce controls. &lt;em&gt;Make sure you change this field to reflect the policy framework you created on the steps before. Otherwise, your deployment will fail.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Will create a couple of sample environment variables&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A sample network policy will be created&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A sample application called Podinfo will be deployed and exposed on port 9898&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see from the code above, this does not require you to deal with infrastructure deployment definitions on Kubernetes, ingress controller configuration, and more. This is, rather, a very application-level definition.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the Action
&lt;/h3&gt;

&lt;p&gt;Once the application definition is in your repository, you can create an Action.&lt;/p&gt;

&lt;p&gt;Click on “Actions” then on “set up a workflow yourself”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EPbu0zGw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9gbschzmkkglz8iy6cre.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EPbu0zGw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9gbschzmkkglz8iy6cre.png" alt="GitHub Actions" width="880" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shipa has a &lt;a href="https://github.com/marketplace/actions/shipa-cloud"&gt;published GitHub Action&lt;/a&gt; that you can leverage to deploy your application. You can copy the file below into your Action definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on: [ push ]

jobs:
  deploy_dev:
    runs-on: ubuntu-latest
    name: Deploy Dev Applications
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Deploy Dev Application
        uses: shipa-corp/shipa-gh-action@0.0.1
        env:
          SHIPA_TOKEN: ${{ secrets.SHIPA_TOKEN }}
          SHIPA_HOST: ${{ secrets.SHIPA_HOST }}
        with:
          shipa-action: './dev-app/dev-app.yml'

  deploy_prod:
    runs-on: ubuntu-latest
    name: Deploy Production Apps
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Deploy Prod Application
        uses: shipa-corp/shipa-gh-action@0.0.1
        env:
          SHIPA_TOKEN: ${{ secrets.SHIPA_TOKEN }}
          SHIPA_HOST: ${{ secrets.SHIPA_HOST }}
        with:
          shipa-action: './prod-app/prod-app1.yml'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This definition will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Check out the application definition&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connect to your Shipa Cloud account using the Host and Token secrets defined before&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploy your application&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you save the file, GitHub will start the action and perform the deployment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--czJMZnxC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qbdjt4dx26euwcfxekkx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--czJMZnxC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qbdjt4dx26euwcfxekkx.png" alt="GitHub Actions" width="880" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Application Dashboard
&lt;/h2&gt;

&lt;p&gt;One of the common issues developers face when deploying on Kubernetes is understanding and managing their applications. Since applications on Kubernetes are a group of independent object definitions in the cluster unless you spend a considerable amount of time learning about each object and how to support it, it becomes complex to manage applications post-deployment,. and as a result, you start depending on the DevOps team to help you support your applications.&lt;/p&gt;

&lt;p&gt;Shipa will also help you here.&lt;/p&gt;

&lt;p&gt;Once the deployment is complete, head back to your Shipa dashboard and click on “Applications”.&lt;/p&gt;

&lt;p&gt;Here you will see your application listed and, if you click on it, you will see all details your need to understand and support your application, including the endpoint you can use to access your application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lle4N5RK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzsuesapssbt6639icpk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lle4N5RK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzsuesapssbt6639icpk.png" alt="Application Dashboard" width="880" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vynizjjj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/noeu1xn5c7av7ibisxj9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vynizjjj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/noeu1xn5c7av7ibisxj9.png" alt="Application Dashboard" width="880" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shipa will also give you a detailed view of your application dependency map and network policy. You can see both by clicking on the “Application Map” icon&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UwpsHEMK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yjxun90vffg2p9zgulmz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UwpsHEMK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yjxun90vffg2p9zgulmz.png" alt="Application Dashboard" width="880" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zIsB7dug--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ep3wixuukrg2ftzen73w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zIsB7dug--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ep3wixuukrg2ftzen73w.png" alt="Application Dashboard" width="880" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mN3qjaAq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2oxuh4b2jwucnxs2fyb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mN3qjaAq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e2oxuh4b2jwucnxs2fyb.png" alt="Application Dashboard" width="880" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In just a few steps, you have set up an application-focused pipeline. This will allow you and your team to quickly adopt Kubernetes without spending time dealing with the underlying infrastructure complexities.&lt;/p&gt;

&lt;p&gt;Not only that, but you have set up a free pipeline. Who doesn’t like a developer-friendly free pipeline? :) &lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>github</category>
      <category>devops</category>
      <category>actionshackathon21</category>
    </item>
    <item>
      <title>Creating a local dev environment for Kubernetes with $0 cost</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Fri, 12 Nov 2021 17:35:11 +0000</pubDate>
      <link>https://forem.com/brunoa19/creating-a-local-dev-environment-for-kubernetes-with-0-cost-4gen</link>
      <guid>https://forem.com/brunoa19/creating-a-local-dev-environment-for-kubernetes-with-0-cost-4gen</guid>
      <description>&lt;p&gt;Embracing any new technology stack can certainly be a journey. No matter if this is your first time using Kubernetes or you have been on the Google Borg Team. &lt;/p&gt;

&lt;p&gt;This post will show you how to create a Kubernetes cluster, add it an application platform (Shipa), and start deploying applications with $0 cost. &lt;/p&gt;

&lt;p&gt;We will leverage minikube and a free Shipa Cloud account.&lt;/p&gt;

&lt;h1&gt;
  
  
  Kubernetes Pre-Reqs
&lt;/h1&gt;

&lt;p&gt;The first part is for us to create a local Kubernetes Cluster, where you can deploy applications to. A quick and free option we will use is minikube on your local machine. &lt;/p&gt;

&lt;p&gt;If you are using a Mac, installing minikube can be accomplished by leveraging Homebrew. &lt;/p&gt;

&lt;p&gt;Once Homebrew is installed, run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install minikube&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If using a new variant of Mac OS, an easy hypervisor to use for minikube is HyperKit. You can set minikube to leverage HyperKit. If you have not installed HyperKit before, Homebrew can take care of that also for you. Potentially you might have to install the machine driver if the brew formulae does not have it as a dependency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install docker-machine-driver-hyperkit #optional
brew install hyperkit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once HyperKit is installed, you can wire minikube to leverage HyperKit. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;minikube config set driver hyperkit&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Lastly, depending on your machine size you can make dedicate more resources to minikube. For example I would like 8 gigs of memory dedicated to minikube. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;minikube config set memory 8128&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now you are all set to start your minukube cluster. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;minikube start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With minukube up and running, you can run a kubectl command to validate. Homebrew would have also laid down kubectl for you if installing minkube from Hoembrew. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl get nodes&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3v-pqn54--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btxsio3jsdiirl43dvdc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3v-pqn54--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btxsio3jsdiirl43dvdc.png" alt="Kubernetes cluster setup" width="880" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you are all set to create your Shipa Cloud account.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Started with Shipa Cloud
&lt;/h1&gt;

&lt;p&gt;Our goal is to deploy and manage our applications without dealing with the underlying complexities that Kubernetes impose, so we will use Shipa Cloud for that.&lt;/p&gt;

&lt;p&gt;You can &lt;a href="https://apps.shipa.cloud"&gt;sign up for a free account here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PZ6r1OSi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jt14vna900udm0gwi55l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PZ6r1OSi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jt14vna900udm0gwi55l.png" alt="Shipa Cloud" width="880" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a few &lt;a href="https://learn.shipa.io/docs/concepts"&gt;core concepts&lt;/a&gt; to work through. The first item that you will need to define is a Framework. A Shipa Framework is the lifeblood of your Shipa Configuration housing all the controls and policies. &lt;/p&gt;

&lt;p&gt;Shipa Cloud -&amp;gt; Frameworks + Create Framework -&amp;gt; Basic&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E-dxYlp3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1xcidu958dlk09ucyp4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E-dxYlp3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1xcidu958dlk09ucyp4.png" alt="Creating Shipa Framework" width="880" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating a basic Framework for the example, just name your Framework “myfirstframework”. By default, you have access to a Plan and Team. The defaults for the example are fine. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8ZLZbpIK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9r687qx3423vbhd602jn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8ZLZbpIK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9r687qx3423vbhd602jn.png" alt="Creating Shipa Framework" width="739" height="635"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you click Create, your Framework will be available. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dk6Dipsf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7gp5m24uwpi5jfdpfd5x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dk6Dipsf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7gp5m24uwpi5jfdpfd5x.png" alt="Creating Shipa Framework" width="880" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Wiring Your Kubernetes Cluster to Shipa Cloud
&lt;/h1&gt;

&lt;p&gt;You will need a few pieces of authentication from your minikube instance to connect it to Shipa Cloud. &lt;/p&gt;

&lt;p&gt;Shipa Cloud will need an accessible address to your cluster, a Kubernetes authentication token, and CA Certificate. &lt;/p&gt;

&lt;h2&gt;
  
  
  Public URL – ngrok
&lt;/h2&gt;

&lt;p&gt;If you run the cluster-info command on your local minukube instance, you will get a local to your network address. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl cluster-info | grep 'Kubernetes' | awk '/http/ {print $NF}'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Leveraging a service like &lt;a href="https://ngrok.com/"&gt;ngrok&lt;/a&gt;, you can expose your local instance, more specifically the Kubernetes API. &lt;a href="https://itnext.io/expose-local-kubernetes-service-on-internet-using-ngrok-2888a1118b5b"&gt;This guide on ITNEXT&lt;/a&gt; is really good for getting started. For evaluation purposes only, you can also expose the Kubernetes API. We will be doing that for this example. &lt;/p&gt;

&lt;h3&gt;
  
  
  Sign up and Install ngrok
&lt;/h3&gt;

&lt;p&gt;You can sign up for a free account with ngrok. Installing the ngrok client is easy with homebrew by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install –cask ngrok&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once installed, you can head to the ngrok setup page and run the authorization command e.g “Connect your account:”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5vQCWqh9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oz5pkxo68saj2v5o0epv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5vQCWqh9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oz5pkxo68saj2v5o0epv.png" alt="ngrok" width="880" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then: &lt;code&gt;ngrok authtoken &amp;lt;your_token&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ltj3dk7m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i615906kvt9nj18rccui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ltj3dk7m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i615906kvt9nj18rccui.png" alt="ngrok" width="880" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that is connected, you can leverage an &lt;a href="https://kubernetes.io/docs/tasks/extend-kubernetes/http-proxy-access-api/"&gt;HTTP proxy for the Kubernetes API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl proxy --disable-filter=true&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then can fire up ngrok to front the traffic over your localhost and the default Kubernetes API Port e.g 8001. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;ngrok http 8001&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n-A56qD---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrw5z5jblvh4yyqrhr5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n-A56qD---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrw5z5jblvh4yyqrhr5u.png" alt="ngrok" width="880" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Grab the HTTP forwarding address and can save that for the Shipa Cloud Cluster configuration. &lt;/p&gt;

&lt;h2&gt;
  
  
  Kubernetes Auth Token
&lt;/h2&gt;

&lt;p&gt;Creating an authorization token based off a Kubernetes role is straightforward. The &lt;a href="https://learn.shipa.io/docs/connecting-clusters"&gt;Shipa Documentation&lt;/a&gt; for connecting a cluster gives the needed manifest to create the role and base the token off of. &lt;/p&gt;

&lt;p&gt;Create the &lt;a href="https://learn.shipa.io/docs/connecting-clusters#cluster-connection"&gt;shipa-admin-service-account.yaml&lt;/a&gt; file with the following content:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I6IC9oLB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zajaj7akbh4wypzhzqqk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I6IC9oLB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zajaj7akbh4wypzhzqqk.png" alt="Shipa service account creation file" width="880" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then apply the manifest. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl apply -f shipa-admin-service-account.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With the service account created, you can grab the authorization token. Can re-run the below command when it is time to copy and paste into Shipa Cloud. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep shipa-admin | awk '{print $1}')&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eJFAj7FR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lplish1ol466hnskd2te.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eJFAj7FR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lplish1ol466hnskd2te.png" alt="Required Cluster Information" width="880" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also grab the CA Certificate for service account by running the following command. Similarly can re-run when needed to copy and paste into Shipa Cloud. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl get secret $(kubectl get secret | grep default-token | awk ‘{print $1}’) -o jsonpath='{.data.ca\.crt}’ | base64 –decode&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding the Cluster
&lt;/h2&gt;

&lt;p&gt;Once you have the three needed pieces, you can add the cluster to Shipa Cloud. &lt;/p&gt;

&lt;p&gt;Shipa Cloud -&amp;gt; Clusters + Add Cluster &lt;/p&gt;

&lt;p&gt;Can name the cluster “myminikube” and leverage your framework you created earlier e.g “myfirstframework”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GxAGSBxD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g445nmxauykezjo7evwm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GxAGSBxD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g445nmxauykezjo7evwm.png" alt="Adding Cluster Information" width="705" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click Next and fill out the the connectivity information [HTTP address, token, and certificate] that was just created. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6T50aJyL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oifkqhdtjdq4vlrwkpga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6T50aJyL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oifkqhdtjdq4vlrwkpga.png" alt="Adding Cluster Information" width="695" height="635"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you click Next, your Cluster will be available! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X50wGcm4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hws8v8arnxgvh7saq3l7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X50wGcm4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hws8v8arnxgvh7saq3l7.png" alt="Cluster available on Shipa Cloud" width="880" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once your cluster is available, the world is your oyster and you are ready to start deploying your apps without all the Kubernetes related complexity. &lt;/p&gt;

&lt;p&gt;Leveraging Shipa Cloud to help drive engineering efficiency across the application stack is now possible. With the wide paintbrush that Shipa Cloud offers, the art of the possible is great.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>shipa</category>
      <category>tutorial</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Nodejs App From Code To Kubernetes Cluster</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Tue, 02 Nov 2021 00:50:27 +0000</pubDate>
      <link>https://forem.com/brunoa19/nodejs-app-from-code-to-kubernetes-cluster-2l5b</link>
      <guid>https://forem.com/brunoa19/nodejs-app-from-code-to-kubernetes-cluster-2l5b</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/shipa-corp/ketch"&gt;Ketch&lt;/a&gt; automatically builds Docker images from your application source code&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/shipa-corp/ketch"&gt;Ketch&lt;/a&gt; saves you time by creating all the required components to run your application on Kubernetes and exposing it through an endpoint without you dealing with infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Pressure to Deliver
&lt;/h2&gt;

&lt;p&gt;Many of us now have to deploy our applications on Kubernetes.&lt;/p&gt;

&lt;p&gt;While this is great and introduces you to an opportunity to learn new technologies, the reality is that you are often swamped with work, under pressure to deliver your applications, and you want to go from ‘code to application’ as fast as possible.&lt;/p&gt;

&lt;p&gt;What conflicts with that goal is that Kubernetes introduces different infrastructure-level concepts and requirements that take our time away from delivering our application code.&lt;/p&gt;

&lt;p&gt;Most of us had an opportunity to experience Heroku. From a developer’s perspective, the experience was great, and we could go from ‘code to application’ fast and without dealing with infrastructure complexity.&lt;/p&gt;

&lt;p&gt;So how can we get the same level of experience but on top of Kubernetes, giving our Ops team the freedom to adopt Kubernetes but still maintain an application layer on top of it to guarantee developer experience?&lt;/p&gt;

&lt;p&gt;This article will show you how you can get a starter NodeJS server deployed on Kubernetes. The goal is to not deal with infrastructure complexities and not even have to build a Docker file, going from ‘code to application.’&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You need NodeJS installed to start development&lt;/li&gt;
&lt;li&gt;Docker in your local machine&lt;/li&gt;
&lt;li&gt;You need to be logged into your container registry&lt;/li&gt;
&lt;li&gt;Access to a Kubernetes cluster and kubectl configured&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://learn.theketch.io/docs/getting-started"&gt;Ketch installed&lt;/a&gt; and available in that cluster&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://learn.theketch.io/docs/getting-started#ketch-cli"&gt;Ketch CLI available&lt;/a&gt; in your local machine&lt;/li&gt;
&lt;li&gt;You have a &lt;a href="https://learn.theketch.io/docs/getting-started#creating-a-framework"&gt;framework created in Ketch&lt;/a&gt; where you will deploy your application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the Kubernetes cluster, I will be using a GKE (Google Kubernetes Engine) I have set up, but you can use local clusters directly from your laptops, such as &lt;a href="https://k3s.io/"&gt;K3s&lt;/a&gt; or &lt;a href="https://minikube.sigs.k8s.io/docs/start/"&gt;Minikube&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For &lt;a href="https://github.com/shipa-corp/ketch"&gt;Ketch&lt;/a&gt;, once you have your cluster available and kubectl access configured, you can quickly install Ketch by &lt;a href="https://learn.theketch.io/docs/getting-started"&gt;following the instructions here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Initializing the Node Application
&lt;/h2&gt;

&lt;p&gt;First, create a separate directory. &lt;/p&gt;

&lt;p&gt;From within the directory, you can initialize the project with npm (Node Package Manager).&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;npm init&lt;/code&gt; will prompt you with basic configuration questions, such as your project name, version, and others. Keeping the default values is good enough for our sample application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install &amp;lt;pkg&amp;gt;` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (nodejs-sample) 
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to /Users/brunoandrade/ketch/apps/nodejs-sample/package.json:

{
  "name": "nodejs-sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "author": "",
  "license": "ISC"
}

Is this OK? (yes) 

~/ketch/apps/nodejs-sample ❯  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Installing Express
&lt;/h2&gt;

&lt;p&gt;Next, you will install Express. You will leverage the Express framework to build web applications and APIs. Use npm to install it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ npm install express -save

added 50 packages, and audited 51 packages in 2s

found 0 vulnerabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above imports the Express module using a require function to return an object to configure your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Deploying the Code
&lt;/h2&gt;

&lt;p&gt;This is the fun part, having your application deployed directly from code into Kubernetes. Ketch will automatically build the Docker image for you, push it to your container registry of choice, create the required Kubernetes objects to run your application, and create an endpoint where you can access your application.&lt;/p&gt;

&lt;p&gt;If you are using Kubernetes directly, you would need to learn and deal with services, deployments, and more, but because you are using Ketch, you will do it all without dealing with any of that!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ketch app deploy nodejs-sample . -i shiparepo/nodejs-sample:0.1 -k dev-framework
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking down the command above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You use App deploy to deploy your application&lt;/li&gt;
&lt;li&gt;Nodejs-sample is the name of the application&lt;/li&gt;
&lt;li&gt;The ‘.’ is the path to your application source code&lt;/li&gt;
&lt;li&gt;‘-i shiparepo/nodejs-sample:0.1’ is the name and version of the image I want Ketch to use when creating and pushing the Docker image to my registry.&lt;/li&gt;
&lt;li&gt;Use the framework you created before with the ‘-k dev-framework’ flag&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 5: Checking your Application
&lt;/h2&gt;

&lt;p&gt;Now, you can check your application deployment status and endpoint by running the ketch app list command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ ketch app list
NAME             FRAMEWORK         STATE          ADDRESSES        BUILDER                                                         
nodejs-sample    dev-framework     1 deploying    http://nodejs-sample.35.230.16.206.shipa.cloud    heroku/buildpacks:20   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the result, you can see that Ketch automatically configured the ingress controller and created the endpoint for your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: There is No Step 6 🙂
&lt;/h2&gt;

&lt;p&gt;You have successfully deployed a sample NodeJS application on Kubernetes!&lt;/p&gt;

&lt;p&gt;The team is excited about enabling developers to focus on their application code instead of infrastructure. We would love it if you could show your support by &lt;a href="https://github.com/shipa-corp/ketch"&gt;starring the project on GitHub&lt;/a&gt; and sharing this article with your teammates.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>javascript</category>
      <category>react</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Deploying applications on Kubernetes using TypeScript</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Sat, 16 Oct 2021 23:32:10 +0000</pubDate>
      <link>https://forem.com/brunoa19/deploying-applications-on-kubernetes-using-typescript-3fn9</link>
      <guid>https://forem.com/brunoa19/deploying-applications-on-kubernetes-using-typescript-3fn9</guid>
      <description>&lt;p&gt;There is no doubt that YAML has developed a reputation for being a painful way to define and deploy applications on Kubernetes. The combination of semantics and empty spaces can drive some developers crazy. &lt;/p&gt;

&lt;p&gt;As Kubernetes advances, is it time for us to explore different options that can support both DevOps and Developers in deploying and managing applications on Kubernetes?&lt;/p&gt;

&lt;h2&gt;
  
  
  Using code to define ... code ...?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pulumi:&lt;/strong&gt; Modern infrastructure as code for developers, a.k.a the new kid on the block.&lt;/p&gt;

&lt;p&gt;Pulumi targets the widespread infrastructure as code (IaC) space but using a different approach. It allows developers to define infrastructure using their language of choice, such as TypeScript, JavaScript, Python, and others, instead of a proprietary language, such as HCL, from our friends at HashiCorp.&lt;/p&gt;

&lt;p&gt;It is an exciting approach that can benefit teams when scaling the management and evolution of infrastructure since it’s easier to find folks in your group who can help write, manage, and extend the infrastructure as code definitions using existing languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending &lt;a href="https://github.com/shipa-corp/ketch"&gt;Ketch&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Although the approach taken by Pulumi is intriguing, the way it deploys applications on Kubernetes today is very “infrastructure-focused.”  What I mean by that is that Pulumi requires developers to define the entire Kubernetes manifest and object, as they would do with Helm, but using their preferred language.&lt;/p&gt;

&lt;p&gt;While it may bring some initial benefits, it still requires developers to know how to define the objects in Kubernetes in detail.&lt;/p&gt;

&lt;p&gt;Instead, by combining the application-focused approach from &lt;a href="https://github.com/shipa-corp/ketch"&gt;Ketch&lt;/a&gt; with the IaC model from Pulumi, developers can have an application-focused layer they can leverage to quickly deploy their applications without getting into the underlying infrastructure details exposed by Kubernetes.&lt;/p&gt;

&lt;p&gt;We will go through the steps to deploy an application using Ketch and Pulumi but you can find additional details about the plugin here: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.theketch.io/docs/pulumi"&gt;Provider documentation&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing &lt;a href="https://github.com/shipa-corp/ketch"&gt;Ketch&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;You can find detailed information on how to &lt;a href="https://learn.theketch.io/docs/getting-started"&gt;install Ketch here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing The &lt;a href="https://github.com/shipa-corp/ketch"&gt;Ketch&lt;/a&gt; Provider For Pulumi
&lt;/h3&gt;

&lt;p&gt;Download Ketch’s resource plugin for Pulumi &lt;a href="https://storage.googleapis.com/ketch-pulumi/pulumi-resource-ketch"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once downloaded, move it to your local Pulumi path:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mv pulumi-resource-ketch $HOME/.pulumi/bin&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, add Pulumi to your PATH by using the command below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;export PATH=$PATH:$HOME/.pulumi/bin&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying an Application
&lt;/h2&gt;

&lt;p&gt;With Ketch and the provider for Pulumi installed, you can now deploy a sample application.&lt;/p&gt;

&lt;p&gt;For Ketch to deploy applications, we first need to create a framework. Frameworks in Ketch translate to a namespace in your cluster, and when deploying applications targeting that framework, they will be deployed to the created namespace.&lt;/p&gt;

&lt;p&gt;Let’s initialize Pulumi, so we can get started. You can do this by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pulumi new typescript&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As a result, Pulumi will create the file structure required for you to run Ketch and Pulumi:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZwUYrMGT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wjm74khlfz54jmu5r4o8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZwUYrMGT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wjm74khlfz54jmu5r4o8.png" alt="Pulumi folder structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s create the &lt;a href="https://github.com/shipa-corp/ketch"&gt;Ketch&lt;/a&gt; framework definition file. You can edit the &lt;strong&gt;index.ts&lt;/strong&gt; file and add the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as pulumi from "@pulumi/pulumi";
import * as ketch from "@shipa-corp/kpulumi";

const item = new ketch.Framework("dev-framework", {
    framework: {
        name: "dev",
        ingressController: {
            className: "istio",
            serviceEndpoint: "1.2.3.4",
            type: "istio",
        }
    }
});

export const frameworkName = item.framework.name;

const app = new ketch.App("bulletin-app", {
    app: {
        name: "bulletin-app",
        image: "docker.io/shipasoftware/bulletinboard:1.0",
        framework: "dev",
    }
});

export const appName = app.app.name;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the &lt;strong&gt;index.ts&lt;/strong&gt; file updated, install the required npm package using the command below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i @shipa-corp/kpulumi&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6utbz5lI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5bzhx3grrtw8wdll41y4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6utbz5lI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5bzhx3grrtw8wdll41y4.png" alt="NPM install result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, just run the command below to have both your framework and application deployed:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pulumi up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sPipfF51--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stc0w3atd7vld5e9wsds.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sPipfF51--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stc0w3atd7vld5e9wsds.png" alt="Running Pulumi"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The output above shows that both the framework and the applications were deployed.&lt;/p&gt;

&lt;p&gt;You can check the framework by using the command below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ketch framework list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6nRPqUvP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s40h1l9jpfrcaq6qtuka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6nRPqUvP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s40h1l9jpfrcaq6qtuka.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As mentioned above, when you create a framework, &lt;a href="https://github.com/shipa-corp/ketch"&gt;Ketch&lt;/a&gt; automatically creates a namespace for it in your cluster &lt;em&gt;(you can also instruct Ketch to use an existing namespace instead)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can also check the status of your application and the endpoint to access it by using the command below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ketch app list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2wTNLJaS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2lem5ocdo4ktroaknem5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2wTNLJaS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2lem5ocdo4ktroaknem5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we access the endpoint created above, we can see our application’s web interface:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oHfzXws1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vvyg0ci8egxfuewi40yg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oHfzXws1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vvyg0ci8egxfuewi40yg.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By combining Ketch and Pulumi, you can improve the developer experience when deploying applications on Kubernetes.&lt;/p&gt;

&lt;p&gt;We would love to hear your feedback and input to continue improving Ketch and build additional providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support The Project
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/shipa-corp/ketch"&gt;Help support Ketch by giving it a GitHub star!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>devops</category>
    </item>
    <item>
      <title>Deploying a Python machine learning app on Kubernetes</title>
      <dc:creator>Bruno</dc:creator>
      <pubDate>Sun, 12 Sep 2021 01:26:51 +0000</pubDate>
      <link>https://forem.com/brunoa19/deploying-a-python-machine-learning-app-on-kubernetes-31g5</link>
      <guid>https://forem.com/brunoa19/deploying-a-python-machine-learning-app-on-kubernetes-31g5</guid>
      <description>&lt;p&gt;Build and deploy simple machine learning data science web app in Python using the streamlit library in Kubernetes, without knowing Kubernetes!&lt;/p&gt;

&lt;p&gt;As a Data Scientist or Machine Learning Engineer, it is extremely important to be able to deploy our data science project using microservices and Kubernetes, as this helps to complete the data science life cycle and our infrastructure teams to continue evolving the infrastructure. &lt;/p&gt;

&lt;p&gt;Traditional deployment of machine learning models can become a daunting and/or time-consuming task if you are new to microservices and Kubernetes, so the goal of this article is to enable you to quickly deploy an ML application without dealing with the underlying Kubernetes infrastructure complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;To follow through this article, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Kubernetes cluster&lt;/li&gt;
&lt;li&gt;Ketch installed and configured. You can find more details here: &lt;a href="https://dev.toGetting%20Started"&gt;https://learn.theketch.io/docs/getting-started&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Since we will be deploying our application from the source, you need to log in through your terminal to your Docker registry.&lt;/li&gt;
&lt;li&gt;Both Ketch and Kubernetes CLI configured in your terminal&lt;/li&gt;
&lt;li&gt;A Ketch framework that we can use to deploy our application. You can find more information here: &lt;a href="https://dev.toGetting%20Started"&gt;https://learn.theketch.io/docs/getting-started#creating-a-framework&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overview of our application
&lt;/h2&gt;

&lt;p&gt;Today, we will be building a simple machine learning-powered web app for predicting the class label of Iris flowers as being setosa, versicolor and virginica.&lt;/p&gt;

&lt;p&gt;This will require the use of three Python libraries namely &lt;code&gt;streamlit&lt;/code&gt;, &lt;code&gt;pandas&lt;/code&gt; and &lt;code&gt;scikit-learn&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the conceptual flow of the app that will include two major components: (1) the front-end and (2) back-end.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;front-end&lt;/strong&gt;, the sidebar found on the left will accept input parameters pertaining to features (i.e. petal length, petal width, sepal length and sepal width) of Iris flowers. These features will be relayed to the back-end where the trained model will predict the class labels as a function of the input parameters. Prediction results are sent back to the front-end for display.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;back-end&lt;/strong&gt;, the user input parameters will be saved into a dataframe that will be used as test data. In the meantime, a classification model will be built using the random forest algorithm from the &lt;code&gt;scikit-learn&lt;/code&gt; library. Finally, the model will be applied to make predictions on the user input data and return the predicted class labels as being one of three flower type: setosa, versicolor or virginica. Additionally, the prediction probability will also be provided that will allow us to discern the relative confidence in the predicted class labels.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web application code
&lt;/h2&gt;

&lt;p&gt;You can find the complete application code available on &lt;a href="https://dev.toGitHub"&gt;https://github.com/brunoa19/ml-iris-app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, so let’s take a look under the hood and we will see that the app that we are going to be building today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import streamlit as st
import pandas as pd
from sklearn import datasets
from sklearn.ensemble import RandomForestClassifier

st.write("""
# Simple Iris Flower Prediction App
This app predicts the **Iris flower** type!
""")

st.sidebar.header('User Input Parameters')

def user_input_features():
    sepal_length = st.sidebar.slider('Sepal length', 4.3, 7.9, 5.4)
    sepal_width = st.sidebar.slider('Sepal width', 2.0, 4.4, 3.4)
    petal_length = st.sidebar.slider('Petal length', 1.0, 6.9, 1.3)
    petal_width = st.sidebar.slider('Petal width', 0.1, 2.5, 0.2)
    data = {'sepal_length': sepal_length,
            'sepal_width': sepal_width,
            'petal_length': petal_length,
            'petal_width': petal_width}
    features = pd.DataFrame(data, index=[0])
    return features

df = user_input_features()

st.subheader('User Input parameters')
st.write(df)

iris = datasets.load_iris()
X = iris.data
Y = iris.target

clf = RandomForestClassifier()
clf.fit(X, Y)

prediction = clf.predict(df)
prediction_proba = clf.predict_proba(df)

st.subheader('Class labels and their corresponding index number')
st.write(iris.target_names)

st.subheader('Prediction')
st.write(iris.target_names[prediction])
#st.write(prediction)

st.subheader('Prediction Probability')
st.write(prediction_proba)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy and create this code using the name &lt;strong&gt;iris-ml-app.py&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Application requirements
&lt;/h2&gt;

&lt;p&gt;For our application to run, we will need to ensure that requirements are in place. &lt;/p&gt;

&lt;h3&gt;
  
  
  Application libraries
&lt;/h3&gt;

&lt;p&gt;Let’s start with the Python libraries we need:&lt;/p&gt;

&lt;p&gt;Create a file called requirements.txt in the same directory as the application code above. Here is the content of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;streamlit
pandas
scikit-learn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These 3 lines will have Ketch install these libraries when the Docker image is built for our application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exposing port
&lt;/h3&gt;

&lt;p&gt;By default, the Python &lt;code&gt;streamlit&lt;/code&gt; library exposes our application through port &lt;strong&gt;8501&lt;/strong&gt;, so we will need to ensure Kubernetes understands that it should use this port for our application.&lt;/p&gt;

&lt;p&gt;To do that, create a file called &lt;strong&gt;ketch.yaml&lt;/strong&gt; in the same directory as the previous files. Here is the content of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubernetes:
  processes:
    web:
      ports:
        - name: iris-app
          protocol: TCP
          port: 8501
          target_port: 8501
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The content above will tell Kubernetes to assign port 8501 to our application process. Save the file&lt;/p&gt;

&lt;h3&gt;
  
  
  Application Process
&lt;/h3&gt;

&lt;p&gt;Last, we need to define how our application should be started once its deployed. For that, create a file called &lt;strong&gt;&lt;em&gt;Procfile&lt;/em&gt;&lt;/strong&gt; in the same directory as the previous files. Here is the content of the file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;web: streamlit run iris-ml-app.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command above will tell Ketch that it should use the &lt;code&gt;streamlit&lt;/code&gt; library to run our Iris app code created before. Save the file&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying and running the application
&lt;/h3&gt;

&lt;p&gt;Now that we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our &lt;strong&gt;iris-ml-app.py&lt;/strong&gt; code&lt;/li&gt;
&lt;li&gt;Our &lt;strong&gt;requirements.txt&lt;/strong&gt; file with all library dependencies&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;ketch.yaml&lt;/strong&gt; file assigning a port to expose our app&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Procfile&lt;/strong&gt; to tell Ketch how to start our application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can then deploy our application. You can deploy your application using the command below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ketch app deploy iris . -i shiparepo/iris:latest -k dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create and deploy our application using iris as the application name&lt;/li&gt;
&lt;li&gt;The "." indicates that it will use the source code and files available in the directory where you are running this command from&lt;/li&gt;
&lt;li&gt;It will automatically create a Docker image and store it in my registry with the name iris. Keep in mind that you should adjust this to reflect your docker registry name&lt;/li&gt;
&lt;li&gt;It will use the dev framework previously created to deploy our application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The deployment process will take a couple of minutes as it will create and store the Docker image in your registry.&lt;/p&gt;

&lt;p&gt;Once the deployment is finished, you can see your application status using the command below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ketch app list&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9rjn0ca7gp89xcfhcn7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9rjn0ca7gp89xcfhcn7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As part of the output of the command, you can see that Ketch also automatically created the endpoint address where you can access your application. Accessing that, we can see our Iris application ready to be used:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ujchwj9oc4cg5qbdm9m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ujchwj9oc4cg5qbdm9m.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That's it! &lt;/p&gt;

&lt;p&gt;You have deployed your Python machine learning application on Kubernetes without having to deal with the underlying complexities that Kubernetes might introduce.&lt;/p&gt;

&lt;p&gt;By using Ketch, you get your applications and models deployed quickly while allowing your infrastructure team to continue the adoption of microservices and Kubernetes.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>kubernetes</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
