Raspberry PiのDocker上でSambaサーバを立ち上げてネットワーク共有フォルダを作成する

こんばんは。それ別にRaspberry Piでやらなくてもいいんじゃない?をやっていく自宅サーバー管理者です。

今回はRaspberry PiにインストールしたDockerでSambaコンテナを立ち上げてNASを構築してみたいと思います。

ざっくりとした手順は以下の通りです。

  1. 事前準備
  2. 外付けハードディスクドライブ(以下、外付けHDD)の準備
  3. docker-compose.ymlファイルの作成
  4. Sambaコンテナの起動
  5. MacとWindowsからの接続確認

それでは順にやっていきます。

[ad]

事前準備

Raspberry PiはRaspberry Pi 4 model B (メモリ:8GB)を使用します。インストールするOS、Docker環境、Docker Compose環境はそれぞれ以下の記事の通りにセットアップ済みである前提です。

外付けHDDの準備

Sambaで読み書きする外付けHDDの準備をします。外付けHDDはUSB接続のものであれば何でも良いですが、私は自宅に転がっていたI-O DATAの古いHDDを使います。このHDDは120GBしか容量がない、今では骨董品扱いされそうな代物です。今回は外付けHDDのファイルシステムとしてEXT4を採用しようと思います。

デバイスファイルの確認

外付けHDDがどのブロックデバイス(/dev/???)で扱われるかを確認します。外付けHDDをRaspberry Pi 4に接続したあと、lsblk コマンドを実行して120GBのディスクを見つけましょう。

コンソール
$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0 106.1G  0 disk 
└─sda1        8:1    0 106.1G  0 part /media/pi/EXTHDD
mmcblk0     179:0    0  29.7G  0 disk 
├─mmcblk0p1 179:1    0   256M  0 part /boot
└─mmcblk0p2 179:2    0  29.5G  0 part /

実行結果からブロックデバイスはsda1であることが分かりました。以降は/dev/sda1を対象に説明を進めますが、環境によっては/dev/sda1ではないことがあります。みなさんの環境でlsblkを実行した結果で読み替えてください。

接続したHDDはFAT32でフォーマットされていたため、自動的に/media/pi/EXTHDDにマウントされているようです。HDDをフォーマットする前にアンマウントしておきます。

コンソール
$ sudo umount /dev/sda1
$ 

パーティショニング

次に外付けHDDのパーティショニングとフォーマットを行ないます。

パーティショニングに関してはgdiskを利用します。(gdiskの使用法に関してはここでは割愛します。)

以下、コンソールです。赤文字部分が実際に入力した内容です。変更後のパーティションテーブルを確認した結果は青文字部分です。

コンソール
$ sudo gdisk /dev/sda
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: not present


***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format
in memory. THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by
typing 'q' if you don't want to convert your MBR partitions
to GPT format!
***************************************************************


Command (? for help): p
Disk /dev/sda: 222541648 sectors, 106.1 GiB
Model: HDPG-SU         
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): AC32DF32-E043-4434-B723-1FF632EE84BE
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 222541614
Partitions will be aligned on 2048-sector boundaries
Total free space is 3853 sectors (1.9 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048       222539775   106.1 GiB   0700  Microsoft basic data

Command (? for help): o  ←「o」と入力しEnter
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): Y  ←「Y」と入力しEnter

Command (? for help): n  ←「n」と入力しEnter
Partition number (1-128, default 1):   ←そのままEnter
First sector (34-222541614, default = 2048) or {+-}size{KMGTP}:   ←そのままEnter 
Last sector (2048-222541614, default = 222541614) or {+-}size{KMGTP}:   ←そのままEnter
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):   ←そのままEnter
Changed type of partition to 'Linux filesystem'

Command (? for help): p  ←「p」と入力しEnter
Disk /dev/sda: 222541648 sectors, 106.1 GiB
Model: HDPG-SU         
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): AC32DF32-E043-4434-B723-1FF632EE84BE
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 222541614
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048       222541614   106.1 GiB   8300  Linux filesystem

Command (? for help): w  ←「w」と入力しEnter

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y  ←「Y」と入力しEnter
OK; writing new GUID partition table (GPT) to /dev/sda.
The operation has completed successfully.

$

これでパーティショニングは完了です。

