Gitpod and Hringvegurinn

Iceland

Ever seen an advertisement for visiting Iceland? Have you noticed that they all mention Hrinvegurinn or the Ring Road, as a good tour? (If you haven't seen a tour ad for Iceland, Steindi Jr does an excellent job in The Hardest Karaoke Song in the World.) The biggest draw to the Ring Road is that it travels the entire island with many stops while being on the same road, Þjóðvegur 1, the entire time. However, to really see it all, you need to plan a couple of weeks to take it all in.

However, if you want to get a good idea of what Iceland is like, the capital city of Iceland, Reykjavík, is a good sample. Why you may ask? In a country of 370,000 people, 233,000 of them live in the Capital Region (Höfuðborgarsvæðið) - around 62%. Sitting about 40 minutes from the international airport, you can even see it if you do a 1 day long layover and get an idea of what it's like. In fact, a multiday layover to visit Reykjavík is one of the budget air carrier Icelandair offers.

But what if you really want to integrate? For remote workers (meeting a few requirements) they offer a long-term remote workers visa, where you can actually live there for 180 days while still working for a non-Icelandic company remotely. Between this, getting a Kennitala, and learning to like plokkfiskur, it's as close as you can be to being Icelandic without actually getting a job there and moving.

I promise, all this leads somewhere beyond my passion for a nation that has fewer people than the city I live in and where I struggle to pronounce my own name in the language.

Gitpod

Gitpod is a way to write your code in your browser. That's it, go home.

...or maybe it's a little more than that. Actually, it really is.

Much like NixOS or containers, what Gitpod does is takes a repo in GitHub, GitLab, or BitBucket and loads it into your browser and runs a version of VSCode with it in an isolated environment. If you're familiar with VSCode, you can even load your own plugins. To top it off, you just need to create your login once using GitHub, GitLab, or BitBucket and give it perms to access your private repos and you're off to the races. Want to see what it's like? Great! Just throw gitpod.io/#/ in front of a repo, and do it. For example, my old Waypoint demo:

gitpod.io/#/https://gitlab.com/mjh/clojure-demo

(If you haven't created an account, you can do so while using your existing GitHub, GitLab, or whatever. You can definitely access GitLab from the other two logins too)

Congratulations! You can now access my old demo. You can make edits, do pull requests, run terminal commands, and do pretty much everything your local machine can do. You can load environment variables (which you need to do for that demo) or execute command line functions, even docker commands.

Behind the scenes, Gitpod is managing your workspace on Kubernetes with a pretty slick container. This allows a few different workspaces to be ran or even off a branch instead. You can, in fact, self-host Gitpod for airgapped or highly restricted environments, but that's beyond the scope of what this'll cover. But this platform makes it so it can launch the image and go!

By using this alone, you hit some of the best features of Gitpod. By throwing https://gitpod.io/#/ before an https git url, you get oh, say, 62% of features. That's right, you've landed in Reykjavík! You can do a lot with this implementation alone - I've built docker images on my iPad and pulled up projects I didn't really trust without exposing my local information to it.

.gitpod.yml and the Ring Road

Alrighty, well, here you are and you have the ability to open any repo you can access, from public GitHub through self-hosted GitLab and BitBucket along the way. You've seen the cool parts, but you know there's more. A lot more.

Here's where you start to get really into exploring Gitpod is with their configuration file. This is truly where you can dig in and see more than the entry point, but it takes a bit more time to do.

What a .gitpod.yml at its core does is hand gitpod instructions while it loads up. For instance, with a couple of Hugo projects I have, this is my .gitpod.yml

tasks:
  - name: Hugo deps
    before: brew install hugo
    init: echo "Hugo version: `hugo version`"
    command: hugo server -D -F --baseUrl $(gp url 1313) --liveReloadPort=443 --appendPort=false --bind=0.0.0.0

ports:
  - port: 1313
    onOpen: open-preview

vscode:
  extensions:
    - esbenp.prettier-vscode
    - rusnasonov.vscode-hugo
    - TabNine.tabnine-vscode

What this does is set up a few things for me out the gate that are reproduced every time the gitpod boots up. In this case, it runs tasks, opens ports, and loads some of my favorite hugo specific extensions.

During the tasks phase, the named task "Hugo deps" initializes by installing hugo with LinuxBrew into the Gitpod workspace. It then runs the command that opens the dev server showing what it would render.

The ports section opens up that port to the workspace URL (as referenced by gp url in the init step) so that it can view the site as rendered in development mode.

The last section loads a few of my favorite VS code extensions, namely making my markdown easier to read, helping me with a few commands, and the utter magic that TabNine is (having come from the IntelliJ suite, TabNine really seals the deal with VSCode).

This means that if you load this same repository, you would get the exact same thing and if you committed changes to the .gitpod.yml and I loaded the repo, I'd get the same thing as you. Really, it's the same road, with different stops to help you enjoy the tour. Welcome to Hringvegurinn! We'll get all the best stops/parts of Gitpod while having shared the same road every time we load.

Becoming One with Gitpod

So, you can now create an environment that reproduces the same thing each time. But what if you were working on some in-depth Prometheus work that required you to fork your own Prometheus, at least temporarily? Boy do I (and, well, Prometheus) have a solution for you.

Go ahead and load the Prometheus repo in Gitpod and watch. It'll take a little bit to get it running - perfect time to go learn about Icelandic hot dogs or maybe plan a visit to the oldest parliment in the world. When you get back, you'll notice a lot of commands have been ran and your environment has a second window open with a demo Prometheus and everything. What's happening here?

Two pieces of magic, first is their .gitpod.yml

image:
  file: .gitpod.Dockerfile
tasks:
  - init:
      make build
    command: |
      gp sync-done build
      ./prometheus --config.file=documentation/examples/prometheus.yml
  - command: |
      cd web/ui/
      gp sync-await build
      unset BROWSER
      export DANGEROUSLY_DISABLE_HOST_CHECK=true
      npm start
    openMode: split-right
ports:
  - port: 3000
    onOpen: open-preview
  - port: 9090
    onOpen: ignore
.gitpod.yml

As you can see here, this is doing some NodeJS work, but leveraging gp sync-done build and gp sync-await build. This is simply saying that when the make build command is done ( gp sync-done build ) it'll update a sync variable called build the gp sync-await is waiting for that variable to be complete before triggering, allowing you to chain builds and make your environment ready.

But wait, what's that image at the top? That's where you can take the default gitpod dockerimage and make your own variant. For Prometheus

FROM gitpod/workspace-full

ENV CUSTOM_NODE_VERSION=16

RUN bash -c ". .nvm/nvm.sh && nvm install ${CUSTOM_NODE_VERSION} && nvm use ${CUSTOM_NODE_VERSION} && nvm alias default ${CUSTOM_NODE_VERSION}"

RUN echo "nvm use default &>/dev/null" >> ~/.bashrc.d/51-nvm-fix
.gitpod.Dockerfile

This is where you can ensure everyone has the exact same versions in their workspaces and every developer has the same, in this case, node version. No more "I have Node 14 and it works" - as soon as someone opens this project in Gitpod, they'll have the same thing.

That's great, but why does that matter beyond the developers? Honestly, the best use case I've ever had is code reviews. A shared secret is that most people don't actually pull down the code to do code reviews and rely on system tests and the dev to do it right, even in paired programming, they will often assume the other one did things right enough. What gitpod can do here is make it so that when you open a branch in a Code Review you can get the exact same environment and can test things - ensuring someone doesn't have a strange syslink or perhaps a custom compiled module.

With this level, everyone can have the same environment and code from wherever you can get internet access. No managing environments, or hoping that they load their nix shell correctly. You can live in the code! At least, as much as anyone can live in the code of another. Kind of like, oh, a visa to their code for a long while.

Summary

Iceland is beautiful and you should visit.

Iceland aside, Gitpod can enable developers to share builds, plugins, environment variables, and everything without relying on external nix packages or assuming everyone loaded the unmodified brew file. It also allows code to happen anywhere, so a developer could be working from Kattakaffihúsið, their desk, or a makerspace, which having a remote workforce appears to be the new normal or at least contributing to happiness.

Consider throwing a .gitpod.yml in your repos to enable a consistent approach, even if most don't use gitpod. It would make it easier on those just touring your code and those of us that use Gitpod most every day (like gitpod themselves does!) and might make you think through a bit more about controlling versions and packages. Heck, if you GitLab, it'll even offer the button on a MR.

As always, reach out - a consistent developer experience is absolutely vital for making DevOps run smoothly and focus more on platform and application development. More doing and less manual work is key!

(Also, please send me your best Plokkfiskur recipes while I learn how to master that comfort food)