<?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: Ramiro Berrelleza</title>
    <description>The latest articles on Forem by Ramiro Berrelleza (@rberrelleza).</description>
    <link>https://forem.com/rberrelleza</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%2F187185%2F76c1cfed-cbbd-4c7e-9912-f15051a8a927.jpeg</url>
      <title>Forem: Ramiro Berrelleza</title>
      <link>https://forem.com/rberrelleza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rberrelleza"/>
    <language>en</language>
    <item>
      <title>Chaos Engineering with Litmus and Okteto Cloud</title>
      <dc:creator>Ramiro Berrelleza</dc:creator>
      <pubDate>Fri, 21 Aug 2020 17:12:57 +0000</pubDate>
      <link>https://forem.com/okteto/chaos-engineering-with-litmus-and-okteto-cloud-2p3l</link>
      <guid>https://forem.com/okteto/chaos-engineering-with-litmus-and-okteto-cloud-2p3l</guid>
      <description>&lt;p&gt;Cloud Native applications are, by definition, highly distributed, elastic, resistant to failure and loosely coupled. That's easy to say, and even diagram. But how do we validate that our applications will perform as expected under different failure conditions?&lt;/p&gt;

&lt;p&gt;Enter Chaos engineering. Chaos engineering is the discipline of experimenting on a software system in production in order to build confidence in the system's capability to withstand turbulent and unexpected conditions. Chaos Engineering is a great tool to help us find weaknesses and misconfiguration in our services. It is particularly important for Cloud Native applications, which, due to their distributed and elastic nature, need to be resilient by default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://litmuschaos.io/" rel="noopener noreferrer"&gt;Litmus&lt;/a&gt; is a CNCF sandbox project for practicing Chaos Engineering in Cloud Native environments. Litmus provides a chaos-operator, a large set of chaos experiments in its hub, detailed documentation, quick Demo, and a friendly community. In this blog we'll show you how you can use Litmus and Okteto together to start Chaos testing your applications in a few seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chaos Testing with Litmus
&lt;/h2&gt;

&lt;p&gt;When chaos testing an application with LitmusChaos, there are four components that you'll need to keep in mind.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chaos Operator
&lt;/h3&gt;

&lt;p&gt;This is &lt;a href="https://github.com/litmuschaos/litmus" rel="noopener noreferrer"&gt;the core part&lt;/a&gt; of LitmusChaos. The operator is in charge of executing the experiments, and reporting the results once the experiment is finished.&lt;/p&gt;

&lt;p&gt;You can install it &lt;a href="https://docs.litmuschaos.io/docs/getstarted/#install-litmus" rel="noopener noreferrer"&gt;directly from the command line&lt;/a&gt;, the &lt;a href="https://hub.helm.sh/charts/litmuschaos/litmus" rel="noopener noreferrer"&gt;official helm chart&lt;/a&gt;, or &lt;a href="https://cloud.okteto.com/#/spaces/@personal?deploy=litmuschaos" rel="noopener noreferrer"&gt;from the Okteto Cloud catalog&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chaos Experiment
&lt;/h3&gt;

&lt;p&gt;This is the chaos action that will performed on your application. This goes from Kubernetes specific like deleting a pod, or hogging the network, to application specific actions like randomly deleting an OpenEBS drive.&lt;/p&gt;

&lt;p&gt;The LitmusChaos community maintains &lt;a href="https://hub.litmuschaos.io/" rel="noopener noreferrer"&gt;an online hub of chaos experiments&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chaos Engine
&lt;/h3&gt;

&lt;p&gt;The Chaos Engine is the link between the chaos experiment and the application under test. This is where you specify any parameters of your experiment such as its duration, enable/disable policies (e.g enable/disable monitoring) as well as information on how to find the targets of the experiment (typically, this is the application under test).&lt;/p&gt;

&lt;h3&gt;
  
  
  Application Under Test
&lt;/h3&gt;

&lt;p&gt;This is the application that will be the "target" of the chaos experiment. Currently, LitmusChaos supports Deployments, StatefulSets and DaemonSets.  Under the default configuration, you need to add the &lt;code&gt;litmuschaos.io/chaos: "true"&lt;/code&gt; tag to the resource for the Chaos Operator to be able to find them, and to prevent other applications from being affected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequistes
&lt;/h2&gt;

&lt;p&gt;To chaos-test your application you'll need to install:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;a href="https://okteto.com/docs/getting-started/installation" rel="noopener noreferrer"&gt;okteto CLI&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A free &lt;a href="https://cloud.okteto.com" rel="noopener noreferrer"&gt;Okteto Cloud&lt;/a&gt; account.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kubectl&lt;/code&gt; configured &lt;a href="https://okteto.com/docs/cloud/credentials" rel="noopener noreferrer"&gt;to talk to Okteto Cloud&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Your favorite IDE or text editor.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Deploy your Chaos-ready Development Environment
&lt;/h2&gt;

&lt;p&gt;You can always manually install every component by hand. But instead, I'm taking advantage of Okteto's &lt;a href="https://okteto.com/blog/cloud-based-development-environments/" rel="noopener noreferrer"&gt;pre-configured development environments&lt;/a&gt;. Just click on the &lt;strong&gt;Develop on Okteto&lt;/strong&gt; button below and deploy your &lt;em&gt;chaos-ready&lt;/em&gt; development environment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cloud.okteto.com/deploy?repository=https://github.com/okteto/litmus-on-okteto&amp;amp;branch=master" rel="nofollow noopener noreferrer"&gt;&lt;br&gt;
  &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fokteto.com%2Fdevelop-okteto.svg" alt="Develop on Okteto"&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will automatically deploy the following resources on your Okteto Cloud account:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Litmus Chaos operator, from the Okteto catalog&lt;/li&gt;
&lt;li&gt;The pod-delete &lt;a href="https://raw.githubusercontent.com/okteto/litmus-on-okteto/master/chaos/experiment.yaml" rel="noopener noreferrer"&gt;chaos experiment&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://raw.githubusercontent.com/okteto/litmus-on-okteto/master/application/k8s.yaml" rel="noopener noreferrer"&gt;application under test&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&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%2Fi%2Fmafs2v4i88ktkqm85c67.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%2Fi%2Fmafs2v4i88ktkqm85c67.png" alt="Development Environment deployed"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Chaos Test the Application
&lt;/h2&gt;

&lt;p&gt;Now that we have our development environment, let's chaos test the application. For this example, we are using the traditional Hello World application, deployed with two replicas. Click on the link and call it a few times to verify that it works fine.&lt;/p&gt;

&lt;p&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%2Fi%2F0zh5sw3xappc7jyjl3wt.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%2Fi%2F0zh5sw3xappc7jyjl3wt.png" alt="Application in Action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the application running, we are ready to start the chaos experiment. In Litmus-speak, this means creating the &lt;code&gt;ChaosEngine&lt;/code&gt; resource.  Create a file &lt;code&gt;engine.yaml&lt;/code&gt;, open it in your favorite IDE, and paste the content below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;litmuschaos.io/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ChaosEngine&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pod-killer-chaos&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;annotationCheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt;
  &lt;span class="na"&gt;engineState&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;active'&lt;/span&gt;
  &lt;span class="na"&gt;appinfo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;applabel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;app=hello-world'&lt;/span&gt;
    &lt;span class="na"&gt;appkind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;deployment'&lt;/span&gt;
  &lt;span class="na"&gt;chaosServiceAccount&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
  &lt;span class="na"&gt;monitoring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;jobCleanUpPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;delete'&lt;/span&gt;
  &lt;span class="na"&gt;experiments&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pod-delete&lt;/span&gt;
      &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;KILL_COUNT&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1'&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TOTAL_CHAOS_DURATION&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;60s'&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CHAOS_INTERVAL&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;15s'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ChaosEngine&lt;/code&gt; resource has three main sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;appinfo&lt;/code&gt;: This tells the Litmus operator which application to target. You have to specify a label selector and the type of resource.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;experiments&lt;/code&gt;: A list of experiments to run. In this case, we are running the Pod Delete experiment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;experiments.spec.components&lt;/code&gt;: The experiment-specific value overrides. In this case, we are telling the experiment to kill 1 pod over 60 seconds. The available values come from the &lt;code&gt;ChaosExperiment&lt;/code&gt; resource.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start the chaos experiment by creating the &lt;code&gt;ChaosEngine&lt;/code&gt; resource with &lt;code&gt;kubectl&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; engine.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chaosengine.litmuschaos.io/pod-killer-chaos created
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Witness the Chaos
&lt;/h2&gt;

&lt;p&gt;The experiment will kill one of our application's pods. If you run the command below once the experiment has started, you'll see how a random pod is killed and then automatically recreated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;kubectl get pod &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME                                 READY   STATUS              RESTARTS   AGE
hello-world-75947547d4-2fcbc         1/1     Running             0          57m
hello-world-75947547d4-c6wsv         0/1     ContainerCreating   0          10s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the experiment is running, keep refreshing the browser. Notice how the calls will display different pod names, but they were never interrupted? That's because our application is resilient to pod destruction 💪🏻!&lt;/p&gt;

&lt;p&gt;When an experiment is created, a &lt;code&gt;ChaosResult&lt;/code&gt; resource will created to hold the result of the experiment. The &lt;code&gt;status.verdict&lt;/code&gt; key is set to &lt;code&gt;Awaited&lt;/code&gt; while the experiment is in progress. Once it finishes, it will change to either &lt;code&gt;Pass&lt;/code&gt; or &lt;code&gt;Fail&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl describe chaosresult pod-killer-chaos-pod-delete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name:         pod-killer-chaos-pod-delete
Namespace:    rberrelleza
Labels:       name=pod-killer-chaos-pod-delete
Annotations:  &amp;lt;none&amp;gt;
API Version:  litmuschaos.io/v1alpha1
Kind:         ChaosResult
Metadata:
  Creation Timestamp:  2020-08-05T21:14:05Z
  Generation:          5
  Resource Version:    165298631
  Self Link:           /apis/litmuschaos.io/v1alpha1/namespaces/rberrelleza/chaosresults/pod-killer-chaos-pod-delete
  UID:                 a7f50d28-1f14-4a03-9013-94e72d69eb72
Spec:
  Engine:      pod-killer-chaos
  Experiment:  pod-delete
Status:
  Experimentstatus:
    Fail Step:  N/A
    Phase:      Running
    Verdict:    Awaited
Events:
  Type    Reason   Age   From                     Message
  ----    ------   ----  ----                     -------
  Normal  Summary  45m   experiment-l0k004-5x2fj  pod-delete experiment has been Passed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extra Chaos
&lt;/h2&gt;

&lt;p&gt;In a future post I'll show how you can take your chaos testing to the next level and write your own application-specific experiments. Can't wait? &lt;a href="https://github.com/ksatchit" rel="noopener noreferrer"&gt;Karthik&lt;/a&gt; from MayaData wrote &lt;a href="https://dev.to/ksatchit/litmus-sdk-devtest-your-chaos-experiments-with-okteto-4dkj"&gt;a pretty cool getting started guide&lt;/a&gt;. And it happens to use the &lt;code&gt;okteto&lt;/code&gt; CLI as part of the dev flow. How cool is that?&lt;/p&gt;

&lt;p&gt;Litmus has &lt;a href="https://hackmd.io/a4Zu_sH4TZGeih-xCimi3Q?view" rel="noopener noreferrer"&gt;a monthly community call&lt;/a&gt; where the community gets together and talks about their cool use cases and needs. The team was nice enough to invite me to &lt;a href="https://www.youtube.com/watch?v=kPFwrPe84sY&amp;amp;feature=youtu.be" rel="noopener noreferrer"&gt;this month's call&lt;/a&gt; to demo the workflow I showed you on this post. It's a great place to talk and learn from other practitioners.&lt;/p&gt;

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

&lt;p&gt;In this post, we showed how you can deploy a replicable development environment that includes an application, the LitmusChaos operator, and your chaos experiment, all in one click. Then, we ran a chaos experiment, validating that our application is resilient to a pod failure.&lt;/p&gt;

&lt;p&gt;This is a great example of how you can &lt;a href="https://okteto.com" rel="noopener noreferrer"&gt;use Okteto to accelerate your entire team&lt;/a&gt;. One person configures the app with the chaos tools, and everyone else can create their own namespace on demand, deploy a pre-configured, chaos-ready development environment, and start running experiments without having to think twice about installation scripts or infrastructure configuration.&lt;/p&gt;