今回の外付けHDDは2TB以下なのでfdiskを用いてMBRのまま利用してもよかったのですが、今どきのドライブは2TB以上が主流だと思いgdiskを使ってGPTパーティションとしました。

フォーマット

mkfs.ext4コマンドでフォーマットしていきましょう。途中でvfatファイルシステムだったけど続行して良いか聞かれたため、yを入力し続行しました。

コンソール
$ sudo mkfs.ext4 /dev/sda1 
mke2fs 1.44.5 (15-Dec-2018)
/dev/sda1 contains a vfat file system labelled 'EXTHDD'
Proceed anyway? (y,N) y  ←「Y」と入力しEnter
Creating filesystem with 27817445 4k blocks and 6955008 inodes
Filesystem UUID: e0949b66-ba09-476b-a57b-1bccb3279ad8
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000, 7962624, 11239424, 20480000, 23887872

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (131072 blocks): done
Writing superblocks and filesystem accounting information: done

これでフォーマットは完了です。

マウント

フォーマットした外付けHDDをマウントします。ここでは/rpinasにマウントします。また、piユーザが書き込めるよう、/rpinasの所有者をpiに変更します。

コンソール
$ sudo mkdir /rpinas
$ sudo mount -t ext4 /dev/sda1 /rpinas
$ sudo chown -R pi:pi /rpinas
$ ls -l / | grep rpinas
drwxr-xr-x   3 pi   pi    4096 Apr 19 23:19 rpinas

これでマウントが完了し、piユーザで読み書きができるようになりました。

自動マウント設定

Raspberry Piを再起動するたびにマウントするのは面倒なのと、Sambaコンテナが立ち上がる際にマウントされていないと困るため、/etc/fstabにエントリを追加します。fstabに追加する際、ブロックデバイス指定だと別のドライブを接続して起動した際にブロックデバイスが変わってしまう恐れがあるため、GUIDを利用します。

まず、外付けHDDのUUIDを確認します。UUIDの確認はblkidコマンドで確認できます。

コンソール
$ blkid /dev/sda1
/dev/sda1: UUID="e0949b66-ba09-476b-a57b-1bccb3279ad8" TYPE="ext4" PARTLABEL="Linux filesystem" PARTUUID="8891ce35-d984-4f06-8e22-595be4525a32"

/dev/sda1のUUIDが”e0949b66-ba09-476b-a57b-1bccb3279ad8″であることが分かりました。

このUUIDを指定して/etc/fstabにエントリを追加します。sudoでfstabを編集します。

/etc/fstab
proc            /proc           proc    defaults          0       0
PARTUUID=e6bfd811-01  /boot           vfat    defaults          0       2
PARTUUID=e6bfd811-02  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

# 以下を追加(UUIDは先ほど調べたものに置き換えてください)
UUID=e0949b66-ba09-476b-a57b-1bccb3279ad8  /rpinas ext4    defaults 0 2

/etc/fstabの編集が完了したら、一度Raspberry Piを再起動して外付けHDDが自動的にマウントされているか確認してみます。

コンソール
$ sudo reboot
(再起動)

$ mount
...
/dev/sda1 on /rpinas type ext4 (rw,relatime)
...

/dev/sda1が/rpinasにマウントされていることが確認できました。

[ad]

docker-compose.ymlファイルの作成

次にSambaコンテナを立ち上げるためにdocker-compose.ymlファイルを作成します。

外付けHDDのマウントポイントである/rpinasはpiユーザで読み書きできるようになっているため、Dockerで立ち上げるSamba側のUIDとGIDも、ホストのpiユーザのUIDとGIDに合わせます。

UIDとGIDを調べる

Raspberry Pi OSでは、デフォルトユーザのpiユーザのUIDとGIDはどちらも1000に設定されていると思いますが、念の為確認しておきます。

UIDとGIDはidコマンドで調べられます。

コンソール
$ id
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),105(input),109(netdev),117(lpadmin),995(docker),997(gpio),998(i2c),999(spi)

UIDとGID共に1000であることが分かりましたので、Sambaコンテナを立ち上げる際にUIDとGIDを1000に設定します。

docker-compose.ymlファイルの作成

piユーザのUIDとGIDが分かったので、実際にdocker-compose.ymlを作成していきましょう。

DockerイメージはDocker Hubでスター数の多い「dperson/samba」を利用させてもらおうと思います。

また、共有フォルダにアクセスするユーザの名前はpiとします。(piでなくても問題ありません。)

