At work, we use remote compute instances (analogous to EC2) for development. In order to do any work, we connect to this remote instance (also known as VM) via SSH and carry out our duties. Due to the inherent nature of remote development, I am heavily dependent on the connection health. However it is beyond my control, so all I can do is pray to god. Or can I? After 6 months of development, I have learned from the pain points, and optimised my workflow. This blog describes the problems I faced and how I resolved them

I have taken a page from the book “Effective Engineer”. This book talks about how ironing out small wrinkles in your daily workflow can have massive impact. Even a 2-minute optimization, when repeated, saves a substantial amount of time and keeps me focused.


Logging via private key

Every time I SSH into my VM, it prompts for password. If the connection is unstable, a disconnection, even for a split second, will prompt me for password again. This pain of re-entering password is common in CLI as well as VSCode. Though VSCode is slightly nicer, it auto detects disconnection and attempts a reconnection, but still prompts for password

SSH Login

To mitigate this pain point, I setup a private key and log into the VM with it. Here is how I achieved it:

Step 1: Generate key pair

$ ssh-keygen

The utility above will generate a SSH key pair. By default, the location of the generated keys will be ~/.ssh folder. Private key will be called id_rsa, and the public key will be id_rsa.pub. We will upload the public key to the server

Step 2: Configure remote server to accept the generated keys

We need to copy the public key to the remote server. Use the following command for that:

$ cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

The first cat command, takes your local public key that we just created. Then the ssh command logs into your VPS, creates a ssh folder (if not already present) and copies the public key into a file called authorized_keys

You should be able to perform SSH via your private key now, without password


SSH shortcut to directly connect to server

I am a lazy person. I don’t like writing the full command, ssh username@host, everytime I want to log in. I need a shortcut. A SSH shortcut is just the solution I want.

To achieve this, open your SSH config (resides at ~/.ssh/config). Add the following

Host shortcut_i_want
    HostName vm_hostname (or IP)
    User username
    IdentityFile /path/to/private/key

Now, I can use the shortcut_i_want defined above to login directly by using the following command:

ssh shortcut_i_want

SSH Tunnel

I use VSCode for remote development. If I run any server, VSCode will automatically detect the port and conveniently setup an SSH tunnel, so that I can access VM’s port on my machine.

However, at my work I need to run multiple servers, 3 to be precise. Three servers with remote tunnel slows down my VSCode dramatically, preventing efficient work. To make the setup performant, I resort to native SSH tunnel instead of relying on VSCode

To achieve this, in SSH config, (same place where we setup the SSH shortcut), we can add one more host for port forwarding as follows:

Host port-forward
    HostName vm_hostname (or IP)
    User username
    IdentityFile /path/to/private/key
    RequestTTY: no
    RemoteCommand echo "Tunnelling connections. CTRL+C to terminate connection"; cat
    LocalForward local_port_1 remote_address_1 # format
    LocalForward 8080 localhost:8080 # example
    LocalForward local_port_2 remote_address_2 # add as many ports as you like

TMUX

There are two problems related to terminal connection that I was still facing.

  1. As a developer I need access to multiple terminals to be effective. Firing a new SSH connection per terminal is little tedious.
  2. Due to the nature of remote work, sometimes the connections are lost. If I am in middle of an important workflow, the lost connection means lost work. I need a persistent connection

Both of my problems gets resolved by TMUX. Tmux is a terminal multiplexer, and runs in separate process from the main terminal. I can fire up multiple terminals. Log out and connect to the same terminal again. All without losing the session

Tmux quick demo Starting tmux, firing up multiple terminals. Detaching and re-attaching to the same terminal

Ideas I have not implemented yet

There are more ideas I have, but the output productivity boost has not (yet) justified, the amount of efforts required.

1. TMUX Scripts

One of the applications I work on, requires me to start 3 servers to function. A single command to boot up entire application would be great. However, I rarely work on this application. Automated start of servers via scripts will require an investment of 10-12 hours. An investment this high to save efforts of writing just 3 commands is simply not worth it. So, I have not implemented this

2. Learn vi and move to NVIM

Initially, my VSCode used to get stuck randomly. I had explored NVIM as an option. Coding directly from terminal will save me a lot of bandwidth and memory usage. However, the root cause was lack of RAM in the system. I got my RAM upgraded, and haven’t faced the issue since. So abandoned the idea