fix: Move /var/run/dstack.sock to /var/run/dstack/dstack.sock directory#471
Merged
Conversation
/var/run/dstack.sock to /var/run/dstack/dstack.sock directory
kvinwang
force-pushed
the
fix/socket-path-for-docker-mount
branch
2 times, most recently
from
January 27, 2026 04:14
a3b76d1 to
34483a0
Compare
…tibility ## Problem When containers mount the socket file directly (e.g., `-v /var/run/dstack.sock:/var/run/dstack.sock`), the socket becomes inaccessible after guest-agent restarts. This is because: 1. Docker's bind mount locks the inode at container start time 2. When guest-agent restarts, Rocket's Unix socket handling deletes and recreates the socket file, creating a NEW inode 3. The container still holds the old inode, which no longer has any listener ### Why Rocket Deletes the Socket Unix Domain Sockets do NOT support `SO_REUSEADDR` like TCP sockets. The `bind()` syscall requires the path to not exist - if the socket file already exists, `bind()` fails with `EADDRINUSE`. Rocket's `reuse` option simulates TCP-like behavior by deleting the existing socket before creating a new one. ## Solution Move sockets to a dedicated directory `/var/run/dstack/`: - `/var/run/dstack/dstack.sock` - `/var/run/dstack/tappd.sock` All SDKs (Rust, Python, JS, Go) try the new path first, falling back to the old path for backward compatibility with older guest-agent versions.
Add systemd socket activation files to provide backward compatibility for containers mounting /var/run/dstack.sock directly. - dstack-socket.socket/service: Proxy for /var/run/dstack.sock - tappd-socket.socket/service: Proxy for /var/run/tappd.sock Uses systemd-socket-proxyd to forward connections from the legacy paths to the new paths in /var/run/dstack/. Since systemd owns the socket file (not the service), the inode persists across guest-agent restarts.
kvinwang
force-pushed
the
fix/socket-path-for-docker-mount
branch
from
January 27, 2026 06:16
fcc9e52 to
d685e07
Compare
kvinwang
enabled auto-merge
January 27, 2026 06:17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When containers mount the socket file directly (e.g.,
-v /var/run/dstack.sock:/var/run/dstack.sock), the socket becomes inaccessible after guest-agent restarts.Root Cause
Docker's bind mount locks the inode at container start time, not the path. When guest-agent restarts:
<path>.lockreuse=true(default), it deletes the existing socket file viaremove_file()bind()- this creates a NEW inodeWhy Rocket Deletes the Socket
Unlike TCP sockets, Unix Domain Sockets do not support
SO_REUSEADDR. Thebind()syscall requires the path to not exist - if the socket file already exists,bind()fails withEADDRINUSE.Rocket's
reuseoption is a workaround that simulates TCP-like behavior by:This "delete and recreate" approach is necessary for UDS but breaks Docker's file-based mounts.
Relevant Rocket code (unix.rs:32-72):
Solution
1. Move guest-agent to listen on new paths
/var/run/dstack.sock/var/run/dstack/dstack.sock/var/run/tappd.sock/var/run/dstack/tappd.sock2. Systemd socket proxy for backward compatibility
For containers that mount the old paths, we use systemd socket activation with
systemd-socket-proxyd:Key insight:
systemd.socketcreates and owns the socket file, not the service process. This means:/var/run/dstack.sockcontinue to work even after guest-agent restartsFiles added:
dstack-socket.socket+dstack-socket.servicetappd-socket.socket+tappd-socket.service3. SDK Fallback
All SDKs (Rust, Python, JS, Go) try the new path first, falling back to the old path for compatibility with older guest-agent versions.
User Impact
None - Apps can continue using
/var/run/dstack.sockand/var/run/tappd.sockas before. The systemd socket proxy handles the forwarding transparently.Changes
/var/run/dstack//var/run/dstack/directory