Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

Service Lifecycle

Relevant source files

This page describes how the Samba service (smbd) operates as the container's main process, the sequence of events during container startup and shutdown, and the runtime behavior of the service. For details on SSHFS mount operations and options, see Mounting Remote Filesystems. For Samba configuration details, see Samba Configuration).

Container Process Model

The docker-sshfs container runs smbd (Samba daemon) as its PID 1 process , making it the container's main process. This is defined in the Dockerfile's CMD directive Dockerfile33

Key Process Flags

FlagPurpose
--foregroundPrevents smbd from daemonizing, keeping it attached to the terminal so Docker can monitor it
--no-process-groupDisables process group creation, ensuring proper signal handling in the container environment
--debug-stdoutRedirects log output to stdout, making logs visible via docker logs

The foreground operation is critical because Docker monitors PID 1 to determine container health. If smbd were to daemonize (default behavior), the container would immediately exit after startup.

Sources: Dockerfile33

Startup Sequence

The following diagram shows the complete startup sequence when docker run is invoked:

sequenceDiagram
    participant User
    participant Docker as "Docker Engine"
    participant Container as "Container Process"
    participant FS as "Filesystem"
    participant Smbd as "smbd Process"
    
    User->>Docker: docker run --privileged -p 127.0.0.1:139:139 -p 127.0.0.1:445:445 docker-sshfs
    
    rect rgb(240, 240, 240)
        Note over Docker,Container: Container Initialization Phase
        Docker->>Container: Create container from docker-sshfs image
        Container->>FS: Mount root filesystem
        Container->>FS: Verify /remote directory exists
        Container->>FS: Verify /samba-share directory exists
        Container->>FS: Verify symbolic link /samba-share/remote -> /remote
        Container->>FS: Apply permissions: chmod 777 /samba-share
    end
    
    rect rgb(240, 240, 240)
        Note over Container,Smbd: Service Startup Phase
        Container->>Smbd: Execute CMD: smbd --foreground --no-process-group --debug-stdout
        Smbd->>FS: Read /etc/samba/smb.conf
        Smbd->>Smbd: Parse global configuration (workgroup, security=user, map to guest)
        Smbd->>Smbd: Load share definition [SSHFS Share] at /samba-share
        Smbd->>Smbd: Bind to ports 139 (NetBIOS) and 445 (SMB)
        Smbd-->>Container: Service ready, listening on ports
    end
    
    rect rgb(240, 240, 240)
        Note over Docker,User: Container Running
        Docker-->>User: Container ID returned
        User->>Docker: docker logs docker-sshfs (optional)
        Docker-->>User: smbd output via --debug-stdout
    end

Startup Phases

Phase 1: Container Initialization

  • Docker creates the container from the docker-sshfs image
  • Filesystem structure is verified:
  • Permissions are applied: /samba-share is set to 777 Dockerfile21

Phase 2: Service Startup

  • smbd process launches as PID 1 Dockerfile33
  • Configuration is loaded from /etc/samba/smb.conf Dockerfile18
  • Network services bind to ports 139 and 445 Dockerfile27
  • Service enters ready state, waiting for SMB connections

At this point, the container is ready but the /remote directory is empty (no SSHFS mount yet). The Samba service is fully operational and serving the /samba-share directory, but it only contains the symbolic link to the unmounted /remote directory.

Sources: Dockerfile12 Dockerfile15 Dockerfile18 Dockerfile21 Dockerfile27 Dockerfile30 Dockerfile33 README31

Runtime Service States

The container transitions through multiple states during its lifecycle:

State Descriptions

StateDescriptionKey Characteristics
ContainerCreatedContainer exists but smbd has not startedNo network services active
SmbdStartingsmbd process initializingReading configuration, binding ports
SmbdReady/NoRemoteMountSamba service operational, no SSHFS mount/samba-share accessible but /remote empty
SmbdReady/RemoteMountedBoth Samba and SSHFS operationalRemote files accessible via /samba-share/remote
SambaIdleNo active SMB client connectionsService listening, no file operations
SambaActivemacOS Finder connected and accessing filesFile I/O operations in progress
SmdbStoppingContainer shutting downPorts being released, connections closed

Sources: Dockerfile33 README31 README49 README76

Service Initialization Details

When smbd starts, it performs the following initialization sequence:

Configuration Loading

The smbd process reads its configuration from /etc/samba/smb.conf, which is copied into the image during build Dockerfile18 Key configuration directives that affect service behavior:

  • Guest Access : map to guest = Bad User allows unauthenticated connections
  • Forced User Identity : force user = sshuser ensures all operations run as UID 1000
  • Protocol Version : min protocol = SMB2 enforces modern SMB protocol
  • Write Permissions : writable = yes with create mask = 0777 allows full read/write access

Sources: Dockerfile18 Dockerfile33

