Messing around with Kasm Workspaces on Reclaim Cloud

At the end of the day today I streamed a little bit of me playing around with Kasm Worskpaces on Reclaim Cloud:

The tool seems interesting and it has been on my list of things to look into for a little while. It’s basically a self-hostable Desktop-as-a-Service (DaaS), like Citrix or Amazon Appstream, but for Linux Desktops and applications. Also, it has a free version!

Under the hood it all runs on Docker, which is how I found out about it. I stumbled on this curious image on DockerHub last week and had to try it out:

Honestly, to my suprise I was able to succesfully get it working in the timespan of a 40 minute stream 🎉🎉🎉

A handy Alfred Workflow to get just the domain name from a URL in your clipboard

A very, very, common thing that I find myself doing while working with web stuff is copying a long URL, but only needing the domain name part to paste into a terminal or elsewhere. It’s annoying to carefully select just part of the URL, and even more annoying to manually delete the parts I don’t need:

I love automating and making little shortcuts to simplify repetitive tasks like this!

After wasting time trying to do this with regular expressions, Nick Plank pointed me in the right direction. All I needed was to programmatically divide the text up into groups using the forward slash as a separator, then grab the text in the third group. Here’s a visual:

a URL divided into 4 parts deliminited by the forward slashes, color coded, starting with https://

You can see that the main domain part, the part I want, is the third group. This is because there are two slashes in a row after https://, so that group exists, but is empty. This methodology works great for my needs here, but I quickly realized I’d also have to check if my URL began with https:// or http:// because sometimes they don’t when they get copied, and in that case I would want to select the first grouping instead:

a URL divided into 2 parts deliminited by the forward slashes, color coded, not starting with https://

With the game plan set, it was time to write a tiny little bash script to try it out:

#!/bin/bash
clipboard=$(pbpaste)
start=$(echo $clipboard | cut -d/ -f1)

if [ $start = "https:" ] || [ $start = "http:" ]; then
	domain=$(echo -n $clipboard | cut -d/ -f3)
else
	domain=$(echo -n $start)
fi
echo -n $domain
echo -n $domain | pbcopy

The script basically just gets the contents of the clipboard using pbpaste and uses cut to divide the URL into parts using by the forward slash as the separator. If the URL starts with https: or http: it will grab the 3rd group of text, and if not it grabs the first group. Finally, it prints out the domain to the terminal, then uses pbcopy to copy the domain name to the clipboard.

This works well, but I don’t really want to have to open a separate terminal to use it all the time1, so I used this script to make an Alfred workflow. Now I can trigger all of that automation by just typing ;domain anywhere on my Mac!

If you’d find this useful, and you are an Alfred user, you can get my workflow here:

⬇️ Domain-snippet.alfredworkflow.zip


  1. Pay no attention to the fact that my demo video shows me pasting this into a terminal, lol. I’m often pasting domain names into web pages or Slack as well! ↩︎

A Tip for Quick SSH Access on Reclaim Cloud

I use SSH to access different environment in Reclaim Cloud a lot, but one thing that I like to do is use a native terminal app (I use iTerm2 on macOS) instead of the Web SSH functionality built in to Jelastic. Web SSH is amazingly convenient, but web-based terminals like this frequently lack some of the features I am used to using in desktop-based terminals like customizable keyboard shortcuts, organization features like tabs and panes1, etc. Sometimes, copy and paste is also a little funky on Web based terminals as well.

Luckily, you can easily use any terminal or SSH client you want with environments on Reclaim Cloud. For environments where you know the password of the user account and you give it a public IP address, you can use SSH like you would to log in to any other server.

But what about environments that you don’t know the password, or don’t have a public IP? Or maybe, like me, you want a way to quickly jump between a bunch of different environments like you can with Web SSH? For this we have the Jelastic SSH Gate! This will allow you to use a text based menu in your terminal to SSH access to any environment in your account!

Adding your public key to your Reclaim Cloud Account

