Purple white and red flowers.
Our garden is growing. We've raised a Series A funding round.
Read more here

Remocal development: The best of local and remote Kubernetes dev environments

James Walker
James Walker
March 14, 2023

Kubernetes has transformed how containerized applications are deployed and managed in production. However, developing these systems is still fraught with problems. Engineers have to step through complex manual processes to replicate live infrastructure locally or cope with bottlenecks and delays when testing changes in remote environments.

Both approaches add friction and require regular context switches. To maximize delivery velocity, you need a self-service development experience that's quick to start, easy to iterate upon, and closely matched to production's characteristics.

In this article, you'll learn how remocal development tools like Garden solve these challenges by blending the best of both local and remote workflows.

The current situation: Cumbersome DX creates bugs and fears

The software delivery pipeline has grown increasingly complex as new tools and processes have become commonplace. Most systems require multiple build, test, and review steps before code can be shipped to production. When it reaches a live environment, code is often deployed as containers in distributed systems. These require special infrastructure to operate.

The DevOps transition has increased software quality, but the developer experience hasn't kept up. Local dev environments are fast, responsive, and quick to iterate upon, but they often lack the full toolchain that's used in your CI/CD pipeline. This can mean problems aren't found until after developers have pushed their work.

In addition, local tools can substantially differ from their production counterparts. These disparities are a constant source of bugs and frustration, forcing devs to debug production issues that they never encountered during the build process.

Teams have learned to cope with these problems by moving the core of their workflow logic into continuous integration, continuous delivery (CI/CD) pipelines. This way, everyone on the team pushes code through the same set of procedures, helping reduce discrepancies between environments. You can use remote development techniques to perform on demand to deploy code into staging zones that run alongside production infrastructure.

However, this method carries its own drawbacks. The pipeline becomes the only way to build, test, and deploy, which can be a serious development hindrance. Even the most optimized pipelines often take several minutes to complete, creating long feedback loops that slow down engineering efforts. Making changes to pipelines is tedious as you have to wait for all jobs to finish before new effects become apparent.

Consequently, most teams end up with an unstructured mix of local and remote tooling. Neither approach is perfect, with both presenting significant usability difficulties. Devs need to understand how to set up their environment so it mimics production, while DevOps engineers have to painstakingly adjust CI pipelines to accommodate change and improve performance.

Do you really need localhost?

All the problems mentioned previously are contributing to the decline of localhost as the default way to build and test. Moving away from localhost has several benefits for developers and DevOps alike and ensures that identical processes are being used for both development and CI.

Localhost causes discrepancies

By removing localhost, developers on specific tools being correctly configured on their machines. Adopting remote environments means you can access familiar workspaces wherever you happen to be, either on your laptop at home or a PC in the office.

Organizations can achieve this model by setting up self-service development environments in the cloud. Engineers are then allocated their own isolated areas, within which they can freely run new code. These environments exist within the same cloud platform as live deployments, minimizing disparities and allowing accurate evaluation of system performance.

Running dev environments in the cloud instead of on localhost is, therefore, a more precise representation of the product that's being built. Localhost workflows are inherently small-scale and prototypical in nature, whereas remote processes are a replica of your actual delivery routines.

Localhost is intimidating

Localhost is an intimidating bottleneck when new developers come on board. Long-time team members get acquainted with the toolchain and learn to work around its pitfalls, but the maze of tools and processes can be daunting to the uninitiated. Try deleting your development environment and rebuilding it from scratch. If you struggle to get it up and running again, then you can be sure that others will too.

Developers may not be experienced with ops technologies, such as Kubernetes. Getting them up and running can require several multistep sequences before you can begin deploying your own stack on top. Kubernetes and microservices have a reputation for scariness that's often off-putting, regardless of how well-documented your process is.

Localhost is brittle

Complex dev environments tend to be brittle, too, increasing the likelihood that localhost will drift over time. This drift can occur in multiple directions, away from production and neighboring developers. This makes it harder to determine which part of the system's actually causing a fault.

By nature, localhost is specific to individual developers. They can replace parts of the stack, add integrations with their own tools, and implement shortcuts around cumbersome systems. While there's an argument that this can benefit productivity, it also impedes the consistency that dev teams need. Hunting bugs that only appear on one person's laptop is nobody's idea of fun.