SSHFS Mount Integration

While smbd runs continuously as the main process, SSHFS mounts are performed interactively by executing commands inside the running container:

sequenceDiagram
    participant User
    participant Container as "Container (PID 1: smbd)"
    participant Shell as "bash (docker exec)"
    participant SSHFS as "sshfs Process"
    participant Remote as "Remote SSH Server"
    participant FS as "/remote Mount Point"
    
    Note over Container: smbd running in foreground
    
    User->>Container: docker exec -it docker-sshfs bash
    Container->>Shell: Launch interactive bash shell
    
    User->>Shell: sshfs -o allow_other,uid=1000,gid=1000 user@host:path /remote
    
    Shell->>SSHFS: Fork sshfs process
    
    SSHFS->>SSHFS: Read /etc/fuse.conf (user_allow_other enabled)
    
    SSHFS->>Remote: Establish SSH connection
    Remote-->>SSHFS: Authenticate and establish tunnel
    
    SSHFS->>FS: Mount remote filesystem at /remote
    
    FS-->>SSHFS: FUSE mount successful
    
    SSHFS->>SSHFS: Run as daemon (background)
    
    SSHFS-->>Shell: Return control
    
    Shell-->>User: Mount complete
    
    Note over Container,FS: /samba-share/remote -> /remote now has files
    
    User->>Shell: exit
    
    Note over Container: smbd continues serving /samba-share with mounted content\nNote over SSHFS: sshfs daemon continues running in background

Mount Process Details

The SSHFS mount operation occurs outside the main smbd process lifecycle:

  1. User opens an interactive shell via docker exec README41
  2. SSHFS command is executed manually README49
  3. Mount options are critical:
    • allow_other: Allows smbd (running as different user) to access the mount README52
    • uid=1000,gid=1000: Maps remote files to sshuser for write access README53
  4. SSHFS daemonizes and runs in background
  5. The symbolic link /samba-share/remote now points to populated directory Dockerfile30
  6. smbd continues serving, now with access to remote files

Note that the mount target is /remote, not /samba-share directly. The symbolic link provides the integration point Dockerfile30

Sources: Dockerfile30 README41 README49 README52 README53

Shutdown Sequence

Container shutdown follows Docker's standard signal handling:

Shutdown Phases

Phase 1: Signal Delivery

  • Docker sends SIGTERM to PID 1 (smbd)
  • By default, Docker waits 10 seconds for graceful shutdown
  • If smbd doesn't exit, Docker sends SIGKILL

Phase 2: Samba Cleanup

  • smbd closes listening sockets on ports 139 and 445
  • Active SMB client connections are disconnected
  • Lock files and temporary files are removed

Phase 3: SSHFS Cleanup

  • Docker sends SIGTERM to all container processes, including background sshfs daemons
  • sshfs unmounts the remote filesystem from /remote
  • SSH connections are closed

Phase 4: Container Termination

  • All processes have exited
  • Container enters "stopped" state
  • Port mappings are released on the host

Forced Shutdown

If SSHFS mount is busy (e.g., macOS Finder still accessing files), unmounting may fail README:82-83 In this case:

  • User must manually unmount the share from macOS Finder first
  • Then retry fusermount -u /remote README76
  • Or simply docker stop will forcefully unmount after timeout

Sources: README76 README:82-83

Process Tree

The running container has the following process structure:

Container (docker-sshfs)
│
├── PID 1: smbd --foreground --no-process-group --debug-stdout
│   ├── Child: smbd worker processes (created on-demand for client connections)
│   └── Child: smbd housekeeping processes
│
└── PID N: sshfs user@host:path /remote -o allow_other,uid=1000,gid=1000
    └── (FUSE kernel module connection)

Process Relationships

ProcessPIDParentPurpose
smbd1None (init)Main Samba service, container's PID 1
smbd workersDynamic1Handle individual SMB client connections
sshfsVariable1FUSE daemon for remote filesystem mount

The --no-process-group flag Dockerfile33 prevents smbd from creating a separate process group, ensuring that Docker's signal delivery works correctly. Without this flag, SIGTERM might not reach all Samba worker processes.

Sources: Dockerfile33

Lifecycle Summary

The complete lifecycle can be summarized as:

PhaseDurationKey ProcessState
BuildOne-timeDocker buildImage created with smbd as CMD
Startup~1-2 secondssmbd initializationPorts bound, configuration loaded
Ready (No Mount)Indefinitesmbd serving/samba-share accessible but empty
Runtime (Mounted)Indefinitesmbd + sshfsFull functionality with remote files
Shutdown~1-10 secondsSignal handlingGraceful or forced termination

The service is designed for continuous operation with interactive SSHFS mount/unmount operations performed on-demand without restarting the container.

Sources: Dockerfile33 README31 README41 README49 README76