How Docker Namespaces and fixuid Broke My Tmux Autosaves

If you use tmux heavily, you probably use tmux-continuum to automatically save your sessions in the background. Recently, my autosaves just... stopped. No errors, no crashing, just silent failure.

After dropping into the terminal to debug, I stumbled into a fascinating edge case involving Linux kernel namespaces, Docker, and user permissions.

Here is how a perfectly configured Docker container broke a host-machine shell plugin.

The Phantom Server

When tmux-continuum initializes, it has a built-in safety check: if it detects more than one tmux server running under your user account, it intentionally aborts the autosave setup. It does this to prevent a race condition where two separate environments try to overwrite your save files at the exact same time.

To check this, the plugin basically runs a raw process count:

pgrep -u $USER tmux

When I ran this on my host machine, it returned two running servers. One was my actual host session, bound to the default socket in /tmp/. But the second server was a phantom—it had no accessible socket on the host filesystem, and its parent process was tied to a user-level systemd scope.

The Docker "One-Way Mirror"

The phantom process turned out to be a tmux session running inside one of my local Docker containers.

This happens because Docker containers aren't virtual machines; they don't run their own isolated OS kernels. They share the host's Linux kernel, utilizing PID Namespaces to create a sensory deprivation tank for the processes inside.

Because of these namespaces, the visibility is a one-way mirror:

The fixuid Trap

But wait—why did the host kernel think my user owned the container's tmux process? Doesn't Docker usually run things as root or an isolated container user?

Enter fixuid.

I use fixuid in my containers to solve the classic Docker volume permission nightmare. On container startup, fixuid intercepts the execution, dynamically rewrites the container's internal UID to match my exact host UID, and drops root privileges. This beautifully ensures that any files created in the container aren't owned by root on my host machine.

But by solving the storage problem, it created a process collision. Because fixuid forced the containerized user to perfectly match my host UID, the host kernel accurately reported that my user account was running both tmux servers.

tmux-continuum saw the raw process count of 2, assumed my save files were in imminent danger of a race condition, and hit the emergency brake.

The Fix

The solution is to avoid hacky workarounds (like forcing scripts into your ~/.tmux.conf as a band-aid). Instead, you must clear the process collision.

Use pgrep -a tmux to identify the rogue containerized sessions, and then issue a clean pkill -f tmux to wipe the slate clean. As soon as you start a fresh tmux instance, continuum kicks into action, passes its safety checks natively, and dynamically injects its own script into status-right exactly as intended.

Takeaway: The host kernel always knows what Docker is hiding. When in doubt, check your namespaces.