To get started, you need to generate a key pair using the terminal on your computer with ssh-keygen. You can in most cases just press enter and accept the defaults when doing this. Next, you will want to copy the contents of the id_rsa.pub file that gets generated. id_rsa.pub is the public part of the public/private key pair. Basically, you never want to share the private key, but the public key is what you can load on to other computers to prove you are who you say you are.

You can use the cat command to print the contents of the file to your terminal, where you can copy it.

cat ~/.ssh/id_rsa.pub

Then in Reclaim Cloud you’ll go to Settings > SSH Keys then click on Add Public Key. Then paste your public key in the Key: box and hit save.

Screenshot of Jelastic’s Public Key screeen

Trying out the SSH Gate

Finally, you can click on SSH Connection in Jelastic, to find the command that you will need to enter to use the SSH Gate.

Screenshot of the SSH Connection Tab

Then paste that command in your terminal!

Making an alias

Ok, but here’s the final tip! We’re going to make a shortcut for this command, because who will ever remember that? We can use a terminal alias so that you only have to type in reclaim-cloud (or whatever you want to name your alias).

I’m going to focus on Macs using the ZSH shell, which has been the default on macOS for the last few years. If you don’t know which shell your computer is set to use, type echo $0 into your terminal, and it should say zsh or bash. If you are on a Mac and you aren’t running ZSH (this could be the case if you have had your Mac for a few years, macOS won’t change these on its own) I would recommend switching to ZSH by running this command:

chsh -s /bin/zsh

If you end up changing your shell with the command above, you will need to close your terminal window and open up a new one.

Now that we are working in the same shell, we are going to edit our .zshrc file to make our alias. You can technically use any text editor, but if you are new to this stuff, I’d recommend using nano. Enter this command to get started:

nano ~/.zshrc

This file may or may not have stuff already in it, depending on your setup. In either case, we are going to use the arrow keys to scroll to the end of the file and add a new line:

alias reclaim-cloud='SSH_GATE_COMMAND_GOES_INSIDE_THE_QUOTES'

You’ll want to replace the text inside the single quotes with the SSH Gate command you copied from earlier. screenshot of nano editing .zshrc Then when you are all set, you will want to use the CTRL+X keyboard shortcut to exit, then type Y, then the Enter key to save your changes. Now close your terminal window, and open up a new one and try out your new alias!

testing out the alias


  1. How could I possibly be productive WITHOUT stuff like this /s Screenshot of a terminal window with 4 panes, neofetch, gotop, htop, and sl clockwise starting from the top left, lots of nonsense  ↩︎

Installing Foundry on Reclaim Cloud

I’ve had this post sitting incomplete in my drafts for a long time!

Foundry Virtual Tabletop is an excellent, self-hostable virtual tabletop tool. You use it to play tabletop RPGs with other folks over the internet, (check the link above out if you are curious). It is a paid, NodeJS application that you can run on your own computer or on a server.

This won’t be a comprehensive tutorial on foundry itself after install, but I want to cover the basics and the Reclaim Cloud specific things that you will need if you don’t want to have to worry about manually starting the foundry application every time you restart a container (foundry’s own install guide doesn’t really cover this). You can also run foundry in Reclaim Cloud using docker containers, but there are no officially maintained containers at this time, and I found issues with foundry plugin compatibility using Docker, so I went with the method below.

First make a new environment, select node at the top of the window, enter your environment name, and set your cloudlets how you’d like them: screenshot of a node environment in reclaim cloud

You will also likely want to hit the SSL button, and enable built-in SSL, particularly if you aren’t going to be mapping a custom domain and will instead be using the shared load balancer and the subdomain it gives you.

The first thing we are going to do is get rid of the sample node application that comes preinstalled. Click the web SSH button and run this command in your foundry container:

rm -r ~/ROOT/*

Now you’ll need to log in to the foundry website, and get your temporary download link for the linux version of Foundry. Then we’re going to basically just follow the instructions on the foundry website:

# Create application and user data directories
cd $HOME
mkdir foundryvtt
mkdir foundrydata

# Install the software
cd foundryvtt
wget -O foundryvtt.zip "<foundry-website-download-url>"
unzip foundryvtt.zip

# Start running the server
node resources/app/main.js --dataPath=$HOME/foundrydata

This will start foundry in the terminal, but if you try to load the URL, you probably won’t see anything yet, as Foundry listens on port 30000 and Jelastic checks for port forwards when it starts a container. For now, you can just quit foundry by using the keyboard shortcut ctrl+c in the terminal.

Now, we need to set up Foundry to auto start when the container launches! We will make a symlink that will allow Jelastic to launch our application. By default, Jelastic is configured to launch server.js in the ~/ROOT folder, instead of adjusting this, I find it simpler to just make this symlink:

ln -s ~/foundryvtt/resources/app/main.js ~/ROOT/server.js

Finally, we need to make a symlink from Foundry’s default config directory, to where we actually want our data stored in the home folder where it is easier to find.

ln -s ~/foundrydata ~/.local/share/FoundryVTT

Now you can restart your Application Server container, and foundry should load up automatically! Visit the URL for your environment to check it out.

You will the need your foundry key to put in the web page, and you can customize settings. You can customize most settings in the web UI, or by editing Foundry’s options.json file. You should be able to find the file at the following path if you followed the above instructions for install: /home/jelastic/foundrydata/Config/options.json

Lastly, if you want to map a custom domain for your foundry server, you will need to add an NGINX load balancer to your environment. screenshot of a node environment with a load balancer

In addition to that, if you want to redirect traffic to HTTPS while using a custom domain (because foundry itself won’t do that), the load balancer can be configured to do this.

Customizing the look of Peertube

PeerTube is a really nice self-hostable YouTube alternative that Jim has been using for a bit and introduced me to. I wanted to spin up my own install at video.jadin.me and theme it a bit to fit in with this blog site.

The first thing I did was install the dark theme, which I thought would more closely match my blog site as a starting point. You can do this from Administration > Plugins/Themes. I grabbed the official dark theme: screenshot of themes in the peertube admin interface

After installing it, you will need to enable it from the Administration > Configuration > Basic page.

What I really wanted to do was change the accent colors in the interface, as well as hide some areas of the interface that I felt were unnecessary given the way I use Peertube1. Custom CSS can be entered on the Administration > Configuration > Advanced page.

I wanted to post my CSS customizations here in case anyone finds them to be useful. Note that these are most likely specific to the dark theme I am using, so they may require tweaking if you are using a different theme. I was able to do some cool things like hide the entire menu drawer and publish button if you aren’t logged in!

/* Change colors */
body#custom-css {
  --mainColor: #f92672;
  --mainColorLighter: #e5789b;
  --mainColorLightest: #dbdbdb;
  --mainHoverColor: #9f1f49;
  --secondaryColor: #98BE47;
}

/* Fix the background of the playlist info section in the dark theme */
.playlist-info {
  background-color: transparent !important;
}

/* Hide the publish button, the menu button, and the drawer if not logged in */
#custom-css > my-app > div.peertube-container.user-not-logged-in > div.header > div.header-right > my-header > a,
.user-not-logged-in > .header > .top-left-block > .icon-menu,
.user-not-logged-in > .sub-header-container > .ng-star-inserted > .menu-wrapper
{
display: none !important;
}

/* Fix the spacing when the menu is hidden and you aren't logged in */
.user-not-logged-in > .sub-header-container > .main-col {
  margin-inline-start: 0px;
  width: 100%;
}

/* Hide various other things */
.login-buttons-block, /* login buttons, I just login by going to /admin */
.block-title, /* hide the "on video.jadin.me" thing */
div.active-filter  /* hide the filter badges*/
{
  display: none !important;
}

  1. For instance, the sensitive content filter. I don’t have any of that on my PeerTube instance, so that button is unnecessary ↩︎

