Self-hosted service
lima-vm/sshocker avatar
lima-vm/sshocker

sshocker is docker run syntax pointed at a remote host

ssh + reverse sshfs + port forwarder, in Docker-like CLI (predecessor of Lima)

658 stars33 forksGoApache-2.0

At a glance

What is it?
sshocker is an Apache-2.0 Go tool that mounts a local directory onto a remote machine over reverse sshfs and forwards a port, with a command line deliberately shaped like docker run, and the project describes itself as the predecessor of Lima.
Who is it for?
sshocker fits a developer who needs to run code on a remote Linux machine while editing files locally, and wants the port forwarding and the file mount to be one command rather than two background SSH sessions. It does not fit a Windows environment, which the README says may not work, and it is not the tool to reach for in new work, since its own description calls it the predecessor of Lima.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 53 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The same mental model as docker run, aimed at a host

sshocker packages three things into one command: ssh, reverse sshfs, and a port forwarder, presented in a Docker-like command line. The README is explicit that it is the predecessor of Lima, and that it is for remote hosts rather than containers.

The whole interface is one line:

console
$ sshocker -p 8080:80 -v .:/mnt/sshfs [email protected]

The README then decodes the two flags. Forwarding connections to port 8080 on the client to port 80 on example.com, and mounting the current directory on the client as /mnt/sshfs on example.com.

The comparison it draws is with docker run -p 8080:80 -v $(pwd):/mnt IMAGE, and the difference is the target. The mapping is deliberately identical so that the muscle memory transfers, and the sentence in the README that this is for remote hosts, not for containers, is the entire pitch in one clause.

What is happening underneath is that the client keeps an SSH connection open to the remote machine and, over that connection, mounts the local directory into the remote filesystem and opens a local port that forwards to a remote one. The direction of the mount is the point: the files stay on the laptop and appear on the server, which is the opposite of what sshfs normally does and is what makes a remote build possible without syncing.

Getting the binary, or building it

The documented install is a download from the GitHub releases page, and the curl form builds the asset name from uname, which is how the release artefacts are named:

code
curl -o sshocker --fail -L https://github.com/lima-vm/sshocker/releases/latest/download/sshocker-$(uname -s)-$(uname -m)
chmod +x sshocker

The naming convention is the same one the Makefile uses for its cross-compilation targets, where the file names look like sshocker-Linux-x86_64, sshocker-Linux-aarch64, sshocker-Darwin-x86_64 and sshocker-Darwin-arm64. The Makefile also carries a comment about the Unix convention of ./bin/sshocker-$(uname -s)-$(uname -m), so the layout is consistent between what a release publishes and what a local build produces.

Building from source is two commands:

console
make
sudo make install

The Makefile makes the build reproducible in a small way worth noting. The version string is taken from git describe with a dirty suffix, and it is injected at link time with -X on the version package, so a build from a working tree identifies itself as dirty rather than pretending to be a release. The binary is built with CGO_ENABLED=0, and the Makefile checks on Linux that the result is statically linked, which is the kind of check that only makes sense for a tool you are about to copy onto a remote machine.

The run subcommand and the flags it copies from docker

The subcommand run is the default, so it can be omitted, and the README shows both forms, with the explicit one being:

console
$ sshocker run -p 8080:80 -v .:/mnt/sshfs [email protected]

The two container-like flags are the core of the interface. The -v flag takes LOCALDIR:REMOTEDIR, with an optional :ro suffix, and mounts a reverse SSHFS. The -p flag takes the form [[LOCALIP:]LOCALPORT:]REMOTEPORT and exposes a port.

The SSH flags are passed through rather than reimplemented. The -F or --ssh-config option specifies the SSH config file used for ssh -F, so a user with a complicated host setup keeps using their existing file. The --ssh-persist option, defaulting to true, enables ControlPersist, which is what keeps the connection alive between invocations instead of re-authenticating each time.

There is one SSHFS-specific flag, --sshfs-noempty, defaulting to false, which enables the sshfs nonempty option. The map of an empty directory to an empty directory on the server, rather than to the user's home directory, is the behaviour that trips people up, and having a switch for it is the difference between a usable tool and an annoying one.

The SFTP driver choice is the security decision

The one flag in this tool that deserves a security review is --driver, which selects the SFTP server driver and defaults to auto. There are two values, builtin, described as legacy, and openssh-sftp-server, described as robust and secure and recommended.

The auto default is not a fixed choice. The README says openssh-sftp-server is chosen by default when the OpenSSH SFTP Server binary is detected, and that the binary is detected automatically when installed in well-known locations such as /usr/libexec/sftp-server. There is also an --openssh-sftp-server flag to point at the binary explicitly, for the case where it lives somewhere else.

The reason this matters is the direction of the mount. The server is serving files back to the client over the SSH connection, and the server side component that does that is a process running on the remote host. A legacy builtin implementation is a second implementation of that service, written by the project, sitting on a machine you may not fully control. The OpenSSH implementation is the one that ships with the SSH server most administrators already patch and audit.

So the practical advice is to check what auto picks on the host you are about to use, and to pass --driver=openssh-sftp-server explicitly if the detection is wrong rather than letting the fallback happen silently.

Reverse sshfs needs sshfs on the server, not the client

One requirement is easy to get backwards, and the README calls it out directly: to use reverse sshfs, sshfs needs to be installed on the server and not on the client.

console
$ ssh [email protected] -- sudo apt-get install -y sshfs

That command is the whole installation step for the server side, and it doubles as a connectivity test, since it uses the same ssh you will use for the mount. The convention of running the command through ssh with a remote sudo is worth keeping, because it avoids the need for a second mechanism to become root on the remote machine.

The design reason for the requirement is inherent to reverse sshfs. The mount lives on the server, so the server needs the FUSE filesystem component to present it, and the client needs the matching library to serve the files over the connection. Splitting the requirement across the two machines is the price of the direction.

There is a security consequence to keep in mind here. Mounting a local directory into a remote host means the remote machine, and anything running on it, can read and write those files. That is the feature, but it also means the remote host is inside your trust boundary for the duration of the mount, which is worth saying out loud before pointing it at a shared machine.

The alternatives, and why the project is the predecessor of Lima

The alternative to sshocker is doing it by hand, which is entirely possible and is what most people do before they find a tool.

A port forward is a single ssh with a remote option. A reverse mount is an ssh command with the remote filesystem option and a path, plus a matching sshfs process on the remote side. Each of these is a background process to start, a port or path to keep track of, and a second thing to remember when the work is done. The value sshocker adds is that the two are expressed in one command with the syntax people already know from container tooling, and that it exits when the work is finished.

The other alternative is Lima, and the README's own framing settles it. sshocker is the predecessor of Lima, so a new project that wants a Linux virtual machine for development should look at Lima, while a project that wants to run against a real remote Linux server with a mounted working directory has a use case that sshocker still covers.

That distinction matters, because the two tools overlap only superficially. A virtual machine local to your laptop and a remote server you ssh into are different problems, and the port forwarding and filesystem semantics that make sshocker useful on the second are not what Lima is for.

Apache-2.0 terms, a small dependency set, and the release trail

The licence is Apache-2.0, with the LICENSE file at the repository root. The module is github.com/lima-vm/sshocker and it requires Go 1.25.0 or newer.

The dependency list is three direct modules: github.com/pkg/sftp for the SFTP client side, github.com/sirupsen/logrus for logging, and github.com/urfave/cli/v2 for the command line interface. The indirect set is the standard transitive tail of those three, including golang.org/x/crypto and golang.org/x/sys, and the markdown and metrics libraries that come with the CLI framework. That is a small footprint for a tool that will be run on someone else's machine, and it is consistent with the CGO_ENABLED=0 static build.

The repository layout follows the Go convention with cmd/ for the entry point, pkg/ for the library code, a Makefile and a go.mod with a go.sum. The last push was on 2026-08-31 and the repository is not archived.

The release history is short and mostly patch level. The most recent tags are v0.3.11 on 2026-07-21 and v0.3.10 on the same day, with v0.3.9 on 2025-11-24 before them. Two releases minutes apart suggests a rebuild or a packaging fix rather than two features, and the project is still on a 0.3 line, which is consistent with a small utility that is maintained rather than developed in public.

Editorial conclusion

sshocker fits a developer who needs to run code on a remote Linux machine while editing files locally, and wants the port forwarding and the file mount to be one command rather than two background SSH sessions. It does not fit a Windows environment, which the README says may not work, and it is not the tool to reach for in new work, since its own description calls it the predecessor of Lima. Before adopting it, decide which SFTP server driver you want, because the default switches between the legacy builtin server and openssh-sftp-server depending on what is detected on the remote host, and remember that the server needs sshfs installed for the mount to work.

Frequently asked questions

What does sshocker do in one command?

It opens an SSH connection to the remote host, mounts the current local directory there over reverse sshfs, and forwards a local port to a remote port. The README compares it to docker run -p 8080:80 -v $(pwd):/mnt IMAGE, with a remote host in place of a container image.

How do I install sshocker?

Download the release binary from the GitHub releases page, with the curl form using sshocker-$(uname -s)-$(uname -m) as the asset name, or build from source with make followed by sudo make install. The README says it was tested on a macOS client and a Linux server.

Where does sshfs need to be installed?

On the server and not on the client. The README shows the step as ssh [email protected] -- sudo apt-get install -y sshfs, because the reverse mount is presented on the remote side.

What does the --driver flag do?

It selects the SFTP server driver, with auto as the default. The values are builtin, described as legacy, and openssh-sftp-server, described as robust and secure and recommended, which is chosen automatically when the OpenSSH SFTP Server binary is detected in a well known location such as /usr/libexec/sftp-server.

Is sshocker still the tool to use for remote development?

The project describes itself as the predecessor of Lima, so new virtual machine based development should look at Lima. sshocker remains a compact way to mount a local directory on a remote server and forward a port in a single command, under the Apache-2.0 licence.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. lima-vm/sshocker on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/lima-vm-sshocker.svg)](https://hysenlabs.com/projects/lima-vm-sshocker)

Was this useful?