Samba
Docker container for Samba file server.
About the Fork
This repository is a fork of the dperson/samba project, which has not been updated for a long time. This version contains the current Samba version for the current Alpine Linux version.
Samba Versions
Image tags correspond to the Samba version in the container. Use the appropriate tag to get the required version. The latest stable version always has the latest tag, and the development version has the develop tag.
The Samba version corresponds to what is available for installation in Alpine. If a new Samba version is not yet available in the image, it means it has not been updated in Alpine yet.
What is Samba?
Since 1992, Samba has provided secure, stable, and fast file and print services for all clients using the SMB/CIFS protocol: all versions of DOS and Windows, OS/2, Linux, and many others.
Image Features
- Alpine Linux base image (minimal size)
- SMB2/SMB3 support (SMB1 disabled by default)
- Time Machine support for macOS
- Built-in recycle bin
- Optimized performance settings
- Healthcheck for status monitoring
Quick Start
Run with default settings
docker run -it -p 139:139 -p 445:445 -d upagge/samba -p
Run with local storage
docker run -it --name samba -p 139:139 -p 445:445 \
-v /path/to/directory:/mount \
-d upagge/samba -p
Run with docker-compose
services:
samba:
image: upagge/samba
restart: unless-stopped
ports:
- "139:139/tcp"
- "445:445/tcp"
volumes:
- /mnt/data:/share
command: '-s "Data;/share;yes;no;no" -u "user;password" -p'
Configuration
Help
docker run -it --rm upagge/samba -h
Command Line Options
| Option | Description |
|---|---|
-h |
Show help |
-c "<from:to>" |
Set up character mapping for file/directory names |
-g "<parameter>" |
Add global option to smb.conf |
-G "<section;parameter>" |
Add option to specific smb.conf section |
-i "<path>" |
Import smbpasswd file |
-n |
Start nmbd daemon to advertise shares |
-p |
Set ownership and permissions on shares |
-r |
Disable recycle bin for shares |
-S |
Disable SMB2 minimum version |
-t |
Enable Time Machine support for macOS |
-s |
Configure a share (see format below) |
-u |
Add a user (see format below) |
-w "<workgroup>" |
Configure workgroup (domain) |
-W |
Allow wide symbolic links |
-I "<path>" |
Add include at the end of smb.conf |
-E |
Enable enhanced security (signing + encryption) |
Share Parameter Format (-s)
-s "<name;/path>[;browse;readonly;guest;users;admins;writelist;comment]"
| Field | Default | Description |
|---|---|---|
name |
required | Share name for clients |
/path |
required | Path to share directory |
browse |
yes | Visible in network browsing (yes/no) |
readonly |
yes | Read-only (yes/no) |
guest |
yes | Allow guest access (yes/no) |
users |
all | List of allowed users (comma-separated) |
admins |
none | List of share administrators (comma-separated) |
writelist |
— | Users with write access on RO share |
comment |
— | Share description |
User Parameter Format (-u)
-u "<name;password>[;ID;group;GID]"
| Field | Description |
|---|---|
name |
Username (required) |
password |
User password (required) |
ID |
User UID (optional) |
group |
User group (optional) |
GID |
Group GID (optional) |
Environment Variables
| Variable | Description |
|---|---|
CHARMAP |
Character mapping |
GENERIC |
Section-specific option (supports GENERIC2, GENERIC3...) |
GLOBAL |
Global option (supports GLOBAL2, GLOBAL3...) |
IMPORT |
Path to smbpasswd file for import |
NMBD |
Enable nmbd daemon |
PERMISSIONS |
Set permissions on shares |
RECYCLE |
Disable recycle bin |
SHARE |
Share configuration (supports SHARE2, SHARE3...) |
SMB |
Disable SMB2 minimum version |
TIMEMACHINE |
Enable Time Machine support |
TZ |
Timezone (e.g., Europe/London) |
USER |
User configuration (supports USER2, USER3...) |
WIDELINKS |
Allow wide symbolic links |
SECURE |
Enable enhanced security (signing + encryption) |
WORKGROUP |
Workgroup |
USERID |
UID for smbuser |
GROUPID |
GID for smb group |
INCLUDE |
Path to additional config file |
RECYCLE_AGE |
Auto-cleanup files older than N days from recycle bin |
RECYCLE_CRON_HOUR |
Hour for cleanup job (0-23, default: 3) |
RECYCLE_CRON_MINUTE |
Minute for cleanup job (0-59, default: 0) |
Examples
Setting the Timezone
docker run -it -e TZ=Europe/London -p 139:139 -p 445:445 -d upagge/samba -p
Creating Users and Shares
docker run -it -p 139:139 -p 445:445 -d upagge/samba -p \
-u "user1;password1" \
-u "user2;password2" \
-s "public;/share;yes;no;yes" \
-s "users;/srv;no;no;no;user1,user2" \
-s "user1_private;/user1;no;no;no;user1" \
-s "user2_private;/user2;no;no;no;user2"
Enabling Time Machine
docker run -it -p 139:139 -p 445:445 -d upagge/samba -p -t \
-u "macuser;password" \
-s "TimeMachine;/backup;no;no;no;macuser"
Using Environment Variables
docker run -it -p 139:139 -p 445:445 \
-e SHARE="Data;/data;yes;no;no" \
-e SHARE2="Backup;/backup;yes;yes;no" \
-e USER="admin;secretpass" \
-e PERMISSIONS="true" \
-e TZ="Europe/London" \
-v /mnt/data:/data \
-v /mnt/backup:/backup \
-d upagge/samba
Full docker-compose.yml
services:
samba:
image: upagge/samba
restart: unless-stopped
environment:
TZ: 'Europe/London'
SHARE: "Documents;/documents;yes;no;no;user1,user2"
SHARE2: "Media;/media;yes;yes;yes"
USER: "user1;${SAMBA_USER1_PASSWORD}"
USER2: "user2;${SAMBA_USER2_PASSWORD}"
PERMISSIONS: "true"
ports:
- "139:139/tcp"
- "445:445/tcp"
volumes:
- /mnt/documents:/documents
- /mnt/media:/media
deploy:
resources:
limits:
memory: 512M
healthcheck:
test: ["CMD", "smbclient", "-L", "\\\\localhost", "-U", "%", "-m", "SMB3"]
interval: 60s
timeout: 15s
start_period: 10s
retries: 3
Ports
| Port | Protocol | Description |
|---|---|---|
| 137 | UDP | NetBIOS Name Service (only with -n) |
| 138 | UDP | NetBIOS Datagram Service (only with -n) |
| 139 | TCP | SMB over NetBIOS |
| 445 | TCP | SMB direct |
Note: Ports 137 and 138 are only needed when using the -n flag or NMBD variable.
Troubleshooting
-G Parameters for Shares Not Overriding Global Settings
If -G parameters for individual shares do not override global force user and force group settings, make sure you are using the latest version of the image.
This issue has been fixed: when using environment variables, GENERIC was processed before SHARE, so share sections did not exist yet. The processing order has now been corrected.
Example of correct usage:
docker run -it -p 139:139 -p 445:445 -d upagge/samba \
-s "public;/cloud/share;yes;no;yes" \
-G "public;force user = nobody" \
-G "public;force group = nogroup" \
-G "public;guest ok = yes" \
-G "public;read only = no"
Or with environment variables:
docker run -it -p 139:139 -p 445:445 \
-e SHARE="public;/cloud/share;yes;no;yes" \
-e GENERIC="public;force user = nobody" \
-e GENERIC2="public;force group = nogroup" \
-d upagge/samba
"Access is denied" Error
If you get an Access is denied error or see change_to_user_internal: chdir_current_service() failed! in the logs:
docker run -it --name samba -p 139:139 -p 445:445 \
-v /path/to/directory:/mount \
-d upagge/samba -p
Add the -p flag or set the PERMISSIONS=true variable.
If changing permissions is not possible, use the USERID and GROUPID variables:
docker run -it --name samba -p 139:139 -p 445:445 \
-e USERID=1000 \
-e GROUPID=1000 \
-v /path/to/directory:/mount \
-d upagge/samba
High Memory Usage
Limit container memory:
docker run -it --name samba -m 512m -p 139:139 -p 445:445 \
-v /path/to/directory:/mount \
-d upagge/samba -p
Connecting via smbclient
By default, smbclient tries to use SMB1. Use the -m SMB3 flag:
smbclient -L \\localhost -U % -m SMB3
smbclient //localhost/share -U user -m SMB3
NetBIOS Not Working
When using -n or NMBD, host network mode may be required:
docker run -it --network host \
-e NMBD=true \
-d upagge/samba -n -p \
-s "share;/data"
Security
- Only SMB2/SMB3 is used by default (SMB1 disabled)
- Use strong passwords
- Store passwords in
.envfile or Docker secrets - Restrict share access to specific users
Enhanced Security Mode
For environments requiring additional protection, use the -E flag or SECURE=true environment variable:
docker run -it -p 445:445 -d upagge/samba -E -p \
-u "user;password" \
-s "secure_share;/data;yes;no;no;user"
This enables:
- Server signing (mandatory) — prevents packet tampering
- Client signing (mandatory) — ensures client authenticity
- SMB encryption (desired) — encrypts traffic when client supports it
Note: Some older clients may not support these features. Only enable if all clients are compatible.
Recycle Bin
By default, the image includes a recycle bin feature. When files are deleted, they are moved to a .deleted folder in each share instead of being permanently removed.
Default Configuration
vfs objects = catia recycle
recycle:keeptree = yes # Preserve directory structure
recycle:maxsize = 0 # No file size limit (0 = unlimited)
recycle:repository = .deleted # Folder for deleted files
recycle:versions = yes # Keep versions when deleting same filename
How It Works
- When a file is deleted, it moves to
.deletedin the share root - Directory structure is preserved:
/share/docs/file.txt→/share/.deleted/docs/file.txt - Deleting a file with the same name creates versions:
file.txt,Copy #1 of file.txt, etc.
Automatic Cleanup
Important: Without cleanup, deleted files accumulate indefinitely and consume disk space.
Enable automatic cleanup with the RECYCLE_AGE environment variable:
services:
samba:
image: upagge/samba
environment:
RECYCLE_AGE: "30" # Delete files older than 30 days
RECYCLE_CRON_HOUR: "4" # Run at 4:00 AM (optional, default: 3)
RECYCLE_CRON_MINUTE: "30" # Run at XX:30 (optional, default: 0)
# ... other configuration
The cleanup job:
- Runs daily at the specified time (default: 3:00 AM)
- Only activates if recycle bin is enabled (no
-rflag) - Logs to
/var/log/recycle-cleanup.log
Disabling Recycle Bin
Use the -r flag or RECYCLE=true to disable the recycle bin entirely:
docker run -d upagge/samba -r -p -s "share;/data"
Recommended when:
- Storing large media files (videos, music)
- Limited disk space
- Temporary or cache directories
Feedback
If you have any problems or questions, please create an issue on GitHub.