Adding a warning when trying to close an unsubmitted form in Gravity Forms

Blogging this before I forget it!

I needed to add a warning to a form in Gravity Forms in case someone started filling out a form but forgot to click the submit button before closing the page. I’ve seen plenty of pages do this before, and figured there might be away to easily do something like this in Gravity Forms.

There isn’t a built-in feature in Gravity Forms for this, but it turns out that using jQuery you can easily check if someone has clicked on any of the form inputs, and if they try to close the page throw up a warning. I found this snippet on the Gravity Forms community forum and it works well:

<script>
    var userStartedForm;
    jQuery(document).on('focus', '.gform_wrapper input', function(){
        userStartedForm = true;
    });
	jQuery(window).on('beforeunload', function(){
        if(userStartedForm){ return ''; }
    });
</script>

You can then copy and paste that script into an HTML field in your form:

Neat!

February Community Chat – State of Reclaim

On February 9th1 we had our second Community Chat at Reclaim Hosting, this one called State of Reclaim!

It was a breakdown of what each group at Reclaim has been busy with, as well as what they are looking ahead towards. We also had Tim talk about early work on the Domains API.

Here’s the recording:

Also, here are some of the links for follow up that were mentioned in that recording:

It was exciting to see so many folks from the Reclaim Community show up, and there was a lot of great discussion around some things Domains admins need and are wondering about. Better documentation for Domain of One’s own was brought up, and is something that’s definitely on our radar, there was interest in more workshops for new Domains admins or refreshers for those who want that, but also the idea of a more advanced workshop for DoOO admins who are looking to learn more about managing the platform efficiently.

I was also really happy with the video platform we used! I upgraded the Jitsi install we have at meet.reclaimhosting.com and did some testing to make sure I was comfortable with it. This Jitsi install is hosted on Reclaim Cloud, and was installed with the Marketplace installer available there, so it was really fast and easy to get things set up! Not only that, the resource usage during the event was very minimal. During the entire event, the usage topped out at 22 cloudlets! Looking at the reporting after the fact, the event cost 8 cents to run on Reclaim Cloud for that hour of higher usage 🙂


  1. Yes, I know I’m behind on blogging this one… ↩︎

January Community Chat

Yesterday, Reclaim Hosting had its first “Community Chat” and I got to host it. The chat was focused around a site template I put together that is intended to help Domains admins showcase the work students, staff, and faculty are doing on their campus. The idea of making tools to build community around domains is not new at all, but I was hoping to make something that schools that were new to DoOO could get started with and would be simple and flexible enough to grow with their needs over time. If there happens to be a Domains admin reading this, reach out to support@reclaimhosting.com and we can put the template on your server. I’m thinking if this template works out well for people, it may be something we build into the DoOO setup for new schools.

The template is just a simple Gravity Forms powered web form that asks for a URL, screenshot, and some information about the website that one might want to feature. It then creates a post in WordPress that’s pending review. I’ve got a demo of the final product here: demo.jadin.me

As well as demoing the site template, I also wanted to use the community chat to talk more broadly about building community, and I was really encouraged by how many people spoke up in the chat and unmuted their mics. There is a recording of the community chat below:

There are also a few nuts and bolts things that I wanted to document about the event itself. For signups, I just used a simple Google Form. I then installed the formLimiter add-on on the form to automatically stop registrations after the event was over. You can also use that add-on to shut off registrations after a certain number of people sign-up or a few other conditions; it’s pretty handy. In addition to this, I wanted to see at a glance which schools had more than one person register, so I used conditional formatting in Google Sheets with this custom formula to find duplicate entries in the relevant column (which happened to be column E): =countifs(E:E,E1)>1

