This documentation is part of the "Projects with Books" initiative at zenOSmosis.
The source code for this project is available on GitHub.
Overview
Relevant source files
Purpose and Scope
This document provides an introduction to sshfs-mac-docker, explaining what the system is, the problem it solves, and how it achieves its goals at a high level. This overview covers the system's architecture, core components, and operational model without going into detailed implementation specifics.
For step-by-step usage instructions, see Getting Started. For in-depth architectural analysis, see Architecture. For detailed configuration reference, see Configuration Reference.
Sources: README.md:1-90
What is sshfs-mac-docker?
sshfs-mac-docker is a containerized solution that enables macOS users to mount remote SSH filesystems without installing macFUSE or kernel extensions on their host system. The system runs an isolated Docker container that bridges SSH-based remote filesystem access (via SSHFS) with native macOS file browsing (via Samba/SMB protocol).
Key Problem Solved: Eliminates the need for macFUSE and custom kernel extensions (kext) on macOS by moving all FUSE-related operations inside a Docker container.
Sources: README.md:1-5
Problem Statement
Traditional SSHFS usage on macOS requires:
- Installation of macFUSE (formerly OSXFUSE)
- Loading kernel extensions that require system-level privileges
- Security policy modifications on modern macOS versions
- Potential system instability from third-party kernel modules
sshfs-mac-docker avoids all of these requirements by:
- Running FUSE operations entirely within a Linux container
- Exposing mounted remote filesystems through the well-established SMB protocol
- Requiring only Docker/OrbStack installation on the macOS host
Sources: README.md3
System Architecture Overview
The system employs a three-tier architecture where the Docker container acts as a protocol translation bridge:
Sources: README.md5 Dockerfile:1-34
graph TB
subgraph "Tier_1[macOS Host]"
Finder["macOS Finder"]
Terminal["Terminal"]
end
subgraph "Tier_2[Docker Container: docker-sshfs]"
Samba["smbd\n(Samba daemon)"]
SSHFS["sshfs process"]
subgraph "Filesystem"
SambaShare["/samba-share\n(chmod 777)"]
Remote["/remote\n(SSHFS mount point)"]
SymLink["Symbolic Link:\n/samba-share/remote → /remote"]
end
User["sshuser:sshpass\n(UID 1000, GID 1000)"]
end
subgraph "Tier_3[Remote Infrastructure]"
SSHServer["Remote SSH Server\nuser@host:path"]
end
Finder -->|SMB Protocol smb://container-ip Ports 139/445| Samba
Terminal -->|docker exec| User
Samba -->|Serves| SambaShare
SambaShare -.->|Contains| SymLink
SymLink -.->|Links to| Remote
SSHFS -->|SSH Port 22| SSHServer
SSHServer -->|Mounted at| Remote
User -->|Executes| SSHFS
Core Components and Code Entities
The system consists of three primary configuration artifacts and several runtime entities:
Configuration Files
| File | Purpose | Key Settings |
|---|---|---|
Dockerfile | Container image definition | Base: ubuntu:latest |
Packages: sshfs, samba | ||
User: sshuser | ||
smb.conf | Samba server configuration | Share path: /samba-share |
| Guest access enabled | ||
Force user: sshuser | ||
/etc/fuse.conf | FUSE permissions | user_allow_other enabled |
Sources: Dockerfile:1-34 smb.conf:1-20
Runtime Components
Component Details:
smbdprocess: Samba daemon started via Dockerfile33 as container's main processsshuseraccount: Non-root user created in Dockerfile9 with hardcoded password/remotedirectory: SSHFS mount point created in Dockerfile12/samba-sharedirectory: Samba root created in Dockerfile15 with 777 permissions Dockerfile21- Symbolic link : Integration point created in Dockerfile30 linking
/samba-share/remote→/remote
Sources: Dockerfile:9-30 Dockerfile33
Key Technologies
The system integrates three core technologies:
| Technology | Role | Configuration |
|---|---|---|
| SSHFS | Remote filesystem client | Mount options in README.md49 |
Requires allow_other, uid=1000, gid=1000 | ||
| Samba | SMB/CIFS server | Configured in smb.conf:1-20 |
| Ports 139 and 445 | ||
| FUSE | Filesystem in userspace | Enabled in Dockerfile24 |
With user_allow_other permission |
Critical Integration:
- FUSE's
allow_other: Enables Samba (running as different user) to access SSHFS mounts README.md52 - UID/GID mapping : Sets ownership to
sshuser(1000:1000) for write access README.md53 - Symbolic link : Zero-copy integration between SSHFS mount and Samba share Dockerfile30
Sources: README.md:49-53 Dockerfile24 Dockerfile30 smb.conf:1-20
Operational Model
The system requires three phases to establish a working connection:
Phase 1: Container Initialization
- Builds image from Dockerfile:1-34
- Starts
smbdin foreground mode Dockerfile33 - Binds SMB ports to localhost README.md31
Sources: README.md22 README.md31 Dockerfile33
Phase 2: Remote Filesystem Mounting
- Executes SSHFS as
sshuserinside container README.md:41-49 - Mounts remote filesystem at
/remote - Accessible via symbolic link at
/samba-share/remoteDockerfile30
Sources: README.md:41-49 Dockerfile30
Phase 3: macOS Client Connection
- Must use container IP address (not
localhost) README.md57 - Connect as "Guest" README.md67
- Files appear in Finder under Network devices README.md69
Sources: README.md:57-69
Why Samba Instead of Docker Volume Mounts?
Docker's native volume mounting (docker run -v) cannot be used because:
- Volume mounts are designed for local filesystems : They map host directories to container paths
- SSHFS operates inside the container : The mounted remote filesystem exists only in the container's namespace
- No reverse mounting capability : Docker cannot expose a container's internal mount back to the host
The Samba approach works because:
- SMB is a network protocol that crosses namespace boundaries
- Samba can serve any filesystem accessible within the container
- macOS has native SMB client support (Finder)
Sources: README.md:13-16
Platform Requirements
The system has specific platform dependencies:
| Platform | Status | Notes |
|---|---|---|
| OrbStack | ✅ Recommended | Works out-of-box with proper networking README.md9 |
| Docker Desktop | ⚠️ Requires modifications | Network routing must be modified README.md9 |
| macOS | Required | Target platform for SMB client |
Critical Detail: While SMB ports are forwarded to 127.0.0.1:139 and 127.0.0.1:445, macOS Finder must connect using the container's internal Docker IP address (e.g., 172.17.0.2), not localhost README.md57
Sources: README.md9 README.md57
Security Considerations
The system's security model includes:
- Privileged container : Required for FUSE operations README.md31
- Localhost-only port binding : SMB ports bound to
127.0.0.1prevent external network access README.md34 - Guest authentication : SMB configured for guest-only access smb.conf:13-14
- Forced user identity : All operations execute as
sshuserregardless of SMB client smb.conf19 - Hardcoded credentials :
sshuser:sshpassdefined in Dockerfile9
Sources: README.md31 README.md34 smb.conf:13-14 smb.conf19 Dockerfile9
Limitations and Alternatives
Known Limitations:
- Requires running container with
--privilegedflag - Manual mount/unmount operations required
- Container IP discovery needed for each connection
- "Device or resource busy" error requires unmounting from Finder first README.md:79-85
Alternative Solution: For users who prefer not to use Docker, the project documentation references fuse-t (https://github.com/macos-fuse-t/fuse-t) as a potential alternative README.md89
Sources: README.md:79-85 README.md89