The rise of remocal

Localhost still has some benefits, though: it's fast, familiar, and customizable to individual developer preferences. Not every activity needs to be remote, as some tasks, such as authoring code and running unit tests, already work well locally. Developers can use their favorite IDE to quickly iterate within a tight feedback loop.

Remocal development is a strategy for combining elements of both remote and local processes. This hybrid model lets you develop locally, then seamlessly build and deploy using remote infrastructure. It ensures you're testing code in realistic environments that are created from consistent configs without exposing you to the caveats of all-remote workflows.

Developers are empowered by self-service access to the resources they require. They can run a simple command to take code from localhost to a production-like environment within seconds, ready for testing to begin.

The use of remocal environments is rising because they can deliver both consistency and a tight feedback loop. They're approachable for developers and easy for operators to administer. Most remocal solutions are also platform-agnostic, so you can mix and match the cloud platforms your stack requires. Simple CLIs let developers build and run code without installing anything else on their machines.

Optimizing Development Workflows with Garden

Garden is a single tool for development, testing, and DevOps tasks. It integrates with your existing infra platforms, including Amazon Web Services (AWS), Google Cloud, GitHub, Docker, and Kubernetes.

Developers can use Garden to start new deployments from localhost straight to remote environments. It eliminates friction from the build and test loop, freeing up more time for productivity. Only the parts of your code that have changed are rebuilt when you deploy, a feature that lets you rapidly iterate without delays.

Garden is quick and easy to configure. You write compact YAML declarations that describe your system's components, such as this example which runs an NGINX Pod in a local Kubernetes cluster:


```yaml
kind: Project
name: demo-app
variables:
  namespace: demo-app
environments:
  - name: local
    defaultNamespace: ${var.namespace}
providers:
  - name: local-kubernetes
    environments: [local]
    namespace: ${var.namespace}

---

kind: Module
name: web
type: container
image: nginx:stable-alpine
services:
  - name: web
    ports:
      - name: nginx
        containerPort: 80
```
This is the Stack Graph visualization for the sample manifest.

The Stack Graph allows you to deploy your entire stack with one command. You can select between different environments, create new ones, and iterate on existing deploys. You can use Garden locally on developer machines and integrate it into your CI/CD pipelines. This minimizes the gap between dev, QA, and production.

One of Garden's principles is pluggability. It doesn't lock you into specific infrastructure providers or make it difficult to change your stack in the future. Garden only codifies the workflow steps required to deliver your app. You can think of this as what should happen when. The where and how are managed by customizable plugins that you can swap out as required, such as to replace a local Minikube instance with a remote Kubernetes cluster, or provision infrastructure using Terraform:


```yaml
kind: Project
name: terraform-demo
providers:
  - name: kubernetes
  - name: terraform

---

kind: Module
type: terraform
name: infra
autoApply: true

---

kind: Module
type: container
name: api
image: my-api:latest
services:
  - name: api
    dependencies: [infra]
    env:
      # Assuming the Terraform stack provisioned by the "infra" 
      # module outputs a value called "db_hostname" that points 
      # to the infrastructure hosting the service's database
      DB_HOSTNAME: ${runtime.services.infra.outputs.db_hostname}
```

Summary: Remocal Means Realistic, Rapid Testing

Cloud-native software needs a cloud-native development approach. Building on localhost alone doesn't cut it anymore. It makes it hard to maintain parity between environments, prevents you from accurately assessing performance, and can be intimidating to newcomers who have to set up complicated tools like Kubernetes before they can get productive. Developers shouldn't need detailed ops knowledge to test their code.

Remote-only dev environments aren't a perfect solution, either. They make you reliant on a stable internet connection, leave you waiting for pipelines to complete, and can be even harder to debug when something goes wrong. For instance, access to detailed CI job logs is often off-limits to developers. Engineers can also be frustrated by the loss of their preferred code editors and other utilities.

Remocal development is the answer. Hybrid solutions give you the benefits of both local and remote while avoiding all the negatives. Garden combines local iteration with remote testing and DevOps automation, helping you maximize dev velocity. You can rapidly test your changes in realistic environments without waiting minutes for regular CI pipelines to run. Get started with Garden to unleash your team's potential.

previous arrow
Previous
Next
newt arrow