Gitpod

Gitpod is a really neat tool that lets you work with your Git repositories in a web browser-based IDE. Gitpod is offered as a hosted solution or you can self host it. Of course self-hosting is the way to go! Unfortunately it's not as easy (at least right now) as most self-hosted apps to setup but this guide aims to walk you through getting a Gitpod instance setup for yourself.

This guide assumes you already have a Kubernetes cluster setup. I personally setup a cluster using k3s. I setup my custer with one master node (4 CPU cores, 4GBs of RAM and 40GBs of disk space) and 4 worker nodes (each with 8 CPU cores, 16GBs of RAM and 250GBs of disk space). This guide also assumes you're using an external MySQL database, external Docker registry and an external MinIO installation. I should also note that I am using GitHub Enterprise but this should work with GitHub.com and GitLab.

As someone who likes to keep things organized the first thing I did was create a project via Rancher called Gitpod. I also created a namespace, gitpod. I run the following command from my workstation where I've setup kubectl with my Kubernetes cluster configuration.

kubectl create namespace gitpod

You should get the following output:

namespace/gitpod created

Rancher Projects

I then added that namespace to the Gitpod project. Next we need to clone the Gitpod repository to our location workstation. You can put the repository wherever you'd like. I have mine in /home/jimmy/Developer/github.com/gitpod-io/gitpod.

git clone https://github.com/gitpod-io/gitpod

I use VS Code myself on my workstation, but use whatever you're most comfortable with. Open the new 'gitpod' folder in your editor. We need to setup our install!

Open the file charts/values.yaml. I recommend replacing the content of this file with this as this is what was recommended to me. Once replaced, save the file. Now we can start adjusting it and filling in our own information.

On line 4, change it to version: 0.5.0. Next adjust line 5 (hostname: localhost) to your domain name. This would be what you use in your web browser to access your instance of Gitpod.

version: 0.5.0
hostname: mydomain.com

We need to change the imagePrefix value as we're setting up a self-hosted installation. Adjust it as follows:

imagePrefix: eu.gcr.io/gitpod-io/self-hosted/

On line 5 (workspaceSizing), you can adjust your workspace settings. The only thing I adjusted was the limits, I set my memory limit to 4Gi. You can set this to whatever you feel comfortable with.

workspaceSizing:
  requests:
    cpu: "1m"
    memory: "2.25Gi"
    storage: "5Gi"
  limits:
    cpu: "5"
    memory: "4Gi"

Next on line 51 (db) you'll want to fill in your database information. You can use a hostname or IP address here for host.

db:
  host: db.yourdomain.com
  port: 3306
  password: password1234

Next open the secrets/encryption-key.json file and create yourself a new key. I am not sure if this is required but I figured it would be better to set something rather than what is in there just in case. I used this website to generate a string.

Next configure the authProviders block. I am not sure if you can have both GitHub and GitLab at the same time, or have both GitHub and a GitHub Enterprise configurations, you're more than welcome to try it out. However I have GitHub Enterprise so I create an OAuth app and filled out the details. It looks something like this:

authProviders:
  - id: "GitHub-Enterprise"
  host: "githubenterprise.com"
  type: "GitHub"
  oauth:
    clientId: "6g5a657e145y51abc2ff"
    clientSecret: "9819537b4694ee6a46312t2dalw17345f8d5hgt"
    callBackUrl: "https://mydomain.com/auth/github/callback"
    settingsUrl: "https://githubenterprise.com/settings/connections/applications/6g5a657e145y51abc2ff"
  description: "GitHub Enterprise"
  icon: ""

In the branding block I updated each instance of gitpod.io to my domain. Feel free to do the same but it's not required as far as I know.

I updated the serverProxyApiKey with a new string for the same reason as I updated the one in the secrets/encryption-key.json file.

Next we'll update some of the settings in the components section. First up is imageBuilder. Since we have our own registry we need to update the registry block to reflect that. Here's what mine looks like:

imageBuilder:
  name: "image-builder"
  dependsOn:
    - "image-builder-configmap.yaml"
    hostDindData: /var/gitpod/docker
    registryCerts: []
    registry:
    name: registry.mydomain.com
      secretName: image-builder-registry-secret
      path: ""
      baseImageName: ""
      workspaceImageName: ""
      # By default, the builtin registry is accessed through the proxy.
      # If bypassProxy is true, the builtin registry is accessed via <registry-name>.<namespace>.svc.cluster.local directly.
      bypassProxy: false
    dindImage: docker:18.06-dind
    dindResources:
      requests:
        cpu: 100m
        memory: 128Mi
    ports:
      rpc:
        expose: true
        containerPort: 8080
      metrics:
        expose: false
        containerPort: 9500

Under workspace make sure to set the secretName of pullSecret to image-builder-registry-secret:

pullSecret:
  secretName: image-builder-registry-secret

Next under wsSync you can setup the remoteStorage details however it may be some what pointless due to a bug in one of the templates. I'll show you how to get MinIO working after we've deployed the Helm chart. I did fill out the information so once the bug is resolved I already have the settings filled out.