&lt;p&gt;Let's keep the conversation going! Join the &lt;a href="https://slack.okteto.com" rel="noopener noreferrer"&gt;Okteto&lt;/a&gt; and &lt;a href="https://slack.litmuschaos.io/" rel="noopener noreferrer"&gt;Litmus&lt;/a&gt; communities to talk more about Cloud Native development and Chaos Engineering.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Thanks to Karthik Satchitanand and Prithvi Raj for reading drafts of this.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>kubernetes</category>
      <category>litmuschaos</category>
      <category>microservices</category>
      <category>docker</category>
    </item>
    <item>
      <title>Remote Development Environments with PyCharm, Okteto and Kubernetes</title>
      <dc:creator>Ramiro Berrelleza</dc:creator>
      <pubDate>Tue, 12 May 2020 17:44:18 +0000</pubDate>
      <link>https://forem.com/okteto/remote-development-environments-with-pycharm-okteto-and-kubernetes-494a</link>
      <guid>https://forem.com/okteto/remote-development-environments-with-pycharm-okteto-and-kubernetes-494a</guid>
      <description>&lt;p&gt;In the past, we've talked about &lt;a href="https://okteto.com/blog/remote-kubernetes-development/"&gt;how to develop remotely with VS Code&lt;/a&gt;. Today, I'm going show you how can you use &lt;code&gt;okteto&lt;/code&gt; to define and deploy a fully configured remote development environment for your python application, how to integrate it with &lt;a href="https://www.jetbrains.com/pycharm/"&gt;Jetbrains' PyCharm&lt;/a&gt; and how to use it to build a Cloud Native application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://okteto.com"&gt;The Okteto Developer platform&lt;/a&gt; allows you to spin up an entire development environment in Kubernetes with one click. This can be as simple as a single container or as complex as a microservice-based Cloud Native Application. You deploy your application with one click, select the component you're going to develop on, and you're ready to go in seconds. &lt;/p&gt;

&lt;h1&gt;
  
  
  Install Okteto
&lt;/h1&gt;

&lt;p&gt;The &lt;a href="https://okteto.com/docs/getting-started/installation"&gt;Okteto CLI&lt;/a&gt; is an open source single-binary application that allows you to deploy development environments (among other things) in any Kubernetes cluster. It works with Linux, MacOS and Windows. We'll be using it to create and launch our development environment. Follow the steps below to install it:&lt;/p&gt;

&lt;p&gt;MacOS / Linux&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl https://get.okteto.com &lt;span class="nt"&gt;-sSfL&lt;/span&gt; | sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Windows&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;Download https://downloads.okteto.com/cli/okteto.exe and add it to your `$&lt;/span&gt;PATH&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h1&gt;
  
  
  Configure your Kubernetes Access
&lt;/h1&gt;

&lt;p&gt;Okteto is compatible with any Kubernetes cluster, local or remote. To keep this example simple, we are going to be using &lt;a href="https://okteto.com"&gt;Okteto Cloud&lt;/a&gt; to deploy the development environment. If you prefer to use your own Kubernetes cluster, you can skip this step.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;okteto login&lt;/code&gt; in your local console to create a free Okteto Cloud account, login, and to download your &lt;code&gt;Kubeconfig&lt;/code&gt;. We'll be needing it later in the post.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto login
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Authentication will continue in your default browser
You can also open a browser and navigate to the following address:
&lt;/span&gt;&lt;span class="c"&gt;...
&lt;/span&gt;&lt;span class="go"&gt; ✓  Logged in as rberrelleza
 ✓  Updated context 'cloud_okteto_com' in '/Users/ramiro/.kube/config'
    Run 'okteto namespace' every time you need to activate your Okteto context again
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Create a New Python Project
&lt;/h1&gt;

&lt;p&gt;Start by opening PyCharm and creating a new project for your application and development environment. Pick the "Pure Python" template and call it &lt;code&gt;guestbook&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iJ0Du3iO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/new-project.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iJ0Du3iO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/new-project.png" alt="New Project "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Define your Remote Development Environment
&lt;/h1&gt;

&lt;p&gt;At a high level, &lt;a href="https://okteto.com/docs/reference/development-environment"&gt;a remote development environment&lt;/a&gt; is a Docker container that contains everything you need to build and develop your application, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One or more language runtimes (e.g python, ruby, node)&lt;/li&gt;
&lt;li&gt;SDKs for your language runtime (e.g JDK, python-dev)&lt;/li&gt;
&lt;li&gt;Binary dependencies (e.g. openssl, git)&lt;/li&gt;
&lt;li&gt;Tools to manage and install dependencies (e.g. pip, bundler, yarn)&lt;/li&gt;
&lt;li&gt;Tools to run your tests and analyze your code (e.g nosetest, pylint)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okteto looks for a special file called &lt;code&gt;okteto.yml&lt;/code&gt; to define the development environment for an application. &lt;/p&gt;

&lt;p&gt;Create a file named &lt;code&gt;okteto.yml&lt;/code&gt; in the &lt;code&gt;guestbook&lt;/code&gt; project and copy the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;guestbook&lt;/span&gt;
&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;okteto/python:3&lt;/span&gt;
&lt;span class="na"&gt;forward&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8080:8080&lt;/span&gt;
&lt;span class="na"&gt;remote&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2222&lt;/span&gt;
&lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This file is telling &lt;code&gt;okteto&lt;/code&gt; to perform the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a development environment named &lt;code&gt;hello-world&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Use the Docker image &lt;code&gt;okteto/python&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Start a remote SSH server on port 2222 (more on this later on)&lt;/li&gt;
&lt;li&gt;Forward port 8080 to the remote environment&lt;/li&gt;
&lt;li&gt;Run the &lt;code&gt;bash&lt;/code&gt; when it starts, so we get a remote terminal. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Take a look at &lt;a href="https://okteto.com/docs/reference/manifest"&gt;the manifest reference&lt;/a&gt; to learn the different configuration settings available.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Deploy your Remote Development Environment
&lt;/h1&gt;

&lt;p&gt;Let's deploy the development environment. First, open a local terminal directly in Pycharm. Then, run the &lt;code&gt;okteto up&lt;/code&gt; command on it.&lt;/p&gt;

&lt;p&gt;Since this is the first time you launch your development environment, you'll be asked to confirm if you want to create it. Type &lt;code&gt;y&lt;/code&gt; and press enter to continue.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;okteto up&lt;/code&gt; command will perform the following tasks automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy the development environment as described by &lt;code&gt;okteto.yml&lt;/code&gt; into Okteto Cloud (or your personal Kubernetes cluster).&lt;/li&gt;
&lt;li&gt;Forward port 8080 to the remote environment.&lt;/li&gt;
&lt;li&gt;Start an SSH server in port 2222.&lt;/li&gt;
&lt;li&gt;Start a &lt;a href="https://okteto.com/docs/reference/file-synchronization/index.html"&gt;file synchronization service&lt;/a&gt; to keep your changes up-to-date between your local filesystem and your application pods.&lt;/li&gt;
&lt;li&gt;Launch a remote shell in your remote development environment. Now you can build, test, and run your application as if you were in your local machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vyuj-osV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/dev-env.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vyuj-osV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/dev-env.png" alt="Development Environment"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Use your Remote Environment as an Interpreter
&lt;/h1&gt;

&lt;p&gt;By default, PyCharm will use your local python interpreter for your project. Instead of that, we're going to configure it to directly use our remote development environment as the target. This way, we can guarantee that we always have the right setup, independent of what happens in our local machine. To do this, we are going to take advantage of PyCharm's &lt;a href="https://www.jetbrains.com/help/pycharm/configuring-remote-interpreters-via-ssh.html"&gt;remote interpreters&lt;/a&gt; and Okteto's &lt;a href="https://okteto.com/docs/reference/manifest#remote-integer-optional"&gt;remote SSH server&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;To add a remote interpreter, right click on the status bar in the bottom right of the screen, and click on the &lt;code&gt;Add Interpreter...&lt;/code&gt; option in the menu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pb2qoZCh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/add-interpreter.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pb2qoZCh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/add-interpreter.png" alt="Add Interpreter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, select the &lt;code&gt;SSH Interpreter&lt;/code&gt; option on the left, and &lt;code&gt;Existing server configuration&lt;/code&gt; on the right. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--piaOsDIV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/add-ssh-interpreter.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--piaOsDIV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/add-ssh-interpreter.png" alt="Add SSH Interpreter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the button with the three dots in the right to launch the SSH Configuration dialog, and add a new configuration with the same values as show below, replacing &lt;code&gt;/Users/ramiro&lt;/code&gt; with the path to your &lt;code&gt;$HOME&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qq5ZDLs8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/add-ssh-configuration.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qq5ZDLs8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/add-ssh-configuration.png" alt="Add SSH Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press the &lt;code&gt;Test Connection&lt;/code&gt; button to validate that everything is configured correctly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you run &lt;code&gt;okteto up&lt;/code&gt; the first time, Okteto will create a SSH key pair for you and save it at $HOME/.okteto/id_rsa_okteto and $HOME/.okteto/id_rsa_okteto.pub. The SSH server launched in your development environment will be automatically configured to use these keys for authentication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iX1KDuWF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/add-interpreter-next.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iX1KDuWF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/add-interpreter-next.png" alt="Add Interpreter Configured"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the SSH configuration is completed, click on the &lt;code&gt;Next&lt;/code&gt; button, to get the to final configuration screen (yay!).&lt;/p&gt;

&lt;p&gt;Update the path to the interpreter to match the one in your remote development environment (&lt;code&gt;/usr/local/bin/python&lt;/code&gt;), set the folder mapping to &lt;code&gt;/okteto&lt;/code&gt; and disable file uploading, since Okteto will automatically take care of this for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_V-RSu3v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/add-interpreter-finish.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_V-RSu3v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/add-interpreter-finish.png" alt="Finish the interpreter's configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;code&gt;Finish&lt;/code&gt; button to save your configuration. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The interpreter configuration is saved in the .idea folder. You can include this configuration in your repository so the rest of your team can benefit from it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From now on, your project will directly use the interpreter in your remote development environment, instead of the local one. Why don't you open PyCharm's python console and try it out?&lt;/p&gt;

&lt;h1&gt;
  
  
  Develop your Application in your Remote Development Environment
&lt;/h1&gt;

&lt;p&gt;Now that we have our development environment up and running, it's time to build our application. For the purpose of this post, we are going to build a an application that lets users post messages to a public message. &lt;/p&gt;

&lt;p&gt;The application will include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A flask web server that handles the display and updates to the guestbook.&lt;/li&gt;
&lt;li&gt;A MongoDB instance to store the messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deploy your MongoDB Instance
&lt;/h2&gt;

&lt;p&gt;One of the big advantages of using remote development environments is that we don't have to run anything locally. Since the development environment is running in Kubernetes, it has access to anything available there, such as secrets, other services, databases, etc.&lt;/p&gt;

&lt;p&gt;For MongoDB, you can take advantage of Okteto Cloud's Application Catalog and deploy it with one click. &lt;/p&gt;

&lt;p&gt;To do this, open your browser, go to &lt;a href="https://cloud.okteto.com"&gt;Okteto Cloud&lt;/a&gt;, click on the &lt;code&gt;Deploy&lt;/code&gt; button, select &lt;code&gt;MongoDB&lt;/code&gt; from the list of applications, and click on the &lt;code&gt;Deploy&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iihC4pun--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/deploy-mongodb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iihC4pun--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/deploy-mongodb.png" alt="Deploy MongoDB with one click"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait for a few seconds for your instance to finish deploying. You'll be able to see the status directly in Okteto Cloud's dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BQKau9a4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/run-mongodb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BQKau9a4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://okteto.com/blog/remote-development-environments-with-pycharm/run-mongodb.png" alt="MongoDB and your Remote Development Environment"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you deployed your development environment in your own cluster, you can deploy it using &lt;a href="https://github.com/helm/charts/tree/master/stable/mongodb-replicaset"&gt;the official Helm Chart&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Developing Directly on Kubernetes
&lt;/h2&gt;

&lt;p&gt;Now that we have our development environment and our MongoDB instance, let's build our application. &lt;/p&gt;

&lt;p&gt;First, create a python file called &lt;code&gt;app.py&lt;/code&gt; in your project. This is the file that will contain our server's code, so let's start with the basics. Copy the code below in &lt;code&gt;app.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask_pymongo&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PyMongo&lt;/span&gt;


