Tech

Okay, Gitpod Flex is actually pretty cool

Okay, Gitpod Flex is actually pretty cool

I’m about to tell you something and I don’t want you to judge me for it. I have a Windows machine. Always have. I’ve never had a Mac or anything Apple, really. Just some Airpods. But my phone is Android, my work laptop is Windows, my home PC is Windows, and I’m not sorry about it.

I just like the experience it provides. Either that, or I have Stockholm syndrome, which could very much be the case. But I digress.

One of the big drawbacks of using Windows is the lack of support in… a lot of things. I periodically do consulting with early-stage startups in the concept and seed stages and they rarely have Windows support. Normally I’m fumbling my way through the dark with founders who say “just use the Windows Subsystem for Linux, it uses a Linux kernel that can run our app” while pretending I have an idea what any of those words mean 😅

It’s no fault to anyone out there, Windows simply isn’t the first operating system of choice for developers. Which is fine, I love a good challenge.

When I started at Momento a couple of years ago, one of my responsibilities was help create and maintain the developer documentation. So I cloned the docs repository (which is open source, by the way) and immediately was hit with the harsh realization that I was the only person at the company running a Windows machine. How did I know? There were a few signs.

The team has built some pretty cool custom components to render code inside of the docs. But the code samples need to be fetched from various code-specific repositories at build time. To do this, they wrote some shell scripts (.sh) as part of the build process. Windows can’t natively run those. So I made .bat versions of them.