Scroll down to the bottom of the page, you should see sections for docker-registry, minio and mysql. Edit them or replace them so it looks like this:

docker-registry:
  enabled: false

minio:
  enabled: false

mysql:
  enabled: false

Now save your values.yaml file. Next we need to create a secret for your Docker registry.

kubectl create secret docker-registry image-builder-registry-secret --docker-server=registry.mydomain --docker-username=$USERNAME --docker-password=$PASSWORD -n gitpod

Make sure to put the URL of your registry for --docker-server and replace $USERNAME and $PASSWORD with your username and password. Once that is done you should see it on the Registry Credentials tab of the Secrets page within Rancher.

Rancher - Registry Credentials

This next step I am not sure if it's necessary, but I found that if I didn't do it, I had issues. So log into your MySQL server and run these queries:

CREATE USER IF NOT EXISTS "gitpod"@"%" IDENTIFIED BY "$PASSWORD";
GRANT ALL ON `gitpod%`.* TO "gitpod"@"%";

CREATE DATABASE IF NOT EXISTS `gitpod-sessions` CHARSET utf8mb4;
USE `gitpod-sessions`;

CREATE TABLE IF NOT EXISTS sessions (
   `session_id` varchar(128) COLLATE utf8mb4_bin NOT NULL,
   `expires` int(11) unsigned NOT NULL,
   `data` text COLLATE utf8mb4_bin,
   `_lastModified` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
   PRIMARY KEY (`session_id`)
);

CREATE DATABASE gitpod CHARSET utf8mb4;

This creates a MySQL user, 'gitpod' (don't forget to update $PASSWORD in the query with your own password), the gitpod-sessions database with a sessions table inside of it and the gitpod database.

Next we need to create 2 repositories (workspace-images and base-images) within our Docker registry. The only way I could figure out how to do this was to push an image to the registry. I just used something small though I plan on deleting it later so I suppose that doesn't matter. I did using these commands:

docker push registry.mydomain.com/workspace-images/docker-whale:latest
docker push registry.mydomain.com/base-images/docker-whale:latest

Now you should be all set to deloy! First lets add the Gitpod Helm charts repository:

helm repo add gitpod https://charts.gitpod.io
helm dep update

Next lets install Gitpod!

helm upgrade --install gitpod gitpod/gitpod --timeout 60m --values values.yaml -n gitpod

You should see something like this:

Release "gitpod" does not exist. Installing it now.
NAME: gitpod
LAST DEPLOYED: Thu Dec  3 10:43:45 2020
NAMESPACE: gitpod
STATUS: deployed
REVISION: 1
TEST SUITE: None

You can watch each of the workloads come up in Rancher if you'd like. Hopefully everything is green!

Rancher - Gitpod Workloads

Now we've got to do a little fixing of certain things due to bugs with Gitpod. First if you have a multi-worker node cluster we need to fix ws-sync. You can do this however you'd like but I find doing it from within Rancher the easiest. In the row for ws-sync click on the little blue button with 3 dots and click on 'View/Edit YML'. Around line 350 or so we need to change the dnsPolicy and add hostNetwork. Adjust it so it reads as:

      dnsPolicy: ClusterFirstWithHostNet
      hostNetwork: true

Save it and this will automatically trigger the workload to redeploy. This will help prevent getting the following when trying to load a workspace:

 cannot initialize workspace: cannot connect to ws-sync: cannot connect to ws-sync: cannot connect to workspace sync; last backup failed: cannot connect to ws-sync: cannot connect to workspace sync.

Next we need to fix the MinIO settings in the server workload. Similar to how we edited the YAML for ws-sync we need to do the same for server. Click the little blue button with 3 dots and click on 'View/Edit YAML'. Locate the following which should just have defaults in the value lines:

        - name: MINIO_END_POINT
          value: minio.minio.svc.cluster.local
        - name: MINIO_PORT
          value: "9000"
        - name: MINIO_ACCESS_KEY
          value: accesskey
        - name: MINIO_SECRET_KEY
          value: secretkey

You may only need to update the values for MINIO_ACCESS_KEY and MINIO_SECRET_KEY. I believe I needed to update the value for MINIO_END_POINT as well as it seemed to have the port tacked onto the end which should be removed. Once everything looks good, hit Save and the server workload will redeploy.

At this point you should be all set. Visit https://yourdomain.com which should redirect you to https://yourdomain.com/workspaces/. You can login from there. Once you do it's just a matter of creating new workspaces. This can be done by constructing a URL like https://yourdomain.com/#https://github.com/username/your-repository. If all went well you should see a code editor in your web browser with your Git repository contents!

Other Notes

  • At the time of writing (December 3, 2020) there still appears to be an issue with uploading extensions. I have a thread on the Gitpod community forums for this. Uploading extensions has actually never worked for me in all the time I've been using Gitpod which appears to have been since June of this year.
  • There appears to be an issue with installing extensions from search results. I just noticed this today after someone else posted about it in the Gitpod community forums.
  • I have my Kubernetes cluster sitting behind Traefik which provides Gitpod with SSL certs.

Resources