Finally, I used the Form Mule add-on for Google Sheets to do a mail merge to let folks who registered know how they could join the call. I’ve used this add-on many times before, and the cool thing about this particular add-on is it is free to use (developed by New Visions for Public Schools) and it can be set to run as soon as someone fills out your form, which is great for catching late signups.

I’m excited about future community chats but there are some things I immediately want to fix for next time. We used Whereby as our video platform, which I’m a big fan of due to its simplicity, but its recording capabilities are limited. For recording, it basically takes a capture of the browser tab, which means that if you resize the window, it changes the effective1 resolution of the recording. It also means you can see the host’s mouse moving around and clicking on stuff. You can see both of these things in the above recording. Now that I know about these limitations, I can avoid them next time, but it might also be worth exploring different platforms for these chats in the future.


  1. affective? effective? ↩︎

A simple landing page for stuff I run in Reclaim Cloud

I haven’t revisited it in a while, but one of my favorite little projects I dug into at the beginning of the pandemic was making my own little radio station using Azuracast. I need to get back to that, but one of the things on my checklist was to make a small improvement to the landing page for it, radio.jadin.me.

The look of the landing page I was already pretty satisfied with, it’s just an HTML5UP template that I customized and slapped the embedded player from azuracast on, but I wanted the page to automatically show that the stream was offline when I have Azurcast stopped in Reclaim Cloud to save money. I was doing this manually by just commenting out bits of the HTML that included the player whenever I would shut the station down, but I knew there were better ways to do this. I just didn’t have the time to investigate.

Why bother with this at all? Well, if I left the page the same when the Azurcast instance I had in Reclaim Cloud was shut down, the page would look like this:

radio.jadin.me landing page with an error box in the middle

Nothing wrong with that I suppose, but I would prefer a nicer looking page:

radio.jadin.me landing page with a nice &ldquo;stream offline&rdquo; message

People who know anything about PHP will probably find this obvious, but the solution for me (credit to Tim Clarke for suggesting I look into this like a year ago!) was to make a simple page that uses PHP to check if Azuracast was available, then display different content based on that. There are a lot of simple ways to do this, but I just made two pages, online.html and offline.html, that look how I want them to look when the station is available or not. Then with a little bit of research, I put together an index.php that just returns the appropriate version of the page if the Reclaim Cloud environment is online. Basically, I just put the url to the environment in the $url variable, and if that returns an HTTP response status code of 200 (which means things are working), it will load online.html. If it receives something different, it loads offline.html instead. You can see the script below:

index.php

<?php
$url = 'https://radiosrv.us.reclaim.cloud/public/radio.jadin.me/embed';
$online = 'HTTP/1.1 200 OK'
$headers = @get_headers($url);
if(!$headers || $headers[0] == $online) {
    // Hey we are online
    readfile("online.html");
}
else {
    // Offline
    readfile("offline.html");
    // Uncomment the following line to see what the status currently is
    // echo($headers[0]);
}
?>

You can also see on the third to last line that I made a section that will actually put the current HTTP status code at the bottom of the page (if you uncomment that line). This is in case whatever application you are running returns something other than 200, like 302 (which would be a redirect). If the $online variable doesn’t match what code your application returns when it is running this whole setup won’t work. If that is the case you would delete the two slashes at the beginning of the line, load the web page, and it will show you that code:

radio.jadin.me with an http status code at the bottom of the page

Then you would simply change the $online variable in index.php to that error code it gave you.

So with that done, I threw index.php, online.html, and offline.html on my subdomain using my FTP client and I was ready to go! Now when I start my radio station in Reclaim Cloud, my radio.jadin.me landing page automatically shows that the station is online!

I think this simple method has a lot of potential. I could see having a landing page that checks to see if a Reclaim Cloud environment is spun up, and if it is, take you there with a redirect. If it’s not spun up, it could do a lot of things. Maybe the page tells you to contact the owner of that account, or maybe even spin the environment up automatically via thhe Jelastic API? (possibly after entering a password). I’ll have to keep exploring this 😀

css.php