A remote dev box is only useful when you can SSH in and immediately pick up where you left off. That means tmux must be running before you arrive, your named session must exist, and reattaching must be a single command. This guide wires all three: a boot-created session via systemd, an attach-or-create alias, and a layout that survives reboots.
The problem with starting tmux manually
If tmux only starts when you SSH in and run tmux new-session, two things go wrong:
- After a reboot, the server is bare until you manually recreate your session.
- If you SSH in from a second terminal before starting tmux, there is no session to attach to — you get a raw shell instead of your workspace.
The fix is to have tmux create the canonical session at boot, independently of any SSH connection. systemd user services are the right tool for this.
systemd user service
Create the service file at ~/.config/systemd/user/tmux.service:
[Unit]
Description=tmux default session
After=network.target
[Service]
Type=forking
ExecStart=/usr/bin/tmux new-session -d -s main
ExecStop=/usr/bin/tmux kill-session -t main
KillMode=none
Restart=on-failure
[Install]
WantedBy=default.targetKey details:
- Type=forking:
tmux new-session -ddaemonizes (detaches immediately). systemd needs to know the process forks so it does not consider the service failed when the foreground process exits. -d: detach immediately after creating the session.-s main: the session name. Pick any name;mainis a readable default.- ExecStop: cleanly kills the session when you run
systemctl --user stop tmux. Without this, systemd kills the tmux server process directly, which may leave child processes orphaned.
Enable linger so the service runs without a login session
systemd user services normally only run while the user has an active login session. On a server, that means the service would stop when you disconnect. Linger removes that restriction.
loginctl enable-linger $USERThis is a one-time command. After enabling linger, systemd starts user services at boot and keeps them running even when no one is logged in.
Enable and start the service:
systemctl --user daemon-reload
systemctl --user enable tmux.service
systemctl --user start tmux.serviceVerify it is running:
systemctl --user status tmux.service
tmux list-sessionsYou should see main: 1 windows (or similar) from list-sessions even before you have attached.
The attach-or-create alias
The -A flag to tmux new-session attaches to an existing session by that name if one exists, and creates it if it does not. Combined with -s main, this gives you a single command that always lands you in your workspace.
alias t='tmux new-session -A -s main'Add this to your ~/.bashrc or ~/.zshrc. Now t is the only command you need to type after SSHing in. If the systemd service created the session at boot, you attach to it. If the session was somehow absent, a new one is created under the same name.
SSH config for a one-keystroke workflow
On your local machine, add a host entry in ~/.ssh/config:
Host vps
HostName 203.0.113.10
User ahmed
IdentityFile ~/.ssh/id_ed25519Now ssh vps connects, and if you add tto your shell's login init (or just muscle-memory type it), you are in your workspace in two commands. Some people set RemoteCommand tmux new-session -A -s main in the SSH config to attach automatically, but that prevents interactive SSH commands like ssh vps 'git pull' — it is a tradeoff.
Organizing windows in the boot session
A single tmux session with named windows is enough for most server workflows. You can pre-create windows in the service by chaining tmux commands in ExecStart, but this gets unwieldy. A simpler approach: use a setup script that the service calls on first run, or just create windows manually once and rely on tmux-continuum to restore the layout after reboots.
# example: pre-create named windows at session start
# (add to ExecStart after new-session, or run manually once)
tmux new-window -t main -n code
tmux new-window -t main -n logs
tmux new-window -t main -n opsWith tmux-continuum configured (@continuum-restore 'on'), these windows are automatically restored on the next boot. The systemd service creates the bare session; continuum restores the saved layout on top of it within seconds.
Verifying persistence after a reboot
# reboot the server
sudo reboot
# after reconnecting (wait ~30 seconds)
ssh vps
tmux list-sessions
# should show: main: N windows (created ...) [attached]If the session is absent after reboot, check linger status and service logs:
loginctl show-user $USER | grep Linger
journalctl --user -u tmux.service --since "5 minutes ago"The most common failure mode is forgetting loginctl enable-linger. The service file is correct but linger is off, so systemd tears down the user slice — and the service with it — when the last session closes.
Multiple named sessions
If you run more than one project on the same server, separate sessions by project rather than stacking everything into windows on one session. Each session has its own window list and status bar, making context switching clean.
# alias per project
alias t='tmux new-session -A -s main'
alias tc='tmux new-session -A -s care90'
alias td='tmux new-session -A -s dars'The systemd service only creates main at boot. The other sessions come alive when you first attach and are saved/restored by continuum from that point forward.
For running parallel Claude Code sessions across these sessions, see the tmux + Claude Code layout guide.