以下、作成したdocker-compose.ymlファイルです。docker-compose.ymlファイルは/home/pi/service/sambaディレクトリに格納します。

docker-compose.yml
version: "3"
services:
    samba:
        image: dperson/samba:latest
        restart: always
        volumes:
            - /rpinas:/mount
        ports:
            - 139:139
            - 445:445
        environment:
            - TZ=Asia/Tokyo
            - USERID=1000
            - GROUPID=1000
        tty: true
        stdin_open: true
        command: '-s "share;/mount;yes;no;no;pi" -u "pi;<パスワード>" '

docker-compose.ymlファイルの「pi」と書かれている部分がSambaの共有フォルダにアクセスする際のユーザ名、<パスワード>と書かれている部分はアクセスする際のパスワードとなります。<パスワード>部分は変更してください。

また、Sambaコンテナがホストの/rpinasにアクセスする際のUIDとGIDをenvironmentのUSERID、GROUPIDに指定しています。先ほど調べた1000ですね。

オプションの詳細はhttps://hub.docker.com/r/dperson/sambaを参照してください。(Dockerイメージの作者さん、便利なイメージをありがとうございます。)

以上でdocker-compose.ymlファイルの作成は終了です。

Sambaコンテナの起動

いよいよ作成したdocker-compose.ymlを使ってSambaコンテナを立ち上げます。

/home/pi/service/sambaディレクトリに移動してdocker-compose up -dコマンドを実行します。Sambaコンテナが立ち上がっているかどうかはdocker-compose psコマンドで確認します。

コンソール
$ cd ~/service/samba/
$ docker-compose up -d
Creating network "samba_default" with the default driver
Pulling samba (dperson/samba:latest)...
latest: Pulling from dperson/samba
912815139b61: Pull complete
b3a3722ca837: Pull complete
8535a7219100: Pull complete
9e239ca8520f: Pull complete
Digest: sha256:66088b78a19810dd1457a8f39340e95e663c728083efa5fe7dc0d40b2478e869
Status: Downloaded newer image for dperson/samba:latest
Creating samba_samba_1 ... done

$ docker-compose ps
    Name                   Command                  State                                        Ports                                 
---------------------------------------------------------------------------------------------------------------------------------------
samba_samba_1   /sbin/tini -- /usr/bin/sam ...   Up (healthy)   137/udp, 138/udp, 0.0.0.0:139->139/tcp,:::139->139/tcp,                
                                                                0.0.0.0:445->445/tcp,:::445->445/tcp

Sambaコンテナが立ち上がったことが確認できました。

[ad]

MacとWindowsからの接続確認

立ち上げたSambaサーバに別のクライアントから接続できるか確認します。

Macで確認

Finderを開き、⌘+Kを押下するとサーバへ接続ダイアログが開きますので、サーバアドレスにsmb://<Raspberry PiのIPアドレス> を入力して「接続」ボタンを押下します。その後、ユーザIDとパスワード聞かれますので、名前にpi、パスワードに先ほどdocker-compose.ymlに設定したパスワードを入力して「接続」ボタンを押下します。

Raspberry PiのIPアドレスを入力して「接続」ボタンを押下
名前にpi、パスワードにdocker-compose.ymlファイルに記載したパスワードを入力して「接続」

Finderウィンドウが開き、Macにマウントすることができました。

Windowsで確認

Win+Rキーで名前を指定して実行のダイアログを表示します。名前欄には¥¥<Raspberry PiのIPアドレス>を入力します。ユーザ名とパスワードは先ほどと同様です。

ファイル名を指定して実行の名前欄に¥¥<Raspberry PiのIPアドレス>を指定
ユーザ名とパスワードを入力して「OK」
共有フォルダが表示されていることを確認

WindowsでもSamba共有フォルダに接続することができました。

まとめ

外付けHDDのフォーマットや自動マウント等、慣れないと難しい操作はあったものの無事にRaspberry PiのDockerでSambaコンテナを起動して共有フォルダを作成することができました。

Dockerを利用することでSambaに必要なモジュールのインストールやユーザ作成等の作業から解放されるだけでなく、Raspberry Pi自身の環境をあまり汚さずに済みました。次回からは今回作成した共有フォルダを利用して、Raspberry Piで音楽再生や写真表示、ビデオ再生などをやってみたいと思います。

それではまた。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です