&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"MONGO_URI"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mongodb://okteto:okteto@mongodb:27017/okteto"&lt;/span&gt;
&lt;span class="n"&gt;mongo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PyMongo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'0.0.0.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The code above will perform the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import &lt;code&gt;flask&lt;/code&gt; and &lt;code&gt;flask_pymongo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Configure the mongo connection string and data access object.&lt;/li&gt;
&lt;li&gt;Start the webserver.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that we are using &lt;code&gt;mongodb:27107&lt;/code&gt; as the name and port of the MongoDB instance, instead of the typical &lt;code&gt;localhost&lt;/code&gt;. This is because our development environment is running in Kubernetes, just as MongoDB, so we can access it using its DNS name. Just like we would do in production 💫.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As soon as you save the file, errors will appear on the first two lines. This is because our development environment doesn't have them installed yet. To install them, go to the console (the one with the &lt;code&gt;okteto &amp;gt;&lt;/code&gt; prompt) and &lt;code&gt;pip install&lt;/code&gt; the requirements, just like you would do locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;rberrelleza:guestbook okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;flask flask_pymongo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="c"&gt;...
&lt;/span&gt;&lt;span class="go"&gt;Installing collected packages: MarkupSafe, Jinja2, itsdangerous, click, Werkzeug, flask, PyMongo, flask-pymongo
Successfully installed Jinja2-2.11.2 MarkupSafe-1.1.1 PyMongo-3.10.1 Werkzeug-1.0.1 click-7.1.2 flask-1.1.2 flask-pymongo-2.3.0 itsdangerous-1.1.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When installing dependencies, is a good practice to add them to your &lt;code&gt;requirements.txt&lt;/code&gt; file, so it reflects all your runtime dependencies. Run the &lt;code&gt;pip freeze&lt;/code&gt; command in the same console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;rberrelleza:guestbook okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you wait a couple of seconds, you'll see that the &lt;code&gt;requirements.txt&lt;/code&gt; file appears in your project automatically. This is the magic of okteto's file synchronization. Any file change in the remote development environment or locally will be automatically synchronized in the other side.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;python app.py&lt;/code&gt; in the console to start the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;rberrelleza:guestbook okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python app.py 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 160-502-646
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Your application is up and running, directly in your remote development environment. To access it, open your browser and go to &lt;code&gt;http://localhost:8080&lt;/code&gt;.  (this is why we included a forwarding rule for port &lt;code&gt;8080&lt;/code&gt; in the &lt;code&gt;okteto.yml&lt;/code&gt; manifest).&lt;/p&gt;

&lt;p&gt;What's cool is that your application is also running on debug mode. This means that flask will automatically reload your application every time the code changes. Let's try that by finishing our application's code.&lt;/p&gt;

&lt;p&gt;Update &lt;code&gt;app.py&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask_pymongo&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PyMongo&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"MONGO_URI"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mongodb://okteto:okteto@mongodb:27017/okteto"&lt;/span&gt;
&lt;span class="n"&gt;mongo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PyMongo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_messages&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;mongo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;post_message&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;mongo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;insert_one&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'0.0.0.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this change, the application will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accept a &lt;code&gt;POST&lt;/code&gt; request on &lt;code&gt;/&lt;/code&gt;. It will read the &lt;code&gt;message&lt;/code&gt; and &lt;code&gt;user&lt;/code&gt; from the request's content and insert them into the MongoDB database.&lt;/li&gt;
&lt;li&gt;Accept a &lt;code&gt;GET&lt;/code&gt; request on &lt;code&gt;/&lt;/code&gt;. It will get all the available messages from MongoDB, and return them as a &lt;code&gt;json&lt;/code&gt; array.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As soon as you save the files, &lt;code&gt;okteto&lt;/code&gt; will detect the changes and synchronize them to your remote development environment. Then, flask will automatically reload them.&lt;/p&gt;

&lt;p&gt;Try the application by calling the new endpoints. Open a second console in PyCharm, and post a few messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;➜  guestbook $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl &lt;span class="nt"&gt;-XPOST&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt;  http://localhost:8080 &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"message": "hello", "user":"ramiro"}'&lt;/span&gt;
&lt;span class="gp"&gt;➜  guestbook $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl &lt;span class="nt"&gt;-XPOST&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt;  http://localhost:8080 &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"message": "how are you?", "user":"cindy"}'&lt;/span&gt;
&lt;span class="gp"&gt;➜  guestbook $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl &lt;span class="nt"&gt;-XPOST&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt;  http://localhost:8080 &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"message": "developing directly in my cluster!", "user":"ramiro"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And then get them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;➜  guestbook $&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl http://localhost:8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"messages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
      &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ramiro"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"how are you?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
      &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cindy"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"developing directly in my cluster!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
      &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ramiro"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;At this point, our application is feature complete, and we already tested it end to end in a fully integrated remote development environment. All that's left is to package it, send a PR, and ship it!&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;In this post we learned about the concept of remote development environments, why they are important, and how you can use Okteto and PyCharm to use them to build a Cloud Native application faster than ever. &lt;/p&gt;

&lt;p&gt;But this post only covers the surface. Using remote development environments gives you a lot of extra benefits such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eliminates the need for a local configuration.&lt;/li&gt;
&lt;li&gt;Makes it simple to share the configuration with the rest of your team.&lt;/li&gt;
&lt;li&gt;You don't need to run Docker or Kubernetes locally.&lt;/li&gt;
&lt;li&gt;You don't depend on your workstation's state.&lt;/li&gt;
&lt;li&gt;You can easily share your development environment with your team.&lt;/li&gt;
&lt;li&gt;It gives you the fastest feedback loop.&lt;/li&gt;
&lt;li&gt;You use your favorite IDEs, debuggers, etc...&lt;/li&gt;
&lt;li&gt;You can take advantage of incremental builds and hot reloaders.&lt;/li&gt;
&lt;li&gt;You are developing on an environment as similar as possible to production.&lt;/li&gt;
&lt;li&gt;You don't depend on CI/CD for validating all your changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this problem sounds familiar to you, you should check out what we have built at Okteto. Take a look at our &lt;a href="https://okteto.com/docs/tutorials/e2e/index.html"&gt;getting started guide&lt;/a&gt; and start developing at the speed of the cloud.&lt;/p&gt;

&lt;p&gt;Our mission at Okteto is to simplify the development of Cloud Native applications. Do this resonate with you? Do you have ideas, comments or feedback? Join us at the &lt;a href="https://kubernetes.slack.com/messages/CM1QMQGS0/"&gt;#okteto&lt;/a&gt; channel in the Kubernetes community Slack and share your thoughts with the community!&lt;/p&gt;

</description>
      <category>python</category>
      <category>kubernetes</category>
      <category>docker</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Build your React + Express App in Okteto Cloud</title>
      <dc:creator>Ramiro Berrelleza</dc:creator>
      <pubDate>Mon, 27 Apr 2020 21:52:12 +0000</pubDate>
      <link>https://forem.com/okteto/build-your-react-express-app-in-okteto-cloud-5g3h</link>
      <guid>https://forem.com/okteto/build-your-react-express-app-in-okteto-cloud-5g3h</guid>
      <description>&lt;p&gt;React is a JavaScript library for building user interfaces. It was originally created by Facebook, and over the years it has become one of the most broadly used frontend libraries. React is particularly powerful when building single-page or mobile apps.&lt;/p&gt;

&lt;p&gt;You can build your React frontend locally. The local development experience is one of the best there is. But is very likely that, in production, your React frontend is going to to work along with other services, like a backend, or a database. What are you going to do then? Typically you'd end up mocking the backend, or calling a staging version, rendering  your local development environments very complex...&lt;/p&gt;

&lt;p&gt;In this post I'll show how you can take advantage of the different features of &lt;a href="https://cloud.okteto.com"&gt;Okteto Cloud&lt;/a&gt; to make it easier than ever to build a React application. You can still benefit from React's local development experience, but you'll also have access to a fully integrated, production-like development environment, backend included. Hello &lt;code&gt;okteto up&lt;/code&gt;, goodbye production-only bugs 👋🏼!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you feel like skipping all the instructions, the final version of the application we are building on this post &lt;a href="https://github.com/okteto/react-express"&gt;is available here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Initial Setup
&lt;/h1&gt;

&lt;p&gt;First, install the &lt;a href="https://okteto.com/docs/getting-started/installation"&gt;Okteto CLI&lt;/a&gt;. We'll be using it to create out development environment and to build and deploy our application.&lt;/p&gt;

&lt;p&gt;MacOS / Linux&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl https://get.okteto.com &lt;span class="nt"&gt;-sSfL&lt;/span&gt; | sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Windows&lt;br&gt;
Download &lt;a href="https://downloads.okteto.com/cli/okteto.exe"&gt;https://downloads.okteto.com/cli/okteto.exe&lt;/a&gt; and add it to your &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt;



&lt;p&gt;Then, create a folder for our code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Launch your Development Environment
&lt;/h1&gt;

&lt;p&gt;One of the big advantages of using the Okteto CLI is that it gives us the ability to define and launch development environments directly in Okteto Cloud. This way, we can have all our tools and dependencies pre-installed and available for us with one command, instead of having to mess with local configuration and conflicting setups. &lt;/p&gt;

&lt;p&gt;Initialize your development environment by running the &lt;code&gt;okteto init&lt;/code&gt; command. Since we are building a React app, we'll pick the &lt;code&gt;javascript&lt;/code&gt; template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Recommended image for development with javascript: okteto/node:10
Which docker image do you want to use for your development environment? [okteto/node:10]:

 ✓  Okteto manifest (okteto.yml) created
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This command will create two files in your folder, &lt;code&gt;okteto.yml&lt;/code&gt; and &lt;code&gt;.stignore&lt;/code&gt;.  &lt;code&gt;okteto.yml&lt;/code&gt; is what tells the Okteto CLI how your development environment looks like. In this case, it's telling it that you want to use &lt;code&gt;okteto/node:10&lt;/code&gt; as the image, that your workdir is &lt;code&gt;/usr/src/app&lt;/code&gt;, and that the starting command will be &lt;code&gt;bash&lt;/code&gt;. &lt;code&gt;.stignore&lt;/code&gt; tells the Okteto CLI which files not to synchronize to your development environment (more on this later). &lt;/p&gt;

&lt;p&gt;Now that we have our manifest, let's launch our development environment. First, let's login to Okteto Cloud by running the &lt;code&gt;okteto login&lt;/code&gt; command. The command will open a browser so you can authenticate with github, and it will download your Okteto Cloud credentials and certificates. If this is the first time you use Okteto Cloud, it will also create a free account for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto login
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Authentication will continue in your default browser
You can also open a browser and navigate to the following address:
&lt;/span&gt;&lt;span class="c"&gt;...
...
&lt;/span&gt;&lt;span class="go"&gt; ✓  Logged in as rberrelleza
 ✓  Updated context 'cloud_okteto_com' in '/Users/ramiro/.kube/config'
    Run 'okteto namespace' every time you need to activate your Okteto context again.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now that we are logged in, run the &lt;code&gt;okteto up&lt;/code&gt; command to launch your development environment. Since this is the first time we launch it, we'll use the &lt;code&gt;--deploy&lt;/code&gt; argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto up &lt;span class="nt"&gt;--deploy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt; ✓  Development environment activated
 ✓  Files synchronized
    Namespace: rberrelleza
    Name:      my-app

Welcome to your development environment. Happy coding!
&lt;/span&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this, your development environment is up and running in Okteto Cloud, and you have a remote terminal to access it from (remember the &lt;code&gt;bash&lt;/code&gt; command in &lt;code&gt;okteto.yml&lt;/code&gt;?). But that's not all. &lt;code&gt;okteto up&lt;/code&gt; also keeps your local folder and your remote development environment synchronized. Any file you edit, locally or remote, will be instantly synchronized in the other side (unless it's listed on &lt;code&gt;.stignore&lt;/code&gt;).&lt;/p&gt;

&lt;h1&gt;
  
  
  Create the Initial App
&lt;/h1&gt;

&lt;p&gt;To create the initial skeleton of the application, we're going to be using &lt;a href="https://create-react-app.dev/docs/getting-started/"&gt;create-react-app&lt;/a&gt;. Run the following command on your remote development environment to build yours:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;npx create-react-app client
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;npx: installed 99 in 16.715s

Creating a new React app in /usr/src/app/client.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...
&lt;/span&gt;&lt;span class="c"&gt;...
...
...
&lt;/span&gt;&lt;span class="go"&gt;We suggest that you begin by typing:

  cd client
  yarn start

Happy hacking!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After a minute or two, the command will finish installing all the required files and dependencies. If you go ahead and open your local IDE you'll see that the files are already there, courtesy of &lt;code&gt;okteto&lt;/code&gt;'s  file synchronization capabilities.&lt;/p&gt;

