NAS Samba DLNA RAID server on RaspberryPi 3

In this tutorial we build a NAS Samba DLNA RAID server on RaspberryPi 3 Model B. The setup is headless, meaning we access the RaspberryPi only via remote SSH controls. No keyboard, mouse or display are required to be connected to the Pi. We use two external USB HDDs to provide sufficient space for all the music, videos and photos we want to store and play. In order to prevent data loss, we create a RAID 1 System to mirror the data on two HDDs.

1. Requirements

  • RaspberryPi 3 + power adapter
  • Micro SD card (recommended size 4 GB or above)
  • Raspbian Jessie, the operating system (download here)
  • SD Card Reader (in order to copy the operating system)
  • 2 equally sized USB HDDs (using external power or using an external powered USB switch)
  • Network/Internet access via LAN cable (to update packages etc.)

2. Download Raspbian to SD card

If you bought a SD card with a preinstalled operating system, you can skip this chapter. Otherwise we will download Raspbian Jessie onto the SD card. We use a 8 GB SD card. Since we did not have an external card reader available, we used a macbook with internal card reader to format the SD card and download Raspbian.

If you are using windows or linux the steps are the same, you just have to use different tools. From the mac we can download the image directly via shell commands. Windows, Mac and Linux solutions are explained on the RaspberryPi download page.

3. Assemble and start RaspberryPi

Unpack the RaspberryPi and put it into a case if available. Insert the SD card on the bottom side (opposite from the USB ports). Now connect the LAN cable (which should be connected to a router / switch for an internet connection to update and install some packages later on), and the USB power supply. You can setup WIFI later on as well, but the first time you need to access via LAN cable. Of course that only applies to the headless setup.

When powered on (connected the USB power adapter to power grid) you should see a yellow and green light working on the ethernet port, as well as a red and orange (toggling) light on the opposite side (both are red until booted, so give it some time).

Now we use an IP scanner to retrieve the IP from the RaspberryPi in order to connect via SSH. For Windows we can recommend the Advanced IP Scanner. For Mac we use the LanScan that can be downloaded in the AppStore.

Scan all the ranges or check ipconfig (Windows) or ifconfig (Mac/Linux) to see which ranges are possible.

Advanced IP Scanner output to get Raspberry PI IP
Advanced IP Scanner output

Now we see the RaspberryPi and can connect via a SSH tool. On Windows we use Putty. For Mac / Linux you already have a shell that works with SSH. On Mac open terminal and press CMD – Shift – k. There you should see an overview and configure your SSH connection.

We start Putty and use the IP provided by the IP Scanner.

Start putty and enter the IP
Start putty and enter the IP

Click open and log in as user pi with password raspberry.

User: pi Password: raspberry
User: pi – Password: raspberry

Now that we are connected, let us adapt some of the RaspberryPi configuration. Enter:

sudo raspi-config

You will see the following output:

Raspberry Pi Configuration
RaspberryPi Configuration

We strongly recommend to perform option 1 to use maximum SD card space and option 2 to change the password. Do not forget your password if you change it. You can quit the configuration with Escape or CTRL-c.

Now we update libraries and reboot:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
sudo reboot

Enter these commands one by one and confirm any installation via “y”. After the reboot your terminal will close (because there is no active connection, the Pi is rebooting). Wait some time and reconnect via Putty. The Pi is now up to date and we can start creating the RAID system.

4. Create Raid System

We use mdadm, a Linux tool, to create software raids and available in most Linux distributions. First, download and install the package:

sudo apt-get install mdadm

4.1 Connect the HDDs

Now plugin and power your external USB HDDs. They should be powered externally via own power adapters or via an externally powered USB switch. The Pi does not provide enough power to support two HDDs. Run:

sudo blkid


sudo fdisk -l

to see if your external HDDs are available and connected. Compare size, file system type etc. to identify your USB HDDs.

Check fdisk or blkid to see if the HDDs are available
Check fdisk or blkid to see if the HDDs are available

Our disks are connected as /dev/sda1 and /dev/sdb1.

4.2 Remove partitions

Please backup any data you want to keep before proceeding, we build a new RAID system and assume empty HDDs. If your HDDs have previous partitions, we have to remove them using fdisk:

sudo fdisk /dev/sda1

Enter “p” to get an overview of all available partitions. Press “d” to delete available partitions.

Command (m for help): d
Partition number (1-4): 4

Repeat with the default number (always the highest) until all partitions are removed. Repeat for the second HDD (in our case /dev/sdb1).

4.3 Create RAID 1

Now we are set up to create the RAID 1 system. Be careful to adapt your commands if your /dev/**** device names differ. Adapt accordingly and enter:

sudo mdadm --create --verbose /dev/md0 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1

The parameter –verbose enforces that we will see all debug output during the process. /dev/md0 is the path where we will access the RAID system. The parameter –level defines the RAID type. We use 1 for mirroring (data redundancy). You can use 0 for striping etc. We do not recommend striping, since you will not gain any performance due to the RaspberryPi´s limited BUS and LAN speed. You will however gain more storage. Finally, –raid-devices specifies the amount of HDDs we plan to use.

RAID 1 created successfully
RAID 1 created successfully

4.4 Wait to finish resync

The RAID system is now bulding up and syncing. Depending on your HDD size and speed this may take several hours, or in our case, days for 5 TB (about 70hours). Check the status manually via:

sudo cat /proc/mdstat

or use the watch command to get updates automatically:

sudo watch cat /proc/mdstat

Depending on the time (which shows the finish=xxxx in minutes output) you can quit Putty and do something fun 🙂

Check RAID assembly progress
Check RAID assembly progress

If successful, you should see a similar output:

The RAID1 was successfully created
The RAID1 was successfully created

4.5 Assemble RAID array

After the sync we can continue assembling the RAID array manually:

sudo mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1

or automatically:

sudo mdadm --assemble --scan

Lets add the array to our mdadm config so that it is available after a reboot. First make a backup and generate a new config based on the assembled arrays:

sudo cp /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.bk
sudo /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf

Your config should look similar to this:

pi@raspberrypi:~ $ cat /etc/mdadm/mdadm.conf
# mdadm.conf
# Please refer to mdadm.conf(5) for information about this file.

# by default (built-in), scan all partitions (/proc/partitions) and all
# containers for MD superblocks. alternatively, specify devices to scan, using
# wildcards if desired.
#DEVICE partitions containers

# auto-create devices with Debian standard permissions
CREATE owner=root group=disk mode=0660 auto=yes

# automatically tag new arrays as belonging to the local system
HOMEHOST <system>

# instruct the monitoring daemon where to send mail alerts

# definitions of existing MD arrays
ARRAY /dev/md/0  metadata=1.2 UUID=a8a398a9:63822741:fe0f09fa:c0b1991f name=raspberrypi:0

# This configuration was auto-generated on Sat, 16 Apr 2016 09:21:01 +0000 by mkconf

Make sure you have an entry below “#definitions of extisting MD arrays”. If the automatic config generation did not work you can add it manually using an editor like nano:

sudo nano /etc/mdadm/mdadm.conf

Add your MD array definitions and exit with CTRL+X, press “y” to overwrite and “enter“. If you need additional information to add the array definition manually, try the following:

sudo mdadm --detail /dev/md0

You should see a similar output:

pi@raspberrypi:~ $ sudo mdadm --detail /dev/md0
        Version : 1.2
  Creation Time : Sat Apr 16 10:47:51 2016
     Raid Level : raid1
     Array Size : 4883627904 (4657.39 GiB 5000.83 GB)
  Used Dev Size : 4883627904 (4657.39 GiB 5000.83 GB)
   Raid Devices : 2
  Total Devices : 2
    Persistence : Superblock is persistent

  Intent Bitmap : Internal

    Update Time : Fri Apr 22 12:18:59 2016
          State : active
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

           Name : raspberrypi:0  (local to host raspberrypi)
           UUID : a8a398a9:63822741:fe0f09fa:c0b1991f
         Events : 54019

    Number   Major   Minor   RaidDevice State
       0       8        1        0      active sync   /dev/sda1
       1       8       17        1      active sync   /dev/sdb1

This also verfies that the RAID array is assembled correctly.

4.6 Format the RAID system

If the RAID is correctly initialized we can format it to ext4 file system:

mkfs /dev/md0 -t ext4

4.7 Mount the RAID system

Now we create a mount point in /media/PI_NAS_5TB. Please adapt your path choice accordingly. We set owner and permissions to the folder.

sudo mkdir /media/PI_NAS_5TB
sudo chown pi:pi /media/PI_NAS_5TB
sudo chmod 777 /media/PI_NAS_5TB

Note that setting permisisons 777 (everybody can read, write and execute) is considered unsafe. However, i would suggest you start using all permissions in order to avoid problems later on. As soon as everything is running smoothly, you can start adapting the permissions and ownership.

We have to get the UUID in order to auto mount the RAID system in /etc/fstab, to be available after a reboot.

pi@raspberrypi:~ $ sudo blkid | grep md0
/dev/md0: UUID="8f127f7e-a385-4c5c-a858-9f4b3e2cac70" TYPE="ext4"

Let us make a backup of the /etc/fstab before editing:

sudo cp /etc/fstab /etc/fstab.bk

If anything goes wrong, you can revert to the original /etc/fstab:

sudo cp /etc/fstab.bk /etc/fstab

Now we add our RAID system to /etc/fstab. Adapt your UUID to the output from blkid accordingly:

pi@raspberrypi:~ $ cat /etc/fstab
proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       2
/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
UUID=8f127f7e-a385-4c5c-a858-9f4b3e2cac70       /media/PI_NAS_5TB       ext4      rw,defaults     0       0
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

We use the UUID to identify our RAID. We mount the RAID to the folder we created earlier (/media/PI_NAS_5TB) with read and write (rw) access. The columns are seperated with tabs instead of spaces.

4.8 Test the RAID system

Let us mount and create a file on the RAID system to see if everything works:

sudo mount -a
> /media/PI_NAS_5TB/test_file
ls /media/PI_NAS_5TB/

If the ls command returns test_file, everything is ok. The RAID 1 system is working. You can perform a reboot via

sudo reboot

to ensure that everything is assembled and mounted correctly. After reboot, try entering sudo blkid:

pi@raspberrypi:~ $ sudo blkid
/dev/mmcblk0p1: SEC_TYPE="msdos" LABEL="boot" UUID="947B-B89A" TYPE="vfa PARTUUID="6f92008e-01"
/dev/mmcblk0p2: UUID="eda95d8a-9cdd-4224-96d0-890b4791600c" TYPE="ext4" RTUUID="6f92008e-02"
/dev/sdb1: UUID="a8a398a9-6382-2741-fe0f-09fac0b1991f" UUID_SUB="0845d675733-28e6-d73c-9a17d4ed7bec" LABEL="raspberrypi:0" TYPE="linux_raid_memb"
/dev/sda1: UUID="a8a398a9-6382-2741-fe0f-09fac0b1991f" UUID_SUB="7f17c9eb29e-124f-7464-9477acd8ab67" LABEL="raspberrypi:0" TYPE="linux_raid_memb"
/dev/md0: UUID="8f127f7e-a385-4c5c-a858-9f4b3e2cac70" TYPE="ext4"

If you see /dev/md0, everything is configured correctly after the reboot, and we move on to install Samba in order to upload some media files.

5. Install Samba

Samba allows to access a directory over a network from almost any device and operating system. We need this to comfortably add data to our RAID system. Load and install the Samba packages:

sudo apt-get install samba samba-common-bin

Now we have to create some folders to store our media data. We create Music, Movies, Series and Photos folder into a public folder.

sudo mkdir /media/PI_NAS_5TB/public/
sudo mkdir /media/PI_NAS_5TB/public/Music
sudo mkdir /media/PI_NAS_5TB/public/Movies
sudo mkdir /media/PI_NAS_5TB/public/Series
sudo mkdir /media/PI_NAS_5TB/public/Photos

Lets make our pi user owner of these folders and set 777 permissions recursivly:

sudo chown -R pi:pi /media/PI_NAS_5TB/public/
sudo chmod -R 777 /media/PI_NAS_5TB/public/

We have to adapt the Samba config to share the public folder. As always, before adapting configuration files lets make a backup first:

sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bk

Open the Samba config:

sudo nano /etc/samba/smb.conf

Adapt the your config accordingly (details below the config example):

pi@raspberrypi:~ $ cat /etc/samba/smb.conf
# Sample configuration file for the Samba suite for Debian GNU/Linux.
# This is the main Samba configuration file. You should read the
# smb.conf(5) manual page in order to understand the options listed
# here. Samba has a huge number of configurable options most of which
# are not shown in this example
# Some options that are often worth tuning have been included as
# commented-out examples in this file.
#  - When such options are commented with ";", the proposed setting
#    differs from the default Samba behaviour
#  - When commented with "#", the proposed setting is the default
#    behaviour of Samba but the option is considered important
#    enough to be mentioned here
# NOTE: Whenever you modify this file you should run the command
# "testparm" to check that you have not made any basic syntactic
# errors.

#======================= Global Settings =======================


## Browsing/Identification ###

# Change this to the workgroup/NT-domain name your Samba server will part of
   workgroup = WORKGROUP
   netbios name = RASPBERRY_NAS
   security = user

# Windows Internet Name Serving Support Section:
# WINS Support - Tells the NMBD component of Samba to enable its WINS Server
#   wins support = no

# WINS Server - Tells the NMBD components of Samba to be a WINS Client
# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
;   wins server = w.x.y.z

# This will prevent nmbd to search for NetBIOS names through DNS.
   dns proxy = no

#### Networking ####

# The specific set of interfaces / networks to bind to
# This can be either the interface name or an IP address/netmask;
# interface names are normally preferred
;   interfaces = eth0

# Only bind to the named interfaces and/or networks; you must use the
# 'interfaces' option above to use this.
# It is recommended that you enable this feature if your Samba machine is
# not protected by a firewall or is a firewall itself.  However, this
# option cannot handle dynamic or non-broadcast interfaces correctly.
;   bind interfaces only = yes

#### Debugging/Accounting ####

# This tells Samba to use a separate log file for each machine
# that connects
   log file = /var/log/samba/log.%m

# Cap the size of the individual log files (in KiB).
   max log size = 1000

# If you want Samba to only log through syslog then set the following
# parameter to 'yes'.
#   syslog only = no

# We want Samba to log a minimum amount of information to syslog. Everything
# should go to /var/log/samba/log.{smbd,nmbd} instead. If you want to log
# through syslog you should set the following parameter to something higher.
   syslog = 0

# Do something sensible when Samba crashes: mail the admin a backtrace
   panic action = /usr/share/samba/panic-action %d

####### Authentication #######

# Server role. Defines in which mode Samba will operate. Possible
# values are "standalone server", "member server", "classic primary
# domain controller", "classic backup domain controller", "active
# directory domain controller".
# Most people will want "standalone sever" or "member server".
# Running as "active directory domain controller" will require first
# running "samba-tool domain provision" to wipe databases and create a
# new domain.
   server role = standalone server

# If you are using encrypted passwords, Samba will need to know what
# password database type you are using.
   passdb backend = tdbsam

   obey pam restrictions = yes

# This boolean parameter controls whether Samba attempts to sync the Unix
# password with the SMB password when the encrypted SMB password in the
# passdb is changed.
   unix password sync = yes

# For Unix password sync to work on a Debian GNU/Linux system, the following
# parameters must be set (thanks to Ian Kahan <<> for
# sending the correct chat script for the passwd program in Debian Sarge).
   passwd program = /usr/bin/passwd %u
   passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .

# This boolean controls whether PAM will be used for password changes
# when requested by an SMB client instead of the program listed in
# 'passwd program'. The default is 'no'.
   pam password change = yes

# This option controls how unsuccessful authentication attempts are mapped
# to anonymous connections
   map to guest = bad user

########## Domains ###########

# The following settings only takes effect if 'server role = primary
# classic domain controller', 'server role = backup domain controller'
# or 'domain logons' is set

# It specifies the location of the user's
# profile directory from the client point of view) The following
# required a [profiles] share to be setup on the samba server (see
# below)
;   logon path = \\%N\profiles\%U
# Another common choice is storing the profile in the user's home directory
# (this is Samba's default)
#   logon path = \\%N\%U\profile

# The following setting only takes effect if 'domain logons' is set
# It specifies the location of a user's home directory (from the client
# point of view)
;   logon drive = H:
#   logon home = \\%N\%U

# The following setting only takes effect if 'domain logons' is set
# It specifies the script to run during logon. The script must be stored
# in the [netlogon] share
# NOTE: Must be store in 'DOS' file format convention
;   logon script = logon.cmd

# This allows Unix users to be created on the domain controller via the SAMR
# RPC pipe.  The example command creates a user account with a disabled Unix
# password; please adapt to your needs
; add user script = /usr/sbin/adduser --quiet --disabled-password --gecos "" %u

# This allows machine accounts to be created on the domain controller via the
# SAMR RPC pipe.
# The following assumes a "machines" group exists on the system
; add machine script  = /usr/sbin/useradd -g machines -c "%u machine account" -d /var/lib/samba -s /bin/false %u

# This allows Unix groups to be created on the domain controller via the SAMR
# RPC pipe.
; add group script = /usr/sbin/addgroup --force-badname %g

############ Misc ############

# Using the following line enables you to customise your configuration
# on a per machine basis. The %m gets replaced with the netbios name
# of the machine that is connecting
;   include = /home/samba/etc/smb.conf.%m

# Some defaults for winbind (make sure you're not using the ranges
# for something else.)
;   idmap uid = 10000-20000
;   idmap gid = 10000-20000
;   template shell = /bin/bash

# Setup usershare options to enable non-root users to share folders
# with the net usershare command.

# Maximum number of usershare. 0 (default) means that usershare is disabled.
;   usershare max shares = 100

# Allow users who've been granted usershare privileges to create
# public shares, not just authenticated ones
   usershare allow guests = yes

#======================= Share Definitions =======================

#   comment = Home Directories
#   browseable = no

# By default, the home directories are exported read-only. Change the
# next parameter to 'no' if you want to be able to write to them.
#   read only = yes

# File creation mask is set to 0700 for security reasons. If you want to
# create files with group=rw permissions, set next parameter to 0775.
#   create mask = 0700

# Directory creation mask is set to 0700 for security reasons. If you want to
# create dirs. with group=rw permissions, set next parameter to 0775.
#   directory mask = 0700

# By default, \\server\username shares can be connected to by anyone
# with access to the samba server.
# The following parameter makes sure that only "username" can connect
# to \\server\username
# This might need tweaking when using external authentication schemes
#   valid users = %S

# Un-comment the following and create the netlogon directory for Domain Logons
# (you need to configure Samba to act as a domain controller too.)
;   comment = Network Logon Service
;   path = /home/samba/netlogon
;   guest ok = yes
;   read only = yes

# Un-comment the following and create the profiles directory to store
# users profiles (see the "logon path" option above)
# (you need to configure Samba to act as a domain controller too.)
# The path below should be writable by all users so that their
# profile directory may be created the first time they log on
;   comment = Users profiles
;   path = /home/samba/profiles
;   guest ok = no
;   browseable = no
;   create mask = 0600
;   directory mask = 0700

#   comment = All Printers
#   browseable = no
#   path = /var/spool/samba
#   printable = yes
#   guest ok = no
#   read only = yes
#   create mask = 0700

# Windows clients look for this share name as a source of downloadable
# printer drivers
#   comment = Printer Drivers
#   path = /var/lib/samba/printers
#   browseable = yes
#   read only = yes
#   guest ok = no
# Uncomment to allow remote administration of Windows print drivers.
# You may need to replace 'lpadmin' with the name of the group your
# admin users are members of.
# Please note that you also need to set appropriate Unix permissions
# to the drivers directory for these users to have write rights in it
;   write list = root, @lpadmin

path = /media/PI_NAS_5TB
comment = RASPBERRYPI_Share
valid users = pi
force group = pi
create mask = 0777
directory mask = 0777
read only = no

You can adapt the Workgroup to your private settings. We use standard WORKGROUP. We recommend to uncomment security = user. This will prompt anyone to enter a valid password and user in order to access files on the public share.  The netbios name = RASPBERRY_NAS option defines the display name of the server in the windows explorer.

In the public folder (last part of the config) we enforce the user/group pi. That is of course not the real meaning of the public folder, feel free to change the name in the brackets to e.g. “private“. Our main target here is to see the server in the network and load some data onto it. Afterwards we can do the data and access seperation.

Press CTRL-X and confirm your changes with “y” and “enter“.

Lets check if the config was adapted correctly. Enter testparam

pi@raspberrypi:~ $ testparm
Load smb config files from /etc/samba/smb.conf
Processing section "[public]"
Loaded services file OK.
Press enter to see a dump of your service definitions

        netbios name = RASPBERRY_NAS
        server role = standalone server
        map to guest = Bad User
        obey pam restrictions = Yes
        pam password change = Yes
        passwd program = /usr/bin/passwd %u
        passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
        unix password sync = Yes
        syslog = 0
        log file = /var/log/samba/log.%m
        max log size = 1000
        dns proxy = No
        usershare allow guests = Yes
        panic action = /usr/share/samba/panic-action %d
        idmap config * : backend = tdb

        comment = RASPBERRYPI_Share
        path = /media/PI_NAS_5TB
        valid users = pi
        force group = pi
        read only = No
        create mask = 0777
        directory mask = 0777

Lets restart the service:

sudo service nmbd restart
sudo service smbd restart

or use:

sudo /etc/init.d/samba restart

Now you should be able to see the RaspberryPi Samba server in the explorer / finder and browse the directories we created earlier. You will be prompted for a user (pi) and password (raspberry).


Lets change the user password (to access data via Samba, not your root password)

sudo smbpasswd -a pi

Enter your password twice. Now you will connect to the Samba files via user (pi) and your newly entered password. Remember, to access the Pi via SSH you still use “raspberry” or the adapted password (if you changed the password earlier via raspi-config).

Finally lets start Samba as a service in order to have it available after reboot:

sudo update-rc.d samba defaults

6. Install MiniDLNA

In order to stream data from the Pi RAID to e.g. a Smartphone or SmartTV, we need a media server. We use MiniDLNA:

sudo apt-get install minidlna

Adapt the config:

sudo nano /etc/minidlna.config

Add media_dir directories according to the config below. A for music, V for video files, P for photos. We set the database directory to db_dir = /home/pi/.minidlna. This is where the MiniDLNA server stores its index database. Make sure to adjust the permissions properly (see 9. troubleshooting). We strongly recommend to uncomment the log_dir in order to have some debug messages if something goes wrong. friendly_name is the display name that shows up in DLNA devices like a SmartTV. inotify=yes will find and index new data in the media_dir directly.

pi@raspberrypi:~ $ cat /etc/minidlna.conf
# This is the configuration file for the MiniDLNA daemon, a DLNA/UPnP-AV media
# server.
# Unless otherwise noted, the commented out options show their default value.
# On Debian, you can also refer to the minidlna.conf(5) man page for
# documentation about this file.

# Specify the user name or uid to run as.

# Path to the directory you want scanned for media files.
# This option can be specified more than once if you want multiple directories
# scanned.
# If you want to restrict a media_dir to a specific content type, you can
# prepend the directory name with a letter representing the type (A, P or V),
# followed by a comma, as so:
#   * "A" for audio    (eg. media_dir=A,/var/lib/minidlna/music)
#   * "P" for pictures (eg. media_dir=P,/var/lib/minidlna/pictures)
#   * "V" for video    (eg. media_dir=V,/var/lib/minidlna/videos)

# Path to the directory that should hold the database and album art cache.

# Path to the directory that should hold the log file.

# Type and minimum level of importance of messages to be logged.
# The types are "artwork", "database", "general", "http", "inotify",
# "metadata", "scanner", "ssdp" and "tivo".
# The levels are "off", "fatal", "error", "warn", "info" or "debug".
# "off" turns of logging entirely, "fatal" is the highest level of importance
# and "debug" the lowest.
# The types are comma-separated, followed by an equal sign ("="), followed by a
# level that applies to the preceding types. This can be repeated, separating
# each of these constructs with a comma.
# The default is to log all types of messages at the "warn" level.

# Use a different container as the root of the directory tree presented to
# clients. The possible values are:
#   * "." - standard container
#   * "B" - "Browse Directory"
#   * "M" - "Music"
#   * "P" - "Pictures"
#   * "V" - "Video"
# If you specify "B" and the client device is audio-only then "Music/Folders"
# will be used as root.

# Network interface(s) to bind to (e.g. eth0), comma delimited.
# This option can be specified more than once.

# IPv4 address to listen on (e.g.
# If omitted, the mask defaults to 24. The IPs are added to those determined
# from the network_interface option above.
# This option can be specified more than once.

# Port number for HTTP traffic (descriptions, SOAP, media transfer).
# This option is mandatory (or it must be specified on the command-line using
# "-p").

# URL presented to clients (e.g.

# Name that the DLNA server presents to clients.
# Defaults to "hostname: username".
friendly_name=RasPi Media Server

# Serial number the server reports to clients.
# Defaults to 00000000.

# Model name the server reports to clients.
#model_name=Windows Media Connect compatible (MiniDLNA)

# Model number the server reports to clients.
# Defaults to the version number of minidlna.

# Automatic discovery of new files in the media_dir directory.

# List of file names to look for when searching for album art.
# Names should be delimited with a forward slash ("/").
# This option can be specified more than once.

# Strictly adhere to DLNA standards.
# This allows server-side downscaling of very large JPEG images, which may
# decrease JPEG serving performance on (at least) Sony DLNA products.

# Support for streaming .jpg and .mp3 files to a TiVo supporting HMO.

# Notify interval, in seconds.

# Path to the MiniSSDPd socket, for MiniSSDPd support.

Save and quit the editor. In order to start the minidlna server after reboot enter:

sudo update-rc.d minidlna defaults

Or start it once via:

sudo service minidlna start

After start / reboot try to connect to the MiniDLNA server via browser: Enter your RaspberryPi device IP and use the default port (if you did not adapt it) 8200. In our configuration:

If the MiniDLNA server is started correctly you should see a basic web page:


If you cannot connect to this server check the MiniDLNA log file.

cat /var/log/minidlna.log

There is a troubleshooting with common errors at the end of this tutorial. Please have a look.

If you have no problems, you can start uploading data to the server. If you do not see any files / changes you can force MiniDLNA to rescan the library via:

sudo minidlna -R

If you adapt / improve the MiniDLNA config, you have to reload the MiniDLNA server in order to take affect:

sudo service minidlna force-reload

You can start, stop and restart the MiniDLNA via:

sudo /etc/init.d/minidlna start
sudo /etc/init.d/minidlna stop
sudo /etc/init.d/minidlna restart

If inotify=yes the MiniDLNA will reindex the libraries after restart / start. This may take a while depending on the size of your library.

7. Testing

If not already happend, upload some music / videos via the Samba server onto the RaspberryPi. Check the MiniDLNA server page (<RaspberryIP>:8200) to see if the MiniDLNA indexed the files.

Then turn on a DLNA device and wait until the RaspberryPi Media Server shows up. Browse the library and play your favorite title.

8. Conclusion

It took us a while to get everything working smoothly, especially to have all the HDDs, RAID and server available atfter reboot. So if something is not working for you, invest some time, feel free to ask or comment and you will make it work.

Our setting here is very basic. Only the pi user is allowed to upload/delete data to the Samba server. Anybody is allowed to use the MiniDLNA streaming service though.

While uploading data we get an average of 10-12 MB/s which is almost the full bandwidth of a 100Mbit LAN. Streaming 1080p HD movies works flawlessly. We streamed two movies at the same time and the RaspberryPi had no problems.

All in all this is a really cheap NAS DLNA server. We spend about 240€ (~270$) for the two 5 TB HDDs and another 40€ (~45$) on the Raspberry. This system runs stable, our data is safe thanks to the RAID 1 system, you can store important data on the server without being troubled about data loss.

A year ago i bought a WD MyCloud system with 3 TB RAID 1 setup. I had multiple data losses there due to the crappy software, some weeks ago one HDD failed even if barely used, so i decided to build my own. Now i have 5 TB storage for under 300€ (~340$), while the 3 TB WD MyCloud was about 360€ (405$). Additonally the Pi is fast enough to run different apps, webserver etc., which makes it a cheap and in my opinion better alternative.

We hope this tutorial was understandable, if not please let us know.

9. Troubleshooting

Now we will show some errors / problems we stumbled over while configuring the RaspberryPi.


The only troubles that occured here for us were the huge amount of time to sync (empty) HDDs. Took about 70h.

9.2 Samba

During the research for this tutorial we found several users having problems with Samba. They had the server running and the config seemed correct. Windows either did not show the network device or the users received errors when trying to connect via explorer. In our experience most of the cases are caused by wrong / bad permissions. Thats why we suggest to start with chmod -R 777 on your shared folder in order to avoid that.

9.3 MiniDLNA

For the MiniDLNA, several errors occured:

minidlna.c:293: fatal: ERROR: Failed to open sqlite database! &nbsp;Exiting...
sql.c:41: error: SQL ERROR 8 [attempt to write a readonly database]

Make sure the created database (db_dir path in the config) is read and writeable by the user defined in the config. Default user is nobody. Adapt the user in the config or make sure that the default user can access the database file via chmod 777 /home/pi/.minidlna

The same problem occured here:

inotify.c:92: error: inotify_add_watch(/media/PI_NAS_5TB/Music) [Permission denied]
inotify.c:92: error: inotify_add_watch(/media/PI_NAS_5TB/Movies) [Permission denied]
inotify.c:92: error: inotify_add_watch(/media/PI_NAS_5TB/Series) [Permission denied]
inotify.c:92: error: inotify_add_watch(/media/PI_NAS_5TB/Photos) [Permission denied]

The MiniDLNA file scanner was not allowed to access the media folders of our server. Same as above, make sure the user in the MiniDLNA config has proper file permissions or make sure everybody can access the files via  chmod -R 777 /media/PI_NAS_5TB/Music etc.

Again, setting file permissions to 777 is considered unsafe.

Feel free to comment or ask if you have problems.


Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.