Also, when pages move in the docs, we add redirects that point from the old location to the new one (makes sense, right?). On Linux and Macs, redirecting an entire folder, /oldlocation/* to /newlocation is totally fine. But Windows doesn’t like asterisks in file paths. So every time I make a change to the docs I have to comment out the wildcard redirects and hope I remember to uncomment them before I commit any changes. Not the best experience.

Trying to make Windows variations of .sh files and workflow scripts, and commenting out random lines of code worked for the short term, but it’s not sustainable. It also works only for me. The docs are open source. If someone comes along with a Windows machine and wants to fix something or make a clarification, the barrier to entry is way too high. So I had to figure out a better way.

By happenstance, my friends over at Gitpod just released Gitpod Flex, a surprisingly simple service that creates and manages development environments that you can run directly from VSCode. They told me all I need to do is add a couple of files to the docs repo and things would just work. Being the professional skeptic that I am, I decided to put that to the test to see if it could make my life easier.

Note - this is a sponsored post by Gitpod. The endorsement is for my attention, not my opinion. This article is a reflection on my personal thoughts towards the product and not that of Gitpod. Ok, now that we have that out of the way, let’s check out some cool stuff!

What exactly is Gitpod Flex?

I undersold Gitpod Flex a moment ago. It has basically everything you need in order to get a development environment built in a way that jives with your processes.

It uses Dev Container, a standardized way of defining development environments, to define the prerequisites, tools, ports, Dockerfile (if needed), VSCode customizations, and build commands.

But that’s just one aspect of it. If you give someone a toolbox but they have no idea how to use any of the tools inside, that toolbox is of little value. Once you show them how to use the tools, or even better, do it for them, then they’re gonna start moving quickly. That’s where automations come in. These are, in my opinion, the biggest differentiator between Gitpod and similar services. Automations are ways you can define both long running processes and single one-off actions, like starting a local development server or seeding a database respectively.

Gitpod also lets you host these environments and automations in a runner in the cloud or locally on your desktop. More on this in a minute.

It does lots of things and presents them in a relatively simple way, allowing you to get started with minimal barrier to entry. Just a little bit of learning, depending on your familiarity with containers and standardizing development environments.

Creating an environment with Gitpod

All cards on the table, it took me a while to figure things out. Having never used a development environment before (and relying mostly on my rubberband and duct tape laptop setup), I wasn’t really sure what I needed to make things work. Plus, I’m not much of a container guy.

My goal was to get the Momento docs runnable on my machine without my hacky setup. So it was a trial by fire to remember the steps I took to get things working in the first place while simultaneously learning what the components were to Gitpod and how to use them. Luckily for my use case, and hopefully for many other open-source projects, all I needed was to create two files.

Setup dependencies and configuration with Dev Container

As I mentioned earlier, Gitpod uses an industry standard for defining container dependencies and configurations: Dev Container. The configuration goes in a .devcontainer/devcontainer.json file in the root of your project and contains all the necessary information to setup and build a container for your development needs. Here’s a peek at the one I created for the Momento docs.

{
	"name": "Node.js",
	"image": "mcr.microsoft.com/devcontainers/javascript-node:20-bullseye",
	"features": {
		"ghcr.io/devcontainers/features/github-cli:1": {}
	},
	"customizations": {
		"vscode": {
			"settings": {},
			"extensions": [
				"dbaeumer.vscode-eslint"
			]
		}
	},
	"updateContentCommand": "npm install",
	"remoteUser": "node",
	"forwardPorts": [ 3000 ],
	"portsAttributes": {
		"3000": {
			"label": "Docs Preview",
			"onAutoForward": "notify",
			"protocol": "http"
		}
	},
	"runArgs": [ "--network=host"	]
}

That’s it! This file lays out everything I need for the development environment to run. The majority of the work is sneakily behind the image property where we use an existing, public container as the base image. On top of the base image I signal that I want VSCode with the eslint extension in there, and that I want to forward port 3000 (more on this in a second). The last thing I’ll call out from this config file is the runArgs property. Anything passed in here is used as command-line arguments for Docker when the container spins up. I pass in --network=host to tell Docker to use the network of the host (in my case it’s an EC2 instance in my AWS account) instead of creating an internal network in the container itself.

I’ve seen how horrific Dockerfiles can be and am always terrified at the complexity and amount you have to learn to even get a “Hello World” going. This devcontainer config took me a few minutes and was explained wonderfully through a combination of the Gitpod docs and my buddy ChatGPT 🙂

Making an environment “just work”

As I said earlier, what we just made is a toolbox. It has everything we need to get the job done, but there’s still a bit of work to do to get where we need to go. In the case of the Momento docs, I had those .sh scripts to run and to figure out how to compile the fancy code components in the solution. This was a 5 step manual process before, of which 3 of them I had totally forgotten about until I wrote this article (because they were one-time setups). I was a boy scout, I always have a feeling of “leave something better than I found it”, which is why I turned to automations.

If you remember from before, automations are scripts that can be either one-time tasks or long-running services. In an ideal world, I could start my dev environment and the docs would be immediately available for me to look at locally and live reload as I make changes. With this in mind, it sounded like a long-running service was what I needed to go for, so I created a .gitpod/automations.yaml file and configured the following:

services:
  docusaurus:
    name: Start Docusaurus Locally
    triggeredBy: [ 'manual', 'postDevcontainerStart']
    commands:
      start: |
        npm install
        npm start

That’s it. That’s all it took. All the manual steps from before are handled right here. As it turns out, the devs at Momento are smart cookies and tied all the shell scripts into pre scripts. So everything simply fell into the right place after dependencies were installed. For the sake of completeness, here’s the command that runs when you type in npm start in the Momento docs.

{
  "scripts": {
    "prestart": "./prepare-ts-plugins.sh && ./prepare-sdk-git-repos.sh",
    "start": "docusaurus start --no-open",
  }
}

With npm, the prestart script will run first, then execute the start script upon success. So all the extra work I was doing was handled right here. You see that it’s running docusaurus start --no-open. That command starts a local server pointed at the dev docs. It defaults to port 3000, which is the port we forwarded in our devcontainer file. That means our development environment will automatically forward network traffic on port 3000 to the host on port 3000, providing us access to the docs!

You might notice the triggeredBy: ['manual', 'postDevcontainerStart'] command. That tells Gitpod when to run this script. I configured it to run automatically when the container starts and also on demand whenever I click “run” just in case something goes wrong. Because this is running when the container boots up, that means by the time I’m ready to roll and am connected remotely, the dependencies are installed and the local server is running!

Wait a minute, did I just say connect remotely?

Connecting to a Gitpod environment

Rememeber, the whole point of this experiment was to not use my machine. The development environment we just configured is setup to run somewhere else. Specifically, I chose to run it from my AWS account. Gitpod Flex is positioned to be extremely versatile - giving you options to self-host the environment in AWS, Azure, GCP, and Linux servers, or you could run it locally with their a desktop app. At the time of writing, only AWS is supported for self-hosting and their desktop client only supports Apple Silicon (I just can’t get away from the lack of Windows support!). So I went with the only option I had: self-hosted in AWS.

I’m going to gloss over a few setup details so I can start talking about my favorite part - using the dev environment. After I setup the container and automations and had it integrated in the Momento docs repository, turning the environment on/off became as easy as a toggle switch in the Gitpod dashboard. When it’s active, there’s a little VSCode button I can press that does nothing short of magic.

When I click the VSCode button in Gitpod, it launches the IDE on my local machine as if I were opening a repo locally. But the cool part is that it’s fully connected to my dev environment hosted in my AWS account. It SSH’d into the container and gives me a window straight into it with full access to the GitHub repository (including the ability to push, pull, switch branches, etc…), the local server built and running via our automation, and the port forwarded from the server so I can hit localhost in a browser on my desktop and see the work-in-progress docs site 🤯

The ability to SSH into a remote environment via VSCode is not new. It is to me, but it’s something that’s been around for a while. The part that gives me goosebumps every time is that it’s completely ready for me to make changes and view them in my browser upon startup. Automations, ftw!

Where I see this going

Despite my rose-colored glasses, there’s a lot of work the Gitpod team still has to do. Support for other cloud environments for self-hosting and Windows/Linux machines for their desktop client needs to be in the short-term roadmap. They also indicate support is coming for other source control providers outside of GitHub, like GitLab and Bitbucket.

But what I’m excited about is how this could change open-source development. When I open source my projects, I often think about how I can get things running with minimal “extras”. Seeding data, fancy build scripts, and hidden dependencies all tend to unknowingly plague my projects, greatly reducing the likelihood of someone being successful with what I’ve written. But if we start normalizing the idea of including devcontainer and automation config files in OSS projects, that could change.

Things could get significantly more complex under the covers, but it wouldn’t matter. Everything is taken care of for you upon launch of the dev environment or on an as-needed basis via automations. We’re in a “one click” mentality these days where if it takes two or more steps, you’re going to start losing people.

What I’d like to see (and something I don’t see in the docs) is a way for open source project owners to host runners for free for contributors. That way things simply “just work” and lower the barrier to entry for contributions. Maybe we can get to a point where there’s a badge in the repository readme that starts a session for you automatically. That type of ease would open the door for so many people. It could be a starting ground for hackathons. It could let interns get their hands dirty day one. The possibilities are endless.

I think Gitpod is headed in the right direction. Looking at their site, you can tell they’re working hard to meet developers where they are. Their plans to have self-hosted runners in the big 3 cloud providers and support for the major source control vendors shows the promise. There’s a lot of stuff I didn’t talk about, like support for different IDEs, organizations, and environment classes, but that’s table stakes for this kind of thing.

I’m genuinely excited about the possibility of getting rid of “tribal knowledge” and hours of guess-and-check unrepeatable setup on local machines. I think it is a real opportunity for changing the way we contribute to OSS.

I didn’t expect to be bullish on the idea going into this experiment, but seeing how quickly I ramped up and how easy it was to get something working that never worked for me before… game changer.

Happy coding!

Allen Helton

About Allen

Allen is an AWS Serverless Hero passionate about educating others about the cloud, serverless, and APIs. He is the host of the Ready, Set, Cloud podcast and creator of this website. More about Allen.

Share on:

Join the Serverless Picks of the Week Newsletter

Stay up to date with the best content serverless has to offer, learn about the latest updates to AWS serverless services, and get to know community superheroes, catered by AWS Serverless Hero Allen Helton. New issue every Monday.
Click here to see past issues.

Join the Serverless Picks of the Week Newsletter

Thank you for subscribing!
View past issues.