Kasm Workspaces on fly.io - Having Trouble

Hey there!
I have been wanting to try out KASM Workspaces for a while, but I could not because my Raspberry Pi was not supported. However, I have recently learned more about fly.io, and have thought that it may be possible to run KASM on it. Heres the current issues I’m running into:

  1. Not enough resources. Kasm’s docs recommends a lot more resources than regular fly.io free machines. However, this can be solved with a paid plan or a scaled-up machine (I think).
  2. Issues while installing: these issues don’t appear using other hosts (like Linode) but they do on fly. Specifically I can not get past “error in YAML” messages. This may be something to ask the Kasm Community instead of the Fly community.

Thank you,
Gav

If you want help you should post the full error message and the steps you used (are you using their standard install, or a container such as linuxserver/kasm?)

Standard install.
Heres the error (im in the ssh console):

Checking if DEFAULT_PROXY_LISTENING_PORT (443) is free
Port (443) is not in use.
Checking if docker and docker compose are installed.
ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
errors pretty printing info
Docker is installed
Unable to check Docker version, is the Docker daemon running?
Aborting Kasm Workspaces install

I am a bit new to linux aswell, as i have used windows for a while.

What base image are you using? E.g. Debian sets /usr/sbin/policy-rc.d to disable services from starting automatically, so you’d have to start Docker manually using service docker start.

Note that if you execute the install commands using SSH, then everything will be lost when the VM restarts (unless you use a persistent volume for the filesystem, which is tricky). So you’ll probably want to put the install commands in a Dockerfile and build an image with Kasm (will probably have more luck with their offline install).

Or just use a pre-built image like the one I mentioned (it’s third party but seems reputable); or look at their Dockerfile for inspiration.

Sorry for the late reply, didnt have emails enabled.
As someone brand-new to docker/linux/kasm and all of that, could you guide me with the prebuilt image? It seems a lot easier and im just kindof a dumb-dumb when it comes to docker containers and stuff.

No worries. I can give you a rough sketch:

To start with, try deploying the image locally (makes debugging easier). Follow the “docker cli” instructions on https://hub.docker.com/r/linuxserver/kasm.

Once you get that working, the basic command to deploy the image to Fly is fly launch --image linuxserver/kasm, but there are complications:

  1. The image starts a setup wizard on port 3000 for setting passwords etc. You’ll need to access that wizard using port forwarding (fly proxy), or find a way to automate the setup (see here for how the wizard sets the passwords).

  2. Kasm only supports HTTPS out of the box (issue), which is a pain because the normal setup on Fly is to have Fly do the the TLS termination and talk to your app using HTTP. Some options:
    (a) As a temporary hack, use fly proxy to access Kasm’s port 443 directly, as with the wizard.
    (b) Run a reverse proxy that listens on port 8080 for HTTP connections and forwards them to port 443 using HTTPS; see using Kasm’s reverse proxy configuration.
    (c) Disable SSL by modifying the image. See the linked issue for some helpful comments.

  3. You’ll want to use persistent volumes, because anything outside a persistent volume will be lost when the Fly VM restarts. Based on the image documentation it looks like /opt should be on a persistent volume, and I’m guessing Kasm’s PostgreSQL database (which has the passwords etc.) will also need to be on a persistent volume.

When you get stuck, post the full steps you used and the full error messages.

Thank you so much!

I deployed using the fly launch --image linuxserver/kasm command you shared, but it keeps spamming the same error (shown here) and stops after 10 restarts. It seems to be with the app running on an incorrect process id, (as it literally states that). EDIT: looked online, and it seems setting init: false in kasm’s docker compose file would fix it. How would I do this when using the --image argument?

Still, thank you for helping.

See a workaround to run init with PID 1. In your case, you’ll need to create a file init-wrapper with the script from that comment, mark it executable (chmod +x), and add a Dockerfile that looks like this:

FROM linuxserver/kasm

# emulate PID 1
COPY init-wrapper /
ENTRYPOINT ["/init-wrapper"]

# switch from nftables to legacy iptables, otherwise /usr/local/bin/dockerd-entrypoint.sh fails
RUN \
    update-alternatives --set iptables /usr/sbin/iptables-legacy && \
    update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy

The last part (update-alternatives, source) is to fix the following error:

failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables v1.8.7 (nf_tables): Could not fetch rule set generation id: Invalid argument

Then use fly launch (without an image argument), and it will use the Dockerfile to build a custom image based on linuxserver/kasm but with init-wrapper to emulate PID 1.

Check fly logs to make sure there are no errors, then run fly proxy 3000 and open https://127.0.0.1:3000 (you’ll get a security warning due to Kasm’s self-signed certificate, that’s fine).

Thank you! I will try this as soon as I get the chance.

I’ve tried the steps, but it seems like its not running on the fly app.
Heres logs: Hastebin
Port 3000 just shows a page not found error
I simply added the init-wrapper, the dockerfile, and did fly launch with a basically empty fly.toml (just app name and primary region)

It works for me (though the installer ran out of memory on a free 256MB instance).

Your logs look fine. Don’t forget to run fly proxy 3000. You can enable debug logging in the proxy by setting the environment variable LOG_LEVEL to “debug”: LOG_LEVEL=debug fly proxy 3000. This will spew out a lot of stuff, the important bit is that when you connect with a browser you should see either:

DEBUG accepted new connection from: 127.0.0.1:...
DEBUG connection closed

meaning the connection succeeded, or something like:

DEBUG accepted new connection from: 127.0.0.1:...
DEBUG failed to connect to target: connect tcp [...]:3000: connection was refused

meaning there is no listening process on the VM.

You can also start an SSH session using fly ssh console then run curl --insecure https://127.0.0.1:3000, it should output

<!DOCTYPE html>
<html>
  <head>
    <title>Kasm Wizard</title>
...

The page not found error you mentioned sounds odd, I would have expected a connection error. A screenshot or exact error message might be helpful.

Just tried again, and getting this after proxying:
image
and this when curling:

root@c505d7b3:/# curl --insecure 127.0.0.1:3000
curl: (52) Empty reply from server

You must use https, not http (due to the unusual way Kasm works).

Thank you! I’ve finally got the wizard to work.
Ive scaled up to 512mb memory, but what do you recommend I scale to for smooth-running kasm?

After running the wizard for a bit (with Brave and Ubuntu selected) i get this:

unexpected EOF
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Great. I don’t have a personal recommendation for the memory size. The docs say the minimum requirement is 4GB, but the actual memory usage will heavily depend on what sort of containers you run.
Don’t forget to set up persistent volumes, otherwise all state will be lost when the Fly VM restarts.

Regarding the error, check the Fly logs – that’s where error messages from dockerd will appear. The linuxserver/kasm image sets dockerd’s -l/--log-level option (docs) to errors-only, so if you don’t see anything you can increase the log level to the default (“info”) by adding the following to your Dockerfile:

RUN sed -i 's/ -l error//' /etc/s6-overlay/s6-rc.d/svc-docker/run

Sorry for a late reply.

I am now getting a different error when deploying. Right after doing fly deploy, I get:

Watch your app at https://fly.io/apps/notwindows/monitoring

Provisioning ips for notwindows
  Dedicated ipv6: 2a09:8280:1::4e:3239
  Shared ipv4: 66.241.124.189
  Add a dedicated ipv4 with: fly ips allocate-v4
This deployment will:
 * create 2 "app" machines

No machines in group app, launching a new machine
  Machine e286565da413d8 [app] update finished: success

WARNING The app is not listening on the expected address and will not be reachable by fly-proxy.
You can fix this by configuring your app to listen on the following addresses:
  - 0.0.0.0:8080
Found these processes inside the machine with open listening sockets:
  PROCESS                | ADDRESSES                           
-------------------------*-------------------------------------
  /.fly/hallpass         | [fdaa:1:4fb4:a7b:f8:1df:cf10:2]:22  
  /usr/bin/node index.js | [::]:3000                           

Creating a second machine to increase service availability
  Machine 32874599c43d38 [app] update finished: success
Finished launching new machines

NOTE: The machines for [app] have services with 'auto_stop_machines = true' that will be stopped when idling

Updating existing machines in 'notwindows' with rolling strategy
  Finished deploying

Visit your newly deployed app at https://notwindows.fly.dev/

As stated in the error, fly proxy 3000 doesnt proxy it.
I tried changing the http_service > internal_port to 3000 and trying both the fly.dev link and proxying 3000 but it doesnt work.

It still works for me.

Fly recently started auto-stopping VMs by default; make sure you change auto_stop_machines to false in fly.toml. And remember to use HTTPS.

The warning is to be expected. As I mentioned earlier, Kasm doesn’t play nicely with Fly’s standard port forwarding. The simple workaround is to use fly proxy instead. To get the .fly.dev domain to work, you’ll need a more complex solution (e.g. option 2(b) or 2(c) from above). And remember that port 3000 is just for the setup wizard; the actual Workspaces interface runs on port 443.

If you get stuck, post more details (the output of curl in an SSH session, and the exact error message you get when you run fly proxy 3000 and open https://127.0.0.1:3000).