Skip to main content

Set Up Samba Server in Docker

!IMPORTANT: Permission setting is very annoying but critical, sometimes you need take long time to fine tune it and debug. !IMPORTANT: When setting up a Samba server in Docker in OSX, you will encounter problems such as Operation not suppored when using bind mount. Roughly saying, the reason is Docker run in a light VM in Mac and your Mac host uses a different file system(HFS+) compared to Linux(ext4 or similar). So switching to volume mount will solve this potential problem.

Some takeaways about Permission:

  • Creating and deleting files is controlled by permissions on the directory.
  • Modifying the file is controlled by permissions on the file. You may have a mask which is removing the write privilege from the file.

When I turned to set up Samba server locally, the main purpose is that I would like to integrate the Samba server into my Docker Compose project to mock a real remote Samba server, which will facilitate your local development in Docker environment.

So this blog will illustrate to set up a Samba server and a client, and test interaction between them.

Start Samba Server in Docker

Here, we use Samba server image from dperson/samba. Although there is an alternative from ghcr.io/servercontainers/samba or crazymax/samba

In OSX, it's critical to use volume mount and avoid using bind mount as we mentioned above.

note

In OSX, due to the docker desktop itself is running in VM, it will cause some error like Operation not supported when binding a local file folder via bind mount even you set 777 mask on the folder. So it's recommended to use volume mount to bind to /mnt in Samba server in OSX.

Furthermore, the Samba server will log such message: error reading meta xattr: Not supported.

In Linux, it's okay to use either volume mount or bind mount.

docker run -it --rm \
--name samba \
-p 139:139 -p 445:445 \
-v mnt:/mnt:z \
dperson/samba \
-p -s "Mount;/mnt;yes;no;yes" -u "bob;bobspasswd" -g "log level = 5"
note

-s "<Mount;/mnt>;yes;no;yes" means [browsable:yes;readonly:no;guest:yes]", which will allow the guest to read and the user to read/write!

Get the samba server IP address:

$ docker inspect \
-f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
samba
172.17.0.2

Start Samba Client in Docker

Use dperson/samba or busybox image,

docker run -it --rm --privileged dperson/samba bash

or

docker run -it --rm --privileged busybox sh

Inside the container:

mkdir /smb_share

# mount -t cifs //[server-ip]/[share-path] /[mount-point]
mount -t cifs //172.17.0.2/Mount /smb_share -o rw,username=bob,password=bobspasswd

# write file
echo "xxxx" > /smb_share/f.txt

Start Samba Client which Create Volume in Docker

  1. Create a CIFS/Samba Volume
docker volume create \
--driver local \
--opt type=cifs \
--opt device=//172.17.0.2/Mount \
--opt o=username=bob,password=bobspasswd \
--name samba-volume
$ docker inspect samba-volume
[
{
"CreatedAt": "2023-08-13T16:24:03Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/samba-volume/_data",
"Name": "samba-volume",
"Options": {
"device": "//172.17.0.2/Mount",
"o": "addr=username=bob,password=bobspasswd",
"type": "cifs"
},
"Scope": "local"
}
]
  1. Start a container using the created volume samba-volume.
docker run -it --rm \
-v samba-volume:/mnt \
busybox \
sh

Use Case in Docker Compose

docker-compose-samba.yml
version: "3"

# Inspired by https://github.com/dperson/samba/blob/master/docker-compose.yml

services:
samba:
image: dperson/samba
privileged: true
environment:
TZ: "EST5EDT"
ports:
- "137:137/udp"
- "138:138/udp"
- "139:139/tcp"
- "445:445/tcp"
volumes:
- mnt:/mnt:z
command: '-s "Mount;/mnt;yes;no;yes" -u "bob;bobspasswd" -p'
# networks:
# default:
# ipv4_address: 172.28.0.20

samba-client:
image: busybox
restart: on-failure
volumes:
- samba-volume:/smb_share
# tty: true
command: sleep infinity
depends_on:
- samba

# networks:
# default:
# ipv4_address: 172.28.0.21

# networks:
# default:
# driver: bridge
# ipam:
# config:
# - subnet: 172.28.0.0/16
# gateway: 172.28.0.1

volumes:
mnt:
samba-volume:
driver: local
driver_opts:
type: cifs
# device: "//172.28.0.20/Mount"
# o: "username=bob,password=bobspasswd"
device: "//localhost/Mount"
o: "addr=localhost,username=bob,password=bobspasswd"

Troubleshooting

When you mount an Samba Share in Linux, you may encounter error like failed: Invalid argument,

bash-5.1# mount -t cifs //172.17.0.2/Mount /mnt/smb_share -o iocharset=utf8,rw,vers=1.0
mount: mounting //172.17.0.2/Mount on /mnt/smb_share failed: Invalid argument

You can use dmesg to debug,

bash-5.1# dmesg
[317258.750535] CIFS: Attempting to mount \\172.17.0.2\Mount
[317258.752956] CIFS: VFS: No username specified
[317336.240984] cifs: Unknown parameter 'passwd'
[317344.451345] CIFS: Attempting to mount \\172.17.0.2\Mount