&lt;p&gt;Follow the instructions in the UI (with a small addition) and start your React application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;export PORT=8080
cd client
yarn start
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When you launch your development environment in Okteto Cloud, you automatically get a public HTTPS endpoint for it, valid certificate included. All you need to do is make sure that your process starts in port 8080 (that's why I added the &lt;code&gt;export&lt;/code&gt; in the commands above). This way you can start accessing your application the same way your users are going to, from the very beginning. Get the URL of the endpoint by going to &lt;a href="https://cloud.okteto.com"&gt;Okteto Cloud&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AFer1DxO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qi2r5jkhdzvfhr6e216q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AFer1DxO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qi2r5jkhdzvfhr6e216q.png" alt="The URL of your Web App"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the URL to see your application live in Okteto Cloud!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cnszGLe0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8hu9pfk1f3s01ir400h7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cnszGLe0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8hu9pfk1f3s01ir400h7.png" alt="Your app is live!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Develop your Application
&lt;/h1&gt;

&lt;p&gt;Now that we have our initial application running, it's time to hack on it a little bit. How about we replace the React logo for Okteto's?&lt;/p&gt;

&lt;p&gt;Load the &lt;code&gt;my-app&lt;/code&gt; folder in your favorite IDE, and open &lt;code&gt;client/src/App.js&lt;/code&gt;. This is the file that has the main logic of the application. Modify it so that it uses &lt;a href="https://okteto.com/icons/icon-384x384.png"&gt;Okteto's logo&lt;/a&gt; instead of React's:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App-header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://okteto.com/icons/icon-384x384.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App-logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;Edit&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/code&amp;gt; and save to reload&lt;/span&gt;&lt;span class="err"&gt;.
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;
          &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App-link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://reactjs.org&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noopener noreferrer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;Learn&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Save the file and go to your browser. Wait for a second, and see how it automatically changes into the Okteto logo. This is the same experience you get when developing locally. But it's happening directly in your remote development environment 🧙‍♂️!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Kh9jwUXl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1rud19tytoooin19be3z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Kh9jwUXl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1rud19tytoooin19be3z.png" alt="Magic!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How did that happen?
&lt;/h2&gt;

&lt;p&gt;When you saved the file, it automatically triggered the following events:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Okteto detected the local change, and synchronized it to your remote development environment.&lt;/li&gt;
&lt;li&gt;The react dev server detected the change, and automatically regenerated the files. &lt;/li&gt;
&lt;li&gt;React use their dev websocket to automatically reload the content on your browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pretty cool no?&lt;/p&gt;

&lt;h1&gt;
  
  
  How About an API?
&lt;/h1&gt;

&lt;p&gt;Now that we have our frontend running, how about giving it an API? For this example, let's create a simple API that returns the URL of the logo, instead of having it hardcoded in the URL. &lt;/p&gt;

&lt;p&gt;We'll do our API in NodeJS, to keep things in the Javascript family. Go back to your IDE, create &lt;code&gt;server.js&lt;/code&gt; and paste the following code on it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bodyParser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;urlencoded&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://okteto.com/icons/icon-384x384.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.0.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then, create &lt;code&gt;package.json&lt;/code&gt;, and paste the content below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-express"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nodemon server.js"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"concurrently"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5.1.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"body-parser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.19.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.17.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"nodemon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.0.3"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go back to your remote terminal and stop React's web server (ctrl+c should do it). Then, go back to the workdir of your remote environment (&lt;code&gt;/usr/src/app&lt;/code&gt;) and install the required dependencies by running &lt;code&gt;yarn install&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;yarn install v1.22.4
&lt;/span&gt;&lt;span class="c"&gt;...
...
...
&lt;/span&gt;&lt;span class="go"&gt;success Saved lockfile.
Done in 54.50s.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Start your API by running &lt;code&gt;yarn start&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;yarn start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;yarn run v1.22.4
warning package.json: No license field
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;node server.js
&lt;span class="go"&gt;Listening on port 8080
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can validate that your API is doing the right thing by going back to the browser, add &lt;code&gt;/api&lt;/code&gt; to the URL and hit enter. This time, you'll get the output of the API instead of your React app since that's the process that we are currently running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xmsCAfHZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rfegd16oc32amloj78n9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xmsCAfHZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rfegd16oc32amloj78n9.png" alt="Your API running"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To run it all together, we are going to use React's &lt;a href="https://create-react-app.dev/docs/proxying-api-requests-in-development/"&gt;API proxy feature&lt;/a&gt;. This allows to both serve our static assets as well as API calls from the same server. To enable it, add the &lt;code&gt;proxy&lt;/code&gt; key to &lt;code&gt;client/package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"proxy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:3000"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are also going to add the following scripts to &lt;code&gt;package.json&lt;/code&gt; to be able to start both the react dev server and &lt;code&gt;server.js&lt;/code&gt; at the same time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nodemon server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn --cwd client start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"concurrently --kill-others-on-fail &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;PORT=3000 yarn server&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;DANGEROUSLY_DISABLE_HOST_CHECK=true yarn client&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Head back to your remote terminal, stop &lt;code&gt;server.js&lt;/code&gt; and run &lt;code&gt;yarn dev&lt;/code&gt; to start both servers this time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;yarn run v1.22.4
&lt;/span&gt;&lt;span class="c"&gt;...
...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now that be have both our React app and our API running, let's put them to work together. For this, we are going to use React's &lt;a href="https://reactjs.org/docs/react-component.html#componentdidmount"&gt;componentDidMount()&lt;/a&gt; hook to call the API right before the browser displays. To do this, update &lt;code&gt;client/src/App.js&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;  

  &lt;span class="nx"&gt;componentDidMount&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App-header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App-logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;Edit&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/code&amp;gt; and save to reload&lt;/span&gt;&lt;span class="err"&gt;.
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;
          &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App-link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://reactjs.org&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_blank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noopener noreferrer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;Learn&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go back to your browser and reload the page, to see everything working together. If you open your developer tools to inspect the requests, you will be able to see the call to our new API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Eb6Umitr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kiif1po0ohk3qrt4z188.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Eb6Umitr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kiif1po0ohk3qrt4z188.png" alt="Your app calling your API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Ship it!
&lt;/h1&gt;

&lt;p&gt;Now that our code is ready, it's time to ship it. For this, we are going to take advantage of two of Okteto Cloud's features: Okteto Build Service and the Okteto Registry.&lt;/p&gt;

&lt;p&gt;First, let's make a final change to our application to enable &lt;code&gt;production&lt;/code&gt; mode. Open &lt;code&gt;server.js&lt;/code&gt; and make the following changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bodyParser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;urlencoded&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://okteto.com/icons/icon-384x384.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Serve any static files&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;client/build&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

  &lt;span class="c1"&gt;// Handle React routing, return all requests to React app&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;client/build&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.0.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will allow our Node API to serve React's static files while in &lt;code&gt;production&lt;/code&gt; mode.&lt;/p&gt;

&lt;p&gt;Finally, create the following &lt;code&gt;Dockerfile&lt;/code&gt; to tell Okteto how to build our application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; okteto/node:10 as build&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json yarn.lock ./&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; client/package.json client/yarn.lock client/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . . &lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn &lt;span class="nt"&gt;--cwd&lt;/span&gt; client build

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PORT 8080&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_ENV production&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this, we are ready to deploy the production version of our application in Okteto Cloud. Head back to your remote terminal, stop the servers by pressing ctrl+c and exit your development environment. Then, simply run &lt;code&gt;okteto push&lt;/code&gt; to push your changes to production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto push &lt;span class="nt"&gt;--deploy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; i  Development environment deactivated
 i  Running your build in Okteto Cloud...
 ...
 ...
 ------
 &amp;gt; importing cache manifest from registry.cloud.okteto.net/rberrelleza/my-app:okteto:
------
 ✓  Source code pushed to the development environment 'my-app'

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;okteto push&lt;/code&gt; command automatically does  everything you need to fully deploy your application in Okteto Cloud. It will: push your code changes to the &lt;a href="https://okteto.com/docs/cloud/build"&gt;Okteto Build service&lt;/a&gt;, build a new container remotely, tag it,  push it to the &lt;a href="https://okteto.com/docs/cloud/registry"&gt;Okteto Registry&lt;/a&gt; and automatically deploy your application.  All of this (and more) in a single command!&lt;/p&gt;

&lt;p&gt;Once the command is finished, go back to your browser and go to Okteto Cloud. You'll notice that your application no longer has an Okteto-green icon. That's because this is the production version of your application, not just your development environment!&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrapping up
&lt;/h1&gt;

&lt;p&gt;In this post we showed you how to build a React + Express app with Okteto Cloud. We talked about the benefits of developing on a fully integrated development environment when compared with just building things locally. Then we talked about how to use Okteto CLI to initialize and deploy your remote development environment. Finally, we walked through how to use the Okteto CLI and the Okteto Build and Registry Services to build, preview and ship your application.&lt;/p&gt;

&lt;p&gt;Okteto Cloud is free for all developers. Get your own account at &lt;a href="https://cloud.okteto.com"&gt;https://cloud.okteto.com&lt;/a&gt; and start building your applications today.&lt;/p&gt;

</description>
      <category>react</category>
      <category>docker</category>
      <category>javascript</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>How to Develop and Debug ASP.NET Core Applications in Kubernetes</title>
      <dc:creator>Ramiro Berrelleza</dc:creator>
      <pubDate>Mon, 02 Mar 2020 22:41:55 +0000</pubDate>
      <link>https://forem.com/okteto/how-to-develop-and-debug-asp-net-core-applications-in-kubernetes-1bef</link>
      <guid>https://forem.com/okteto/how-to-develop-and-debug-asp-net-core-applications-in-kubernetes-1bef</guid>
      <description>&lt;p&gt;&lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; is an open-source project for automating deployment, scaling, and management of containers. It has rapidly become the standard to run production workloads and the community around it is just great!&lt;/p&gt;

&lt;p&gt;But developing in Kubernetes presents some challenges. The typical development workflow looks like this: write code, build a Docker image, push it to the registry, redeploy, validate your changes and repeat. This workflow is slow, full of friction, and makes us very unproductive.  &lt;/p&gt;

&lt;p&gt;And if you are a Windows .NET developer, then you are well aware that there are major challenges around developing applications that are meant to run in Linux containers in Windows. You can cross compile, you can dual boot, you can use WSL, etc. But those experiences are far from frictionless.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/okteto/okteto"&gt;Okteto&lt;/a&gt; was created to solve this problem. On this blog post, we will show you how Okteto improves the developer experience in Kubernetes for ASP.NET Core developers. You will be able to take full advantage of using an instant development environment, dependency caching, hot-reloading and VS Code's remote debugging features while developing your application directly in Kubernetes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Deploy the ASP.NET Core Sample App
&lt;/h2&gt;

&lt;p&gt;Get a local version of the ASP.NET Sample App by executing the following commands in your local terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git clone https://github.com/okteto/aspnetcore-getting-started
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;aspnetcore-getting-started
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;k8s.yml&lt;/code&gt; file contains the raw Kubernetes manifests to deploy the ASP.NET Core Sample App. Run the application by executing the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; k8s.yml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;deployment.apps "hello-world" created
service "hello-world" created
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is cool! You typed one command and your application just runs 😎. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can deploy to your own Kubernetes cluster or give &lt;a href="//www.okteto.com"&gt;Okteto Cloud&lt;/a&gt; a try. Okteto Cloud is a development platform for Kubernetes applications. Free developer accounts come with three Kubernetes namespaces with 8GB of RAM, 4 CPUs, and 50GB Disk space each.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 2: Install the Okteto CLI
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/okteto/okteto"&gt;Okteto CLI&lt;/a&gt; is an open-source project that lets you develop your applications directly in Kubernetes while taking advantage of well-known local tooling. We will use it to speed up our development cycle instead of using the typical development workflow based on building docker images and redeploying containers.&lt;/p&gt;

&lt;p&gt;Install the Okteto CLI:&lt;/p&gt;

&lt;p&gt;MacOS / Linux&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl https://get.okteto.com &lt;span class="nt"&gt;-sSfL&lt;/span&gt; | sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Windows&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Download https://downloads.okteto.com/cli/okteto.exe and add it to your $PATH.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 3: Start your development environment in Kubernetes
&lt;/h2&gt;

&lt;p&gt;With the ASP.NET Core sample application deployed, run the following command in your local terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto up
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt; ✓  Development environment activated
 ✓  Files synchronized
    Namespace: rberrelleza
    Name:      hello-world
&lt;/span&gt;&lt;span class="gp"&gt;    Forward:   5000 -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;5000
&lt;span class="gp"&gt;               2222 -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;22
&lt;span class="go"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;okteto up&lt;/code&gt; command starts a &lt;a href="https://okteto.com/docs/reference/development-environment/index.html"&gt;Kubernetes development environment&lt;/a&gt;, which means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ASP.NET Core Sample App container is updated with the Docker image &lt;code&gt;okteto/dotnetcore:3&lt;/code&gt;. This image is based of &lt;code&gt;mcr.microsoft.com/dotnet/core/sdk:3&lt;/code&gt;, and is preconfigured with all the required dev tools to build, test, debug and run a &lt;code&gt;dotnetcore&lt;/code&gt;-based application.&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://okteto.com/docs/reference/file-synchronization/index.html"&gt;file synchronization service&lt;/a&gt; is created to keep your changes up-to-date between your local filesystem and your application pods.&lt;/li&gt;
&lt;li&gt;Container port 5000  is forwarded to localhost.&lt;/li&gt;
&lt;li&gt;Start a terminal into the remote container. Build, test and run your application as if you were in your local machine and get your application logs immediately in your terminal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this (and more) can be customized via the &lt;code&gt;okteto.yml&lt;/code&gt; &lt;a href="https://okteto.com/docs/reference/manifest/index.html"&gt;manifest file&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To start the application, execute in the Okteto terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt; okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dotnet watch run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;watch : Polling file watcher is enabled
watch : Started
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /okteto
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Test your application by running the command below in a local terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl localhost:5000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Hello world!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Develop directly in Kubernetes
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;Controllers/HelloWorldController.cs&lt;/code&gt; in your favorite local IDE and modify the response message on line 25 to be &lt;em&gt;Hello world from the cluster!&lt;/em&gt;. Save your changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Linq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Mvc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Logging&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;helloworld.Controllers&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ApiController&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[controller]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HelloWorldController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HelloWorldController&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;HelloWorldController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HelloWorldController&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello world from the cluster!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Take a look at the Okteto terminal and notice how the changes are detected by &lt;code&gt;dotnet watch run&lt;/code&gt; and automatically built and reloaded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
watch : Exited
watch : File changed: /okteto/Controllers/HelloWorldController.cs
watch : Started
warn: Microsoft.AspNetCore.Server.Kestrel[0]
      Overriding address(es) 'https://localhost:5001, http://localhost:5000'. Binding to endpoints defined in UseKestrel() instead.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://0.0.0.0:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /okteto
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Call your application to see the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl localhost:5000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Hello world from the cluster!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice how your code changes were instantly applied to Kubernetes. No commit, build or push required 😎! &lt;/p&gt;

&lt;p&gt;Every time you make a change in a file, it will be automatically synchronized to your remote development environment, and the process will be hot reloaded automatically. Can you image  how much more productive this is going to make you?&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Debug directly in Kubernetes
&lt;/h2&gt;

&lt;p&gt;Okteto enables you to debug your applications directly from your favorite IDE. For this post, we are going to integrate &lt;a href="https://okteto.com/docs/reference/manifest/#remote-integer-optional"&gt;Okteto's remote mode&lt;/a&gt; with &lt;code&gt;vsdbg&lt;/code&gt; (the VS dotnet debugger) and VS Code's remote debugging capabilities.&lt;/p&gt;

&lt;p&gt;For this step, we are going to use the &lt;code&gt;C#&lt;/code&gt; extension for VS Code. If you don't have it, you can &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp#review-details"&gt;install it here&lt;/a&gt;.You might need to restart your VS Code instance.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;HelloWorldController.cs&lt;/code&gt; in VS Code, set a breakpoint on line &lt;code&gt;26&lt;/code&gt; and press &lt;code&gt;F5&lt;/code&gt;. VS Code will connect to your remote development environment via SSH and give you a list of processes you can attach to. Scroll through the list, and select the &lt;code&gt;helloworld&lt;/code&gt; process, as shown below (you can also type &lt;code&gt;helloworld&lt;/code&gt; in the search bar directly).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VW7OgX-r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cz6dzc8vadspatqbja82.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VW7OgX-r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cz6dzc8vadspatqbja82.png" alt="VS Code Debugger showing you the processes to attach"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you select the process, VS Code will switch to debug view, launch the debugger and attach it to the process you just selected. You'll know it's finished when the status bar at the bottom turns orange.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kaFrNLn3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fus50m5h4qgfghgka8ge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kaFrNLn3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fus50m5h4qgfghgka8ge.png" alt="VS Code Debugger attached to the remote process"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go back to the terminal and call your application again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl localhost:5000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As soon as the service receives the request the execution will halt at your breakpoint and VS Code will jump to the front of the screen. You can then inspect the request, the available variables, etc. Your code is executing in your development environment in Kubernetes, but you can debug it from your local machine without any extra services or tools. Pretty cool no? 😉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eTBJLMl5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lj99p5cqzipfag73n633.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eTBJLMl5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lj99p5cqzipfag73n633.png" alt="VS Code Debugger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How does it works?
&lt;/h3&gt;

&lt;p&gt;Your development environment is configured to automatically start an SSH server in your remote development environment, a port-forward and to add an entry to your local SSH config file when you run &lt;code&gt;okteto up&lt;/code&gt;. This allows you to use VS Code to launch a remote debugger securely, so you can develop and debug directly in your remote development environment running in Kubernetes, while coding in your favorite OS and IDE.&lt;/p&gt;

&lt;p&gt;All of this is described via &lt;code&gt;okteto.yml&lt;/code&gt; and the &lt;code&gt;launch.json&lt;/code&gt; manifests. This way, everyone collaborating in your project will get the &lt;em&gt;exact same configuration&lt;/em&gt; by simply running &lt;code&gt;okteto up&lt;/code&gt; 🤖.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;In this post we talked about how you can use Okteto to develop ASP.NET Core applications directly in Kubernetes, independently of your host OS. We showed you how to launch a fully configured remote development, how to iterate in your application, and how to validate the changes you make directly in Kubernetes. Finally, we showed you how you can leverage Okteto's remote mode together with VS Code's Remote Development extension to create a fully remote development environment directly in your Kubernetes cluster, debugger included!&lt;/p&gt;

&lt;p&gt;Okteto integrates with every stack and runs in any Kubernetes instance. Let us know what you think about it &lt;a href="https://twitter.com/oktetohq"&gt;on Twitter&lt;/a&gt;, or in &lt;a href="https://kubernetes.slack.com/messages/CM1QMQGS0/"&gt;the Okteto channel&lt;/a&gt; in the &lt;a href="http://slack.k8s.io/"&gt;Kubernetes slack&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>kubernetes</category>
      <category>microservices</category>
      <category>vscode</category>
    </item>
    <item>
      <title>How to Develop and Debug Python Applications in Kubernetes </title>
      <dc:creator>Ramiro Berrelleza</dc:creator>
      <pubDate>Fri, 31 Jan 2020 07:26:28 +0000</pubDate>
      <link>https://forem.com/okteto/how-to-develop-and-debug-python-applications-in-kubernetes-1j80</link>
      <guid>https://forem.com/okteto/how-to-develop-and-debug-python-applications-in-kubernetes-1j80</guid>
      <description>&lt;p&gt;&lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt; is an open-source project for automating deployment, scaling, and management of containers. It has rapidly become the standard to run production workloads and the community around it is just great!&lt;/p&gt;

&lt;p&gt;But developing in Kubernetes presents some challenges. The typical development workflow looks like this: write code, build a Docker image, push it to the registry, redeploy, validate your changes and repeat. This workflow is slow, and as anti-python as it could be.  Python is famous for it's quick &lt;a href="https://www.freecodecamp.org/news/this-is-why-your-read-eval-print-loop-is-so-amazing-cf0362003983/" rel="noopener noreferrer"&gt;Read-Eval-Print loop&lt;/a&gt;, after all. We don't want to give that away when bulding Cloud Native applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/okteto/okteto" rel="noopener noreferrer"&gt;Okteto&lt;/a&gt; was created to solve this problem. On this blog post, we will show you how Okteto improves the developer experience in Kubernetes for Python developers. You will be able to take full advantage of using an instant development environment, dependency caching, hot-reloading and even the PyCharm debugger while developing your application directly in Kubernetes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Deploy the Python Sample App
&lt;/h2&gt;

&lt;p&gt;Get a local version of the Python Sample App by executing the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git clone https://github.com/okteto/python-getting-started
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;python-getting-started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;k8s.yml&lt;/code&gt; file contains the Kubernetes manifests to deploy the Go Sample App. Run the application by executing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;kubectl create &lt;span class="nt"&gt;-f&lt;/span&gt; k8s.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;deployment.apps "hello-world" created
service "hello-world" created
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One command and a dev version of your application is ready to go 😎.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Install the Okteto CLI
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/okteto/okteto" rel="noopener noreferrer"&gt;Okteto CLI&lt;/a&gt; is an open-source project that lets you develop your applications directly in Kubernetes while taking advantage of your language's toolkig. We will use it to speed up our development cycle instead of using the typical development workflow based on building docker images and redeploying containers.&lt;/p&gt;

&lt;p&gt;Install the Okteto CLI:&lt;/p&gt;

&lt;p&gt;MacOS / Linux&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl https://get.okteto.com &lt;span class="nt"&gt;-sSfL&lt;/span&gt; | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Windows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Download https://downloads.okteto.com/cli/okteto.exe and add it to your `$PATH`.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Start your development environment in Kubernetes
&lt;/h2&gt;

&lt;p&gt;With the Python Sample Application deployed, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt; ✓  Development environment activated
 ✓  Files synchronized
    Namespace: rberrelleza
    Name:      hello-world
&lt;/span&gt;&lt;span class="gp"&gt;    Forward:   8080 -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;8080
&lt;span class="gp"&gt;               5678 -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;22
&lt;span class="go"&gt;    Reverse:   3500 &amp;lt;- 3500

Welcome to your development environment. Happy coding!
&lt;/span&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;okteto up&lt;/code&gt; command starts a &lt;a href="https://okteto.com/docs/reference/development-environment/index.html" rel="noopener noreferrer"&gt;Kubernetes development environment&lt;/a&gt;, which means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Python Sample App container is updated with the docker image &lt;code&gt;okteto/python:3&lt;/code&gt;. This image contains the required dev tools to build, test, debug and run the Python Sample App.&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://okteto.com/docs/reference/file-synchronization/index.html" rel="noopener noreferrer"&gt;file synchronization service&lt;/a&gt; is created to keep your changes up-to-date between your local filesystem and your application pods.&lt;/li&gt;
&lt;li&gt;Container port 8080 (the application) is forward to localhost.&lt;/li&gt;
&lt;li&gt;Container post 3500 (the debugger) is reverse forwarded to localhost.&lt;/li&gt;
&lt;li&gt;A remote shell is started in your Kubernetes development environment. Build, test and run your application as if you were in your local machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this (and more) can be customized via the &lt;code&gt;okteto.yml&lt;/code&gt; &lt;a href="https://okteto.com/docs/reference/manifest/index.html" rel="noopener noreferrer"&gt;manifest file&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello-world&lt;/span&gt;
&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;okteto/python:3&lt;/span&gt;
&lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
&lt;span class="na"&gt;workdir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/okteto&lt;/span&gt;
&lt;span class="na"&gt;forward&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8080:8080&lt;/span&gt;
&lt;span class="na"&gt;reverse&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;3500:3500&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You can also use the file &lt;code&gt;.stignore&lt;/code&gt; to skip files from &lt;a href="///docs/reference/file-synchronization/index.html"&gt;file synchronization&lt;/a&gt;. This is useful to avoid synchronizing virtual environments or git metadata.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Working in your remote development environment is the same as working on your local machine. You first create your virtual environment using the remote shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Activate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the service dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(venv)okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Collecting Click==7.0 (from -r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
&lt;/span&gt;&lt;span class="c"&gt;...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Using a virtual environment in your development environment has two great benefits: You don't need to rebuild your docker image every time you add new dependencies, and the virtual environment will be cached and restored automatically when you relaunch your development environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And then start the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(venv)okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt; Starting hello-world server...
 * Serving Flask app "app" (lazy loading)
 * Environment: debug
 * Debug mode: off
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test your application by running the command below in a local shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Hello world!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Develop directly in Kubernetes
&lt;/h2&gt;

&lt;p&gt;Open the &lt;code&gt;app.py&lt;/code&gt; file in your favorite local IDE and modify the response message on line 7 to be &lt;em&gt;Hello world from the cluster!&lt;/em&gt;. Save your changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello_world&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hello World from the cluster!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okteto will synchronize your changes to your development environment in Kubernetes. Flask's auto-reloader will detect the changes automatically and restart the application with the new code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt; * Detected change in '/okteto/app.py', reloading
 * Restarting with stat
Starting hello-world server...
 * Debugger is active!
 * Debugger PIN: 281-298-026
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Call your application from a local shell to validate the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Hello world from the cluster!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool! Your code changes were instantly applied to Kubernetes. No commit, build or push required 😎!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Debug directly in Kubernetes
&lt;/h2&gt;

&lt;p&gt;Okteto enables you to debug your applications directly from your favorite IDE. Let's take a look at how that works in one of python's most popular IDE's, &lt;a href="https://www.jetbrains.com/pycharm/" rel="noopener noreferrer"&gt;PyCharm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, open the project in PyCharm, remove the comments on &lt;code&gt;app.py&lt;/code&gt; line &lt;code&gt;20&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Starting hello-world server...&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# comment out to use Pycharm's remote debugger
&lt;/span&gt;  &lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second, launch the &lt;a href="https://www.jetbrains.com/help/pycharm/remote-debugging-with-product.html" rel="noopener noreferrer"&gt;Remote Debug Server&lt;/a&gt; by clicking on the Debug button on the top right. Ensure that the Debug Tool Window shows the &lt;code&gt;Waiting for process connection..&lt;/code&gt; message. This message will be shown until you launch your script on the remote machine, and this script will connect to the Debug Server.&lt;/p&gt;

&lt;p&gt;Finally, stop and star the service again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;(venv)okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Starting hello-world server...
 * Serving Flask app "app" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
 * Restarting with stat
Starting hello-world server...
Connecting to debugger...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On your local machine, switch to the Debug Tool Window. Once the service connects it will show the connection to the pydev debugger. Press the &lt;code&gt;resume&lt;/code&gt; button to let the execution continue.&lt;/p&gt;

&lt;p&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%2Fi%2F93w2bi42az973yzgocfr.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%2Fi%2F93w2bi42az973yzgocfr.png" alt="Debugger connected"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add a breakpoint on &lt;code&gt;app.py&lt;/code&gt;, line 10, and then call your application from your local shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The execution will halt at your breakpoint. You can then inspect the request, the available variables, etc. Your code is executing in your development environment in Kubernetes, but is being debugged on the local machine. Pretty cool no? 😉&lt;/p&gt;

&lt;p&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%2Fi%2F9zghk31txbb2vbirwk4l.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%2Fi%2F9zghk31txbb2vbirwk4l.png" alt="PyCharm Debugger breaking on a request"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How does it works?
&lt;/h3&gt;

&lt;p&gt;The PyCharm project includes a debugging configuration to start the &lt;a href="https://www.jetbrains.com/help/pycharm/remote-debugging-with-product.html" rel="noopener noreferrer"&gt;remote debug server&lt;/a&gt; and to listen for connections on &lt;code&gt;localhost:3500&lt;/code&gt;. The Okteto manifest is configured to &lt;a href="https://okteto.com/docs/reference/manifest/index.html#reverse-string-optional" rel="noopener noreferrer"&gt;start a reverse tunnel&lt;/a&gt; on port 3500 when the development environment is launched. &lt;/p&gt;

&lt;p&gt;This way, when the service it's started in your remote development environment, the connection is sent back to your local machine through the reverse tunnel, where the remote debug server receives and starts the debugging process. &lt;/p&gt;

&lt;p&gt;This configuration allows you debug your application while fully integrated in Kubernetes. And the coolest thing is that since all of this is described in your &lt;code&gt;.idea&lt;/code&gt; and Okteto manifests, everyone collaborating in your project will get the &lt;em&gt;exact same configuration&lt;/em&gt; by simply running &lt;code&gt;okteto up&lt;/code&gt; 🤖.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;Kubernetes has the potential to be a great development platform, providing replicable, resource-efficient and production-like development environments. We have shown you how to use &lt;a href="https://github.com/okteto/okteto" rel="noopener noreferrer"&gt;Okteto&lt;/a&gt; to create a development workflow that also lets you take advantage of features like incremental builds, hot reloaders or debuggers while developing your application directly in Kubernetes.&lt;/p&gt;

&lt;p&gt;Accelerate your development and start developing directly in Kubernetes today. Let us know what you think about it &lt;a href="https://twitter.com/oktetohq" rel="noopener noreferrer"&gt;on Twitter&lt;/a&gt;, or in &lt;a href="https://kubernetes.slack.com/messages/CM1QMQGS0/" rel="noopener noreferrer"&gt;the Okteto channel&lt;/a&gt; in the &lt;a href="http://slack.k8s.io/" rel="noopener noreferrer"&gt;Kubernetes slack&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>python</category>
      <category>tutorial</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Survey: Cloud Native application development</title>
      <dc:creator>Ramiro Berrelleza</dc:creator>
      <pubDate>Mon, 09 Sep 2019 20:24:46 +0000</pubDate>
      <link>https://forem.com/rberrelleza/survey-cloud-native-application-development-2108</link>
      <guid>https://forem.com/rberrelleza/survey-cloud-native-application-development-2108</guid>
      <description>&lt;p&gt;We’d like to invite you to participate in a survey we’re conducting of Cloud Native developers, users and community members. The purpose of the survey is to learn more about how you build Cloud Native applications, what you enjoy about it and the challenges that you're facing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.google.com/forms/d/e/1FAIpQLSeVAfZTARMxDuqVl_Etukgk-JstcpHhOlxE2CVd2eYNrCxvwA/viewform?usp=sf_link"&gt;Click here to participate&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Your input is important so take the survey before it closes on &lt;em&gt;Friday, September 20th&lt;/em&gt;. It only takes 2 minutes to complete. We'll be sharing the results once the survey has closed.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>cloudnative</category>
      <category>docker</category>
    </item>
    <item>
      <title>An Early Look At Helm 3</title>
      <dc:creator>Ramiro Berrelleza</dc:creator>
      <pubDate>Tue, 03 Sep 2019 23:06:20 +0000</pubDate>
      <link>https://forem.com/okteto/an-early-look-at-helm-3-l79</link>
      <guid>https://forem.com/okteto/an-early-look-at-helm-3-l79</guid>
      <description>&lt;p&gt;The first beta of Helm 3 &lt;a href="https://github.com/helm/helm/releases/tag/v3.0.0-beta.1"&gt;is now available&lt;/a&gt;! This is a particularly important milestone because it signals the finalization of &lt;em&gt;the big helm rewrite&lt;/em&gt;. From now on, the Helm team's focus will be in bug fixes and stability. Which means that we can start to build charts targeting Helm 3, right?&lt;/p&gt;

&lt;p&gt;I really wanted to try Helm 3 around, but didn't want to mess my local machine (the Helm and Helm 3 binaries are not compatible, so you need to keep separate installs, &lt;code&gt;$HELM_HOME&lt;/code&gt;and whatnots), so instead of testing it in my machine, I decided to launch a development environment in &lt;a href="https://cloud.okteto.com"&gt;Okteto Cloud&lt;/a&gt; and test everything from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launch your development environment in Okteto Cloud
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;If this is your first time using Okteto, start by installing &lt;a href="https://okteto.com/docs/getting-started/installation/index.html"&gt;the Okteto CLI&lt;/a&gt;. We'll need it to launch the development environment into Okteto Cloud.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We'll start by initializing &lt;a href="https://okteto.com/docs/reference/development-environment/index.html"&gt;our development environment&lt;/a&gt;, using the &lt;code&gt;okteto init&lt;/code&gt; command to create our manifest (this tells Okteto what kind of development environment to launch). Since we are working on an empty directory, &lt;code&gt;okteto&lt;/code&gt; will ask us to pick a runtime. Pick the first one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;helm3
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;helm3
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now that we have our development environment defined, we need to configure our local environment to work with Okteto Cloud. &lt;/p&gt;

&lt;p&gt;First, run the &lt;code&gt;okteto login&lt;/code&gt; command to create your Okteto Cloud account and link it to your local computer (you only need to do this once per computer).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto login 
&lt;span class="go"&gt; ✓  Logged in as rberrelleza
    Run `okteto namespace` to activate your download your Kubernetes credeentials.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Second, run the &lt;code&gt;okteto namespace&lt;/code&gt; command to download the Kubernetes credentials for Okteto Cloud, and to set it as our current context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto namespace 
&lt;span class="go"&gt; ✓  Updated context 'cloud_okteto_com' in '/Users/ramiro/.kube/config'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we are ready to go! Run the &lt;code&gt;okteto up&lt;/code&gt; command to launch our development environment directly into Okteto Cloud:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;okteto up
&lt;span class="go"&gt;
Deployment okteto-helm3 doesn't exist in namespace rberrelleza. Do you want to create a new one? [y/n]: y
 ✓  Persistent volume provisioned
 ✓  Files synchronized
 ✓  Okteto Environment activated
    Namespace: rberrelleza
    Name:      okteto-helm3

Welcome to your development environment. Happy coding!
&lt;/span&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;okteto up&lt;/code&gt; command launches a development environment in Okteto Cloud, keeps your code synchronized between your development environment and your local machine and automatically opens a shell into the development environment for you. From now on we'll be running all the commands &lt;em&gt;directly in our remote development environment&lt;/em&gt; (note the &lt;code&gt;okteto&amp;gt;&lt;/code&gt; bash symbol in the code samples 😎).&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Helm 3 in the development environment
&lt;/h2&gt;

&lt;p&gt;Download the v3.0.0-beta.1 release from github, and install it in &lt;code&gt;/usr/bin/local&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;wget https://get.helm.sh/helm-v3.0.0-beta.1-linux-amd64.tar.gz &lt;span class="nt"&gt;-O&lt;/span&gt; /tmp/helm-v3.0.0-beta.1-linux-amd64.tar.gz
&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xvzf&lt;/span&gt; /tmp/helm-v3.0.0-beta.1-linux-amd64.tar.gz &lt;span class="nt"&gt;-C&lt;/span&gt; /tmp 
&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;mv&lt;/span&gt; /tmp/linux-amd64/helm /usr/local/bin/helm
&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/bin/helm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;helm version&lt;/code&gt; to make sure everything is OK (We are dealing with beta software, after all).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;helm version
&lt;span class="go"&gt;version.BuildInfo{Version:"v3.0.0-beta.1", GitCommit:"f76b5f21adb53a85de8925f4a9d4f9bd99f185b5", GitTreeState:"clean", GoVersion:"go1.12.9"}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploying our first chart
&lt;/h2&gt;

&lt;p&gt;To keep exploring Helm 3, we are going to create a simple chart by running &lt;code&gt;helm create&lt;/code&gt;. This command creates a chart with a deployment of an NGINX container and its corresponding service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;helm create hello-world
&lt;span class="go"&gt;Creating hello-world
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Deploy your chart by running the &lt;code&gt;helm install&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;helm &lt;span class="nb"&gt;install &lt;/span&gt;hello-world ./hello-world
&lt;span class="go"&gt;NAME: hello-world
LAST DEPLOYED: 2019-08-29 23:01:17.851466604 +0000 UTC m=+0.128796294
NAMESPACE: rberrelleza
STATUS: deployed
&lt;/span&gt;&lt;span class="c"&gt;....
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can then run &lt;code&gt;helm list&lt;/code&gt; to see all the installed releases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;helm list
&lt;span class="go"&gt;NAME                    NAMESPACE   REVISION    UPDATED                                 STATUS      CHART
hello-world             rberrelleza 1           2019-08-29 23:06:40.982957007 +0000 UTC deployed    hello-world-0.1.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;When you launch a development environment in Okteto Cloud, a set of credentials is automatically created for you. The credentials are automatically mounted on your development environment, so you can start using tools like &lt;code&gt;helm&lt;/code&gt; or &lt;code&gt;kubectl&lt;/code&gt; without requiring extra configuration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of having to run a port-forward to our local machine, we will let Okteto Cloud &lt;a href="https://okteto.com/docs/cloud/ssl.html"&gt;automatically create a publicly accessible SSL endpoint&lt;/a&gt; for our application by annotating the service with &lt;code&gt;dev.okteto.com/auto-ingress=true&lt;/code&gt;. The chart created by &lt;code&gt;helm create&lt;/code&gt; doesn't support annotations, so we'll just use &lt;code&gt;kubectl annotate&lt;/code&gt; directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;kubectl annotate service hello-world dev.okteto.com/auto-ingress&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="go"&gt;service/hello-world annotated
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's open our browser and head out to &lt;a href="https://cloud.okteto.com"&gt;Okteto Cloud&lt;/a&gt; to see the application's endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UKzLtbVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/y4uzj6usnp2nujamfr0v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UKzLtbVf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/y4uzj6usnp2nujamfr0v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's go ahead and cick on the URL to see our application up and running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c5r8pNLf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/13ycvy0r17h0aowy70wc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c5r8pNLf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/13ycvy0r17h0aowy70wc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Helm 3.0.0-beta.1 can't install charts from a repository due to &lt;a href="https://github.com/helm/helm/issues/6287"&gt;#6287&lt;/a&gt;. It'll be fixed in the next beta release.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Upgrading the chart
&lt;/h2&gt;

&lt;p&gt;Let's change the boring "Welcome to nginx page!" with something with more flair. We'll upgrade our chart and change the container image from &lt;code&gt;nginx&lt;/code&gt; to &lt;code&gt;ramiro/hello&lt;/code&gt; using the &lt;code&gt;helm upgrade&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;helm upgrade &lt;span class="nt"&gt;--set&lt;/span&gt; image.repository&lt;span class="o"&gt;=&lt;/span&gt;ramiro/hello hello-world ./hello-world
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;helm list&lt;/code&gt; to see the state of the release. Notice how the value of &lt;code&gt;revision&lt;/code&gt; changed from &lt;code&gt;1&lt;/code&gt; to &lt;code&gt;2&lt;/code&gt; to indicate that a new version was deployed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;helm list
&lt;span class="go"&gt;NAME        NAMESPACE   REVISION    UPDATED                                 STATUS      CHART
hello-world rberrelleza 2           2019-08-30 00:05:57.204015932 +0000 UTC deployed    hello-world-0.1.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go back to your browser, reload the page, and verify that it was correctly upgraded 🐶.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleanup
&lt;/h2&gt;

&lt;p&gt;Use the &lt;code&gt;helm uninstall&lt;/code&gt; command to uninstall the chart and remove all the related resources.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;okteto&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;helm uninstall hello-world
&lt;span class="go"&gt;release "hello-world" uninstalled
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once you're done playing with your development environment, exit the terminal and run the &lt;code&gt;okteto down&lt;/code&gt; command to shut it down. But don't worry, all the files you created there (like the chart) were automatically synchronized back to your local machine.&lt;/p&gt;

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

&lt;p&gt;I'm really excited about Helm 3. The team managed to keep all the good things about it (repeatable installations, manifest-driven approach, easy to share charts, same commands) while removing the need to have a central service to keep all the state (buh bye &lt;code&gt;Tiller&lt;/code&gt;!). Can't wait to get my hands on the final version!&lt;/p&gt;

&lt;p&gt;Ephemeral development environments are a great way to keep different tech stacks from messing with each other, or to quickly try out beta software without "polluting" our machine. Making them super easy to use for everyone is one of our main motivations with building Okteto. &lt;/p&gt;

&lt;p&gt;I would ❤️ to hear what &lt;a href="https://twitter.com/intent/tweet?text=%40oktetohq%20I%20think%20that%20development%20environments..."&gt;you think about this feature&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>helm</category>
      <category>kubernetes</category>
      <category>cloudnative</category>
    </item>
    <item>
      <title>How to develop a serverless app with OpenFaaS and Okteto</title>
      <dc:creator>Ramiro Berrelleza</dc:creator>
      <pubDate>Tue, 13 Aug 2019 05:01:04 +0000</pubDate>
      <link>https://forem.com/okteto/how-to-develop-a-serverless-app-with-openfaas-and-okteto-240g</link>
      <guid>https://forem.com/okteto/how-to-develop-a-serverless-app-with-openfaas-and-okteto-240g</guid>
      <description>&lt;h3&gt;
  
  
  How to Develop a Serverless App with OpenFaaS and Okteto
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qVFQNrhm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AQ5JCUZlucY-FikYWj6o_Zw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qVFQNrhm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AQ5JCUZlucY-FikYWj6o_Zw.jpeg" alt=""&gt;&lt;/a&gt;Okteto + OpenFaas&lt;/p&gt;

&lt;p&gt;OpenFaaS (Functions as a Service) is a framework for building serverless functions with Docker and Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.openfaas.com/"&gt;OpenFaaS&lt;/a&gt; simplifies your application by helping you package your application logic in discrete packages that react to web events. Instead of having to deploy tens of pods to keep your application running at scale, OpenFaaS scales your functions automatically and independently based on web events and metrics.&lt;/p&gt;

&lt;p&gt;On this blog post we'll show you how to deploy your own instance of OpenFaaS, launch your first function and how to develop it. Then we'll show you how you can use the Okteto CLI to accelerate your serverless development even more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy OpenFaaS in Okteto Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;If you already have your own installation of OpenFaaS, feel free to skip to the next step.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For this post, we'll deploy OpenFaaS into &lt;a href="https://cloud.okteto.com"&gt;Okteto Cloud&lt;/a&gt;. Okteto Cloud is a &lt;a href="https://okteto.com/docs/cloud"&gt;self-service, multi-tenant Kubernetes cluster&lt;/a&gt; optimized for team collaboration and Cloud Native development.&lt;/p&gt;

&lt;p&gt;Log in to &lt;a href="https://cloud.okteto.com"&gt;Okteto Cloud&lt;/a&gt; and click on the Deploy button. Switch the deploy method to &lt;strong&gt;Deploy from Helm Chart&lt;/strong&gt;, select OpenFaaS, pick a password, and click deploy.  Your OpenFaaS instance will be up and running in a matter of seconds.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EdryJPq9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hl48fjdbmtd752bdc3in.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EdryJPq9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hl48fjdbmtd752bdc3in.png" alt="Deploy OpenFaaS in okteto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenFaaS includes a web gateway as part of the deployment, which can be used to see your functions, create new ones, and to invoke them. Okteto Cloud automatically created an ingress for your OpenFaaS gateway. Open &lt;a href="https://cloud.okteto.com"&gt;Okteto Cloud&lt;/a&gt; in your browser and click on the gateway URL to access it.&lt;/p&gt;

&lt;p&gt;When opening the gateway the first time you will be prompted for credentials. The user is admin and the password will be the content of the &lt;code&gt;Password&lt;/code&gt; field you provided in the deployment dialog (it defaults to &lt;code&gt;Password123!&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VNo6CGTa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3oc3vxea7c05zuo4zvr5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VNo6CGTa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3oc3vxea7c05zuo4zvr5.png" alt="The Gateway UI via Okteto"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Install the OpenFaaS CLI
&lt;/h3&gt;

&lt;p&gt;We need the OpenFaaS CLI available locally to deploy a function. If you are in Mac or Linux, run the command below to install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -sL cli.openfaas.com | sudo sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;On Windows download the latest faas-cli.exe from the &lt;a href="https://github.com/openfaas/faas-cli/releases"&gt;releases page&lt;/a&gt; and place it somewhere in you $PATH.&lt;/p&gt;

&lt;p&gt;Validate that it was installed correctly by opening a terminal and running:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ faas-cli help
$ faas-cli version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;To access the OpenFaaS gateway from the CLI, you need to export the &lt;code&gt;$OPENFAAS_URL&lt;/code&gt; and &lt;code&gt;$OPENFAAS_PASSWORD&lt;/code&gt; environment variables (you can get your gateway's URL from &lt;a href="https://cloud.okteto.com"&gt;Okteto Cloud's&lt;/a&gt;) and login using the faas-cli login command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export OPENFAAS_URL=$OPENFAAS_GATEWAY_URL
export OPENFAAS_PASSWORD="Password123!"
$ echo $OPENFAAS_PASSWORD | faas-cli login -u admin --password-stdin

Calling the OpenFaaS server to validate the credentials...
credentials saved for admin https://gateway-rberrelleza.cloud.okteto.net
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Deploy your first function
&lt;/h3&gt;

&lt;p&gt;Now that we have our instance of OpenFaaS, it’s time to deploy our first function.&lt;/p&gt;

&lt;p&gt;OpenFaaS supports pretty much any programming language, but since I'm a huge golang fan, we'll use that for this post. Use the &lt;code&gt;faas-cli&lt;/code&gt; new command to create all the necessary files.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ faas-cli new -lang go gohash
...
  ___                   _____           ____
 / _ \ _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 \___/| .__/ \___|_| |_|_|  \__,_|\__,_|____/
      |_|Function created in folder: gohash
Stack file written: gohash.yml
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We now have a folder called gohash with a file called &lt;code&gt;handler.go&lt;/code&gt;, this is the main code of our function. We also have a file called &lt;code&gt;gohash.yml&lt;/code&gt; with the function metadata, and a folder called template with the different function templates available.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;gohash.yml&lt;/code&gt; with your favorite text editor and put your Docker Hub account into the &lt;code&gt;image:&lt;/code&gt; section. i.e. &lt;code&gt;image: okteto/gohash:latest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, run the faas-cli up command to build, push and deploy your function.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The faas-cli up command uses your local Docker client to build and push the images. It requires you to be logged to Docker Hub or a similar registry.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ faas-cli up -f gohash.yml
[0] &amp;gt; Building gohash.
...
[0] &amp;lt; Building gohash done.
[0] worker done.

[0] &amp;gt; Pushing gohash [ramiro/gohash:latest].
...
[0] &amp;lt; Pushing gohash [ramiro/gohash:latest] done.
[0] worker done.

Deploying: gohash.

Deployed. 202 Accepted.
URL: https://gateway-openfaas-rberrelleza.cloud.okteto.net/function/gohash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Once your function has been deployed, we'll use the gateway's UI to invoke it. Open the gateway in your browser, click on the gohashon the left, type testas the Request body, and click the _Invoke _button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1k7cK29A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AX4w2Z2YOqM6hZDUqksVuTA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1k7cK29A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AX4w2Z2YOqM6hZDUqksVuTA.png" alt=""&gt;&lt;/a&gt;Your first OpenFaaS function&lt;/p&gt;
&lt;h3&gt;
  
  
  Develop your function
&lt;/h3&gt;

&lt;p&gt;Once our function is up and running, let's add a simple feature. Instead of just echoing back the input, we'll calculate the checksum of the string and return that instead.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;gohash/handler.go&lt;/code&gt; with your favorite editor, and update it:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Save the file, and build , push and deploy your function with the faas-cli up command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ faas-cli up -f gohash.yml
...
...
Deployed. 202 Accepted.
URL: https://gateway-rberrelleza.cloud.okteto.net/function/gohash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Wait 30 seconds, go back to the gateway's UI and invoke the function again to verify your code change:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WFEOndWw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ADBFy15YsTVbQVJWrEAIdKQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WFEOndWw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ADBFy15YsTVbQVJWrEAIdKQ.png" alt=""&gt;&lt;/a&gt;Result of the function after adding the checksum&lt;/p&gt;

&lt;p&gt;You'll need to edit the &lt;code&gt;handler.go&lt;/code&gt; file and run faas-cli up every time you want to deploy a new change.&lt;/p&gt;
&lt;h3&gt;
  
  
  Develop your function, Cloud Native style
&lt;/h3&gt;

&lt;p&gt;OpenFaaS offers you a great experience when building functions (way better and AWS Lambda and GCP's Cloud Functions, in my opinion), but having to build, push and redeploy every time you want to change a line of code adds a lot of friction to my inner loop.&lt;/p&gt;

&lt;p&gt;What if instead of building, pushing and deploying, we take advantage of &lt;a href="https://okteto.com"&gt;Okteto&lt;/a&gt; and develop our function directly in the cluster, Cloud Native style?&lt;/p&gt;

&lt;p&gt;Okteto uses &lt;a href="https://okteto.com/docs/reference/manifest/index.html"&gt;a manifest&lt;/a&gt; to know how to build and deploy your development environment. Create an file called gohash/okteto.yml, with the following content:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: go-dev
image: okteto/openfaas:golang
mountpath: /go/src/handler/function
command: ["bash"]
securityContext:
 fsGroup: 100
services:
 - name: gohash
 mountpath: /home/app/src
 environment:
 - fprocess=src/handler
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Go to your terminal, navigate to the gohash folder and run the okteto up command to start your remote development environment:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd gohash
$ okteto up

Deployment 'go-dev' doesn't exist. Do you want to create a new one? [y/n]: y
 ✓ Persistent volume provisioned
 ✓ Files synchronized
 ✓ Okteto Environment activated
 Namespace: rberrelleza
 Name: go-dev

Welcome to your development environment. Happy coding!
okteto&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Build and install the binary in your remote environment:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;okteto&amp;gt; go install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;If you want to use go build instead, call it like this: &lt;code&gt;go build -o /go/src/handler/function&lt;/code&gt; for OpenFaaS to pick it up the changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Go back to the browser, and test the function again:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--67zn4MJV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A1_7pwxX8ZJcGp6ucg85KTw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--67zn4MJV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A1_7pwxX8ZJcGp6ucg85KTw.png" alt=""&gt;&lt;/a&gt;Result of the function running with Okteto&lt;/p&gt;

&lt;p&gt;Now, let's implement a second feature: We'll include a timestamp in the response. Open &lt;code&gt;gohash/handler.go&lt;/code&gt;.go with your favorite editor and update it:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Save your file, go back to your terminal, and build your function again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;okteto&amp;gt; go install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go back to your browser, and test your function again:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vh3Ib-QI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A8wtFESfxpG529JQec3qt6A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vh3Ib-QI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A8wtFESfxpG529JQec3qt6A.png" alt=""&gt;&lt;/a&gt;Result of the function after adding the timestamp&lt;/p&gt;

&lt;p&gt;Our change made it to the function! How did this happen? With Okteto your changes were automatically applied to the remote containers as soon as you saved them. This way you can execute native go builds, leveraging golang's caches and incremental builds to see your changes in seconds. No commit, build, push or redeploy required 💪!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Once you're done developing, run okteto down to return everything to the previous state.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Whoa, how does it works?
&lt;/h3&gt;

&lt;p&gt;When you run &lt;code&gt;okteto up&lt;/code&gt;, Okteto enables what we call &lt;em&gt;development mode&lt;/em&gt;. Development Mode is what enables you to test your changes directly in the cluster, instead of having to build, push and redeploy.&lt;/p&gt;

&lt;p&gt;After running &lt;code&gt;okteto up&lt;/code&gt; the following events happen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Okteto creates a persistent volume on Okteto Cloud.&lt;/li&gt;
&lt;li&gt;A bi-directional synchronization service is started between your local machine and the persistent volume.&lt;/li&gt;
&lt;li&gt;Okteto launches your development environment, using the image you defined in your okteto.yml, with your persistent volume mounted. The deployment will use the image defined in your manifest. In this case, we are using &lt;code&gt;okteto/openfaas:golang&lt;/code&gt;, an image that has all the tools you need to develop golang-based functions already preinstalled.&lt;/li&gt;
&lt;li&gt;Okteto relaunches all the deployments defined in the services section of your manifest (in this case, your function). The deployment is slightly modified to have your persistent volume mounted in &lt;code&gt;mountpath&lt;/code&gt;, and the environment variable &lt;code&gt;fprocess&lt;/code&gt; injected.&lt;/li&gt;
&lt;li&gt;A shell was opened into your development environment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EZSMECAM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AWxkSwFKdGOVBlAMrSWt0cA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EZSMECAM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AWxkSwFKdGOVBlAMrSWt0cA.jpeg" alt=""&gt;&lt;/a&gt;Your function in Okteto's development mode&lt;/p&gt;

&lt;p&gt;Every time you change a file (e.g when you add the timestamp code), the code is synchronized between your machine and your remote environment. And every time you compile your go binary, the updated version is available both in your development environment and in your function's deployment (since they both share the same volume).&lt;/p&gt;

&lt;p&gt;This is the 'magic' that allows you to validate your changes directly in the cluster, no commit, build, push or redeploy required. &lt;a href="https://kubernetes.slack.com/messages/CM1QMQGS0/"&gt;Join us on slack&lt;/a&gt; to talk more about Okteto's features, architecture, and use cases!&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;We just built and deployed our first function in OpenFaaS in minutes.&lt;/p&gt;

&lt;p&gt;OpenFaaS makes it simple to turn anything into a serverless function that runs on Linux or Windows through Kubernetes. &lt;a href="https://openfaas.com"&gt;Learn more about OpenFaaS here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And then, we used &lt;a href="https://okteto.com"&gt;Okteto&lt;/a&gt; to show you the advantages of developing directly in Kubernetes while keeping the same developer experience than working on a local machine. By developing directly in the cluster you not only gain speed, you also avoid the burden of having to keep Kubernetes and OpenFaaS running in your local machine.&lt;/p&gt;

&lt;p&gt;Working on the Cloud is always better. You don’t work on your spreadsheets and listen to media files locally, do you? Stop dealing with local environments and &lt;a href="https://okteto.com"&gt;become a Cloud Native Developer&lt;/a&gt; today!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Interested in boosting your team's Kubernetes development workflows? &lt;a href="https://okteto.com/#sales"&gt;Contact us&lt;/a&gt; to start running Okteto Enterprise in your own infrastructure today.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>serverless</category>
      <category>cloudcomputing</category>
      <category>programming</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Develop a Django + Celery app in Kubernetes</title>
      <dc:creator>Ramiro Berrelleza</dc:creator>
      <pubDate>Thu, 27 Jun 2019 14:26:15 +0000</pubDate>
      <link>https://forem.com/okteto/develop-a-django-celery-app-in-kubernetes-3apk</link>
      <guid>https://forem.com/okteto/develop-a-django-celery-app-in-kubernetes-3apk</guid>
      <description>&lt;h3&gt;
  
  
  Develop a Django + Celery App in Kubernetes
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://djangoproject.com/"&gt;Django&lt;/a&gt; + &lt;a href="http://www.celeryproject.org/"&gt;Celery&lt;/a&gt; is probably the most popular solution to develop websites that require running tasks in the background. Developing a Django + Celery app locally is complex, as you need to run different services: Django, Celery worker, Celery beat, Redis, databases… &lt;a href="https://docs.docker.com/compose/"&gt;docker-compose&lt;/a&gt; is a very convenient tool in this case. You can spin up your local environment with docker-compose in just one single command. And thanks to the use of volume mounts, you are able to hot reload your application in seconds.&lt;/p&gt;

&lt;p&gt;In this blog post, we want to go a step forward and explain why you should develop your Django + Celery app directly in Kubernetes. The benefits are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce integration issues by developing in a more production-like environment, consuming Kubernetes manifests, secrets, volumes or config maps from development.&lt;/li&gt;
&lt;li&gt;Overcome local development limitations. You will be able to develop against any Kubernetes cluster, local or remote. And having a lot of microservices makes it harder and harder to run the entire development environment locally.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it is well-known that developing in Kubernetes is tedious. Let’s explore together how to develop in Kubernetes the &lt;strong&gt;Cloud Native way&lt;/strong&gt; 💥💥💥💥.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy the Django + Celery Sample App
&lt;/h3&gt;

&lt;p&gt;Get a local version of the Django + Celery Sample App by executing the following commands in your local terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/okteto/math
$ cd math
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The Django + Celery Sample App is a multi-service application that calculates math operations in the background. It consists of a web view, a worker, a queue, a cache, and a database.&lt;/p&gt;

&lt;p&gt;Execute the command below to deploy the application in your Kubernetes cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl apply -f manifests
statefulset.apps "cache" created
service "cache" created
statefulset.apps "db" created
service "db" created
statefulset.apps "queue" created
service "queue" created
deployment.apps "web" created
service "web" created
deployment.apps "worker" created
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Wait for a few seconds for the app to be ready. Check that all pods are ready by executing the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get pod
NAME READY STATUS RESTARTS AGE
cache-0 1/1 Running 0 2m
db-0 1/1 Running 0 2m
queue-0 1/1 Running 0 2m
web-7bccc4bc99-2nwtc 1/1 Running 0 2m
worker-654d7b8bd5-42rq2 1/1 Running 0 2m
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Efficient Kubernetes Development with Okteto
&lt;/h3&gt;

&lt;p&gt;Now that we have the Django + Celery Sample App running in a Kubernetes cluster, we can use it as our development environment. When working in Kubernetes, you would have to rebuild your docker images, push them to a registry and redeploy your application every time you want to test a code change. This cycle is complex and time-consuming. It sounds like a bad idea to kill your productivity this way.&lt;/p&gt;

&lt;p&gt;If you are familiar with docker-compose, you know how useful is to mount local folders into your containers to avoid the docker build/push/redeploy cycle. Volume mounts are a game changer for developing Docker applications and they are the missing piece to speed up your Kubernetes development cycle.&lt;/p&gt;

&lt;p&gt;We developed &lt;a href="https://github.com/okteto/okteto"&gt;Okteto&lt;/a&gt; to solve this problem. To give you all the good parts of using docker-compose when developing while moving your development into your Kubernetes cluster. Okteto is open source, and the code is &lt;a href="https://github.com/okteto/okteto"&gt;available in github&lt;/a&gt;. Feel free to check it out, contribute, and star it 🤗!&lt;/p&gt;

&lt;p&gt;To install the Okteto CLI in your computer, follow the &lt;a href="https://github.com/okteto/okteto/blob/master/docs/installation.md"&gt;installation instructions&lt;/a&gt; and check that it is properly installed by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ okteto version
okteto version 1.8.18
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Okteto CLI &amp;gt;= 1.8.18 is required to follow this tutorial.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In order to start developing the Django + Celery Sample App, execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ okteto up
✓ Files synchronized
✓ Okteto Environment activated
 Namespace: pchico83
 Name: web
 Forward: 8080 -&amp;gt; 8080

curl: (52) Empty reply from server
Database is ready
No changes detected in app ‘myproject’
Created migrations
Operations to perform:
Apply all migrations: auth, contenttypes, myproject, sites
Running migrations:
No migrations to apply.
Migrated DB to latest version
Performing system checks…
System check identified no issues (0 silenced).
June 26, 2019–11:00:02
Django version 1.11.21, using settings ‘myproject.settings’
Starting development server at http://0.0.0.0:8080/
Quit the server with CONTROL-C.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s have a look at the &lt;code&gt;okteto.yml&lt;/code&gt; file to understand what the okteto up command does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: web
command: ./run_web.sh
sync:
  - .:/app
services:
  - name: worker
    command: ./run_celery.sh
    sync:
      - .:/app
forward:
  - 8080:8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;okteto up&lt;/code&gt; synchronizes your local source code to the containers of the deployment &lt;em&gt;web&lt;/em&gt; and &lt;em&gt;worker&lt;/em&gt;. Your source code is synchronized to the container path &lt;em&gt;/app&lt;/em&gt;. Also, the port 8080 is automatically forwarded between your development container and your computer. If you want to know more about how Okteto works, follow this &lt;a href="https://github.com/okteto/okteto/blob/master/docs/how-does-it-work.md"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let’s Write some Code and Fix a Bug
&lt;/h3&gt;

&lt;p&gt;Verify that the application is up and running by opening your browser and navigating to &lt;a href="http://localhost:8080/jobs/"&gt;http://localhost:8080/jobs/&lt;/a&gt;. Go ahead and calculate the &lt;em&gt;fibonacci&lt;/em&gt; for the number 5:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rxWYsjCD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AmEeMsXH3n_jsvQ_1IMviZg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rxWYsjCD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AmEeMsXH3n_jsvQ_1IMviZg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press the &lt;em&gt;POST&lt;/em&gt; button to submit the operation. The response payload will include the url of the job. Go to &lt;a href="http://localhost:8080/jobs/1/"&gt;http://localhost:8080/jobs/1/&lt;/a&gt; and you will notice that the result is wrong (&lt;em&gt;hint: the fibonacci number of 5 is not 32&lt;/em&gt;). This is because our worker has a bug 🙀!&lt;/p&gt;

&lt;p&gt;Typically, fixing this would involve you running the app locally, fixing the bug, building a new container, pushing it and redeploying your app. Instead, we’re going to do it the &lt;strong&gt;Cloud Native way&lt;/strong&gt; &lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;myproject/myproject/models.py&lt;/code&gt; in your favorite local IDE. Take a look at the value of the task variable in line 29. It looks like someone hard-coded the name of the operation instead of reading it from the job. Let's fix it by changing it to &lt;code&gt;self.type&lt;/code&gt; , as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;task = TASK_MAPPING[‘power’]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;task = TASK_MAPPING[self.type]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Save your file and go back to &lt;a href="http://localhost:8080/jobs/,"&gt;http://localhost:8080/jobs/.&lt;/a&gt; Submit a new &lt;em&gt;fibonacci&lt;/em&gt; calculation for the same values as before. Go to &lt;a href="http://localhost:8080/jobs/2/"&gt;http://localhost:8080/jobs/2/&lt;/a&gt; and verify the result. The result looks correct this time, success!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vOO_kcLK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A_-wSVERUQj5tDdugQ7jPtg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vOO_kcLK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A_-wSVERUQj5tDdugQ7jPtg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How did this happen? With Okteto your changes were automatically applied to the remote containers as soon as you saved them. No commit, build, push or redeploy required 💪!&lt;/p&gt;

&lt;p&gt;Okteto can be used in local Kubernetes installations, but why would you limit yourself to develop locally when you can develop at the speed of the cloud? Developing in the cloud have several advantages, among others:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The cloud offers faster hardware.&lt;/li&gt;
&lt;li&gt;Your company might deploy a few services to make them available to every development environment, like a Kafka instance or a company Identity Service.&lt;/li&gt;
&lt;li&gt;Consume infrastructure services like Elasticsearch or Prometheus from development to boost debugging.&lt;/li&gt;
&lt;li&gt;Share your development environment endpoints with the rest of your team for fast validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Every developer should work in an isolated namespace, sharing the same Kubernetes cluster. Okteto Enterprise takes care of setting Roles, Network Policies, Pod Security Policies, Quotas, Limit Ranges and all the other tedious work needed to provide controlled access by several developers to the same Kubernetes cluster. If you want to give it a try, follow our &lt;a href="https://okteto.com/docs/getting-started/"&gt;getting started guide&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Cleanup
&lt;/h3&gt;

&lt;p&gt;Cancel the okteto up command by pressing Ctrl + C and run the following commands to remove the resources created by this guide:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ okteto down -v
✓ Okteto Environment deactivated

$ kubectl delete -f manifests
statefulset.apps "cache" deleted
service "cache" deleted
statefulset.apps "db" deleted
service "db" deleted
statefulset.apps "queue" deleted
service "queue" deleted
deployment.apps "web" deleted
service "web" deleted
deployment.apps "worker" deleted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;We have shown the advantages of developing directly in Kubernetes while keeping the same developer experience than working on a local machine. Working on the Cloud is always better. You don’t work on your spreadsheets and listen to media files locally, do you? Stop dealing with local environments and &lt;a href="https://okteto.com"&gt;become a Cloud Native Developer&lt;/a&gt; today!&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>django</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
