This is the server (i.e. the main) part of the Raspberry Pi home server setup.

Here you configure your Pi to be easily accessible on the network, create users and directories, set up permissions, configure daemons. Once all this is done you can start the daemons and test them.

First things first.

Static IP

If you use DHCP, it is useful to assign a static IP to your server, so you don't have to chase its IP and update hosts files constantly. This is not absolutely necessary, though.

To do this edit /etc/network/interfaces and configure your interface, in my case wlan0:

allow-hotplug wlan0
iface wlan0 inet static
wpa-ssid "XXX"
wpa-psk "XXX"

I thought the wifi would be able to obtain the keys from the supplicant. Even though wpa_supplicant was configured, I could not get it to work, so entering the ssid and psk solved it.

Then reload networking:

sudo /etc/init.d/networking reload

We have given the server the IP Test if the network connection works. Run ifconfig and verify that your interface is assigned the IP by looking at the inet addr field.


Go ahead and create the users that are going to perform backups on the server:

sudo adduser birdman

You might want to add these users to a home_group group of some sort. It is up to you.

sudo addgroup home_group
sudo usermod birdman -a -G home_group

I also have a special user for running the daemons, let's call it imaginatively server_user.

sudo adduser server_user
sudo usermod server_user -a -G home_group



You need to come up with a directory layout for your backup.

In my setup, there are personal backups per user, and for instance media files and code repos are in a shared space.

Each user can have their own directory on the hard drive.

Let us assume that the drive is mounted on /mnt/backup_drive.

  • /mnt/backup_drive
    • birdman
      • documents
      • projects
    • music
    • code
    • pictures

Once you are satisfied with the setup, you could add this mount to your fstab. The entry would be something like

UUID=XXXX-XXXX  /mnt/backup_drive  auto    rw,noauto,user,uid=server_user

The mount point should be owned by server_user. (also check man fstab)

Create birdman's directory and make him the owner:

mkdir /mnt/backup_drive/birdman
chown birdman /mnt/backup_drive/birdman

Other directories are shared and here owned by server_user:

mkdir /mnt/backup_drive/music /mnt/backup_drive/code

I changed their group to the home_group group and made them writable by the group. This will allow your users to write to the shared directories.

chgrp -R home_group /mnt/backup_drive/music
chmod 770 /mnt/backup_drive/music


I decided not to run the daemons as root, but as server_user. Since this user does not have access to /var/run and /var/logs, we are going to use an alternative structure for the necessary files in the home directory:

  • /home/server_user/home_server/
    • config/
      • rsyncd.conf
      • minidlna.conf
    • logs/
    • pids/
    • locks/

config contains configuration files for the daemons.

We are going to start the daemons with their PIDs written to files in the pid directory. This would allow us to kill the daemons without having to search for the pid.

We are also going to configure them to write their logs in the logs directory, and their locks, well, you know where.

Get the script

Check out this repo into server_user's home directory

git clone ~/home_server
cd ~/home_server

Create the necessary directories:

mkdir logs pids locks

Follow the instructions below for configuring each daemon.

Then you can invoke the included init.d-style script to start and stop services:

./ rsync start

These commands are responsible for calling the daemons with the config and pid locations set in this directory.

Setting up the rsync daemon

One of the advantages of using the rsync daemon is that it is configured through a file that gives you logical locations to sync to. This means that you could change the real layout of your backup and only have to update this config file instead of all the client configs that would otherwise contain absolute paths.

To find out more about the rsync daemon configuration, run man rsyncd.conf. It contains global parameters and the so-called 'modules'. A module can override any global option. Each module is a directory tree that is given a logical name. For instance the client does not need to know about the path /mnt/backup_drive.

Let us have a look at ~/home_server/config/rsyncd.conf:

pid file = /home/server_user/home_server/pids/
log file = /home/server_user/home_server/logs/rsync.log
lock file = /home/server_user/home_server/locks/rsync.lock
use chroot = no
read only = no
hosts allow =
port = 54777

    uid = birdman
    gid = birdman
    path = /mnt/backup_drive/birdman
    comment = "Birdman's space"

    uid = nobody
    gid = nobody
    path = /mnt/backup_drive/music
    comment = "Rock on"

As described above, resources such as pids and logs are configured to be created in the corresponding directories and not under root-owned ones.

We want to be able to write to the directories, and will not use chroot.

Only hosts from the local network are allowed on a custom port.

Then come the modules. The name in square brackes is the path rsync clients are going to use. For example (note the double colon):

rsync -avz ~/Documents hostname::bird/documents
rsync -avz ~/Music hostname::music

to write to a subfolder documents of /mnt/backup_drive/birdman and directly in /mnt/backup_drive/music.

Setting uid and gid for a directory only works when the daemon is run by root. These are here for illustration purposes.


Not much to say here, I normally create some bare repos in code/ and push to them.

cd /mnt/backup_drive/code
git init --bare imaginary_project

Then a client could do

git push master

(Here we use absolute paths)

Setting up apache

There are plenty of resources on how to do this, so I will leave it out of this tutorial.

Setting up dlna

minidlna worked right away for me. Go ahead and install it:

sudo apt-get install minidlna

It is configured with a file with an ini sort of format:


Where A stands for audio. Run man minidlna.conf for more information and look at the systemwide configuration in /etc/minidlna.conf and the provided home_server/config/minidlna.conf.example. It is best to copy this file and use it as base.

Create a minidlna.conf file in home_server/config and set up your media directories.

Then run

~/home_server/ dlna start

And this should do it.

other possibilities

I am running a moinmoin wiki for home-wide info.

owncloud is certainly a good fit to this setup. I had good experience with it previously, so it's on my todo list.

Of course you can open up your entire setup to access it from outside your home network, but this would be the topic of another tutorial.