Running tmux on a Synology NAS

This is a short tutorial on how to use tmux on a NAS, without installing any unofficial package. I am using this on a Synology NAS running DSM 7.1—the current version at the time of this writing—but the same technique will work on any device which supports Docker.

Before starting, I must say that tmux is available from SynoCommunity, in a package called “SynoCli Network Tools”. SynoCommunity is a reputable and trustworthy source, but I decided not to install any unofficial package on my Synology, since I want absolute stability.

The Problem

Modern NAS devices pack considerable computing power, and can have a very decent amount of RAM: they can do much more than storage. I often need to do analysis on big volumes of data, and I prefer to avoid doing it on my laptop (limited storage, heat, etc.). I can connect to the NAS with SSH but, having to rely solely on nohup for long processes, can be pretty limiting. To give you an example, a couple of weeks ago I wanted to move a 5 TB folder to a MinIO server: the simplest way I could find was to use MinIO Client (with the mc cp command). I was going to run the mc cp command from a MinIO Client container, to move data from a shared folder on the NAS to a MinIO Server container.

Since I knew that the process would have taken a couple of days at least, I wanted to avoid having to keep a terminal open and rely on a stable network connection for all that time. I could have possibly run something like nohup mc cp on the client container, but I am uncertain if that is even possible, and I preferred to keep the process running in a shell.

The Solution

My solution is simple: I used a third container—based a basic alpine image—with the addition of tmux and OpenSSH. The idea is to run tmux inside the container, and ssh back to the host. I am no Docker expert, but this is the Dockerfile I used:

FROM alpine:latest
RUN apk add openssh
RUN apk add tmux
# The following command is just to keep the container alive once started
CMD tail -f /dev/null

From the directory containing the Dockerfile, I just did the following:

  1. Build the image: docker build -t alpine_tmux .
  2. Start a container based on the new image: docker run -d --rm --name tmux alpine_tmux:latest
  3. Start a shell: docker exec -it tmux sh
  4. SSH into the host: ssh your_username@$(/sbin/ip route|awk '/default/ { print $3 }')1

If you want to avoid building the image, I have published the one I use (please note that I have added a couple of other tools) to it. The image is on Docker hub, if you want to use it, you can skip point 1, and replace the command at point 2 with: docker run -d --rm --name tmux tagliasteel/tmux_ssh.

Once the work is done, I just stop the container with docker stop tmux, and docker cleans everything up (since the container was created with the --rm option).

Final Thoughts

When I don’t need to run commands on other containers, I prefer to just map the volumes I need (adding -v to the docker run command above), and install everything I need inside the container. I like the alpine image because it’s extremely minimalistic, of course I would choose a more appropriate image if I needed to do something very specific.

Nothing here is particularly complex but, as a docker newbie, it took me a while to come up with this solution. I hope it will be useful to others facing the same issue.

  1. The /sbin/ip route|awk '/default/ { print $3 }' command simply outputs the IP address of the host.