A Raspberry Pi File and Print Server

I was recently looking into the options to buy a living room “home server” to centralize certain services like file and print server, media server, etc.

It didn’t take me long to realize that for less money I could get a whole legion of small microcomputers that do the same work better and more securely; and use less energy while doing so.

This was of course the pretext to buy my first Raspberry Pi. A few more should follow… This article starts a little series explaining what I did and how I did it. Today, I will look at the first and simplest type of server:

#1: Print and File Server

Until now, I had a USB-printer (a Brother HL-2030) connected to the family PC in the living room. The printer was shared so we could print from any computer, but of course, this only worked when the PC was switched on, and printing from an iPad or iPhone? Who would even try to do that?

The same PC also had a large (2 GB) USB hard disk connected. This served as a backup drive, mostly for media files, the music collection, software installers, etc.

This looked like a good case study for using a “Raspi” as home server. In fact, it even turned out easier than expected. Here’s what you need:

  • Raspberry Pi, Model B
  • A memory card (4 GB or more, Class 6 or higher)
  • A suitable power supply
  • a case for the Raspberry Pi
  • Ethernet cable (and a free port in your router)

Of course, the resources you want to serve:

  • A USB hard drive
  • A USB printer

During the setup process, you will also need:

  • A USB keyboad
  • A computer with a card reader
  • A HDMI cable and a TV set with HDMI input (or an adapter to whatever you have), or
  • alternatively: a RCA cable and possible adapters to connect it to your monitor or TV

A few notes on these items:

  • Although this project should work with a 2 GB SD card, I recommended that you use one that has at least 4 GB capacity. I am actually not buying anything smaller than 16 GB these days, as they offer the best value-for-money nowadays.
  • The Raspberry’s card interface can’t read or write faster than ca. 20 MB/s. Don’t waste money for cards that are much faster than this. But don’t use a much slower card either.
  • Before you buy an SD-card, check the compatibility list. Not all cards work.
  • Many mobile phone chargers can be used as power supplies. Check your drawers before you buy a new one, but be aware that some power adapters are known to cause problems. There is, of course, another compatibility list for these.
  • The keyboard is only needed for a short time during the setup phase. If you don’t have a spare one, you can probably borrow it from your PC…
  • The same applies to the HDMI cable. You can probably borrow one from some set-top box for the few minutes that you’ll need it.
  • It is possible to use a USB WiFi dongle instead of a network cable. In this case you probably also need a USB hub and if you have that, then a “model A” Raspberry might be good enough for you. This is, however, not covered by this guide.

1. Setup

Set up the SD card according the the instructions here. For this build, you should either download and install the latest Raspbian package, or the NOOBS image and then select Raspbian from the menu. The latter is easier to install on the SD-card but requires more space (min. 4 GB).

Then insert the card to your Raspberry, connect the TV, the network, the keyboard and the power supply (in this order) and watch it start up.

The first time Raspbian is started, it asks you if you want to configure the system. Sure you do:

  • change the password to something you can remember (but nobody else can guess)
  • if you have more than one Raspberry, you should change its name to something unique for your network (need inspiration?)
  • make sure to enable SSH so you can connect to the command line from your computer
  • set your keyboard layout and location in the internationalization options
  • Memory split says how much memory is reserved for graphics. Set it to the minimum (“16”).

At the end, your Raspberry will be restarted and you get a brand new console window where you can log in – or simply connect with an SSH client to the Raspberry.

On Windows, PuTTY seems to be a good client. One of its advantages is that you can simply paste text in by right-clicking into it. This speeds up things quite a bit.

Update the System

You should make it a habit to regularly check for updated packages by entering

sudo apt-get update

and of course, install all updated packages:

sudo apt-get upgrade

At the very least, you should do that now.

Change Screen Resolution (optional)

If you want to use your TV set as a monitor, it is very likely that the screen resolution is too high for comfort (that is, unless you are sitting very close to the screen – in which case the screen is probably to large to work comfortably..)

First, find out which resolutions the monitor understands by entering the following command:

tvservice -d edid

This will generate a new (binary) file named “edid” which contains the resolution information. To parse this into a human-readable form, use the following command:

edidparser edid

This outputs a long (in most cases) list of resolutions your TV set can handle. Note that some of them are “CEA” and the others “DMT” modes. For all we need in this build, there is no difference between them, but it is worth to know that DMT does not support sound to be transmitted via the HDMI link, so if you want to play sounds on your TV set, better choose a CEA mode.

For me, 720×480 at 60Hz or 720×576 at 50Hz looked like reasonable screen resolutions for these cases where I may want to look at the Raspberry’s output. Just remember the codes your preferred resolution. We’re going to force the Raspberry to use this resolution from now on:

sudo nano /boot/config.txt

This opens the boot configuration file. There are many settings that modify certain aspects of how the Raspery Pi works hidden here, but we are only interested in two lines (move down about a screen or so to find them:

#hdmi_group=1
#hdmi_mode=1

To activate them, first remove the hash sign in front of both lines, then change them: If you chose a CEA setting, hdmi_group should be “1”, in case of a DMT mode it should be “2”. Secondly, hdmi_mode should of course be the code we established earlier. In my case, this section now looks like this:

hdmi_group=1
hdmi_mode=18

Unless you know what you are doing, I strongly recommend not to touch anything else in this file (if you are curious, there is documentation available for this file, of course).

Press Ctrl-O to save the file (press Enter to confirm), then Ctrl-X to exit the editor. After restarting the Raspery Pi with
sudo shutdown -r now
you should see the new screen resolution.

Install ZeroConfig Networking (optional)

ZeroConfig is a network protocol that, simply said, allows you to discover services in your network without fiddling about with IP-addresses, etc.

Installation is quite straightforward. First install the Avahi daemon:

sudo apt-get install avahi-daemon
Then make sure it is start as a server:
sudo insserv avahi-daemon
Now just make sure the server also knows what to advertise. This is defined in an XML file. A simple example would be:
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=RaspberryPi</txt-record>
</service>
<service>
<type>_ssh._tcp</type>
<port>22</port>
</service>
</service-group>

The easiest way to get this file onto the server is by connecting via SSH (see above) and start a text editor:
sudo nano /etc/avahi/services/multiple.service
Then simply copy and paste the above text into the window, press Ctrl-O to save and then Ctrl-X to exit.

You should now be able to refer to your Raspberry Pi by its ZeroConfig network name. That is always the machine name (by default: “raspberrypi”) plus the extension “.local”. So the complete name, if you didn’t change the host name, should be “raspberrypi.local”.

While you are at it, you should also consider installing additional tools to manage the Avahi services
sudo apt-get install avahi-utils
At the very least, this enables you to see if other ZeroConfig service announcements can be seen from this machine by entering:
avahi-browse -at

2. Installing NAS File Server

This will allow you to access the contents of a hard disk from any computer in the network.

Install NTFS file support (optional)

If you are planning to add a USB drive later that is installed in the NTFS file system, you should first install NTFS support by executing:
sudo apt-get install ntfs-3g
If, on the other hand, you only use FAT or ext as file systems, you can safely skip this step.

Mount the USB Drive

In principle you can use this technique to share any kind of USB volume: sticks, hard disks… you name it. However, it is probably most useful to connect a USB hard disk as the ratio of drive space per $moneyunit is best. Please keep in mind, though, that the Raspberry can’t power energy-hungry hard drives via its USB port, so you should use a drive case that has its own power supply.

You can also connect more than one USB drive: either via the second USB port (if you don’t want to use it as a print server as well) or via a USB hub.

Simply plug the USB drive into your Raspberry. It should be recognized automatically (though not auto-mounted) and appear as /dev/sda or /dev/sdb

To find its device name, simply run
sudo fdisk -l
You should get an output similar to this:

Disk /dev/mmcblk0: 15.9 GB, 15931539456 bytes
4 heads, 16 sectors/track, 486192 cylinders, total 31116288 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00047c7a

Device Boot Start End Blocks Id System
/dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA)
/dev/mmcblk0p2 122880 31116287 15496704 83 Linux

Disk /dev/sda: 2000.4 GB, 2000398934016 bytes
255 heads, 63 sectors/track, 243201 cylinders, total 3907029168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x918fd713

Device Boot Start End Blocks Id System
/dev/sda1 63 3907024064 1953512001 c W95 FAT32 (LBA)

It is easy to see: the first entry (here /dev/mmcblk0) is obviously the SD-card, the second one is the one we are looking for: the USD-drive is at “/dev/sda“, the first (and only) file system on it is a FAT32 partition located at /dev/sda1.

Let’s now mount this file system somewhere useful
sudo mkdir /media/usbhd1
sudo mount -t auto /dev/sda1 /media/usbhd1
And to make sure your Raspberry remembers this the next time you boot, we add this to the famous fstab file:
sudo nano /etc/fstab
by simply adding the following line to the end of the file:
/dev/sda1 /media/usbhd1 auto noatime 0 0
Then the same procedure as last time: Ctrl-O, Enter, Ctrl-X. Ready.

Installing Samba

Samba is the component that actually handles the Windows file sharing. Let’s get started by installing all its required components:
sudo apt-get install samba samba-common-bin
And before we start editing the Samba configuration file, its always a good idea to make a backup:
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.old
Time to start up the editor:
sudo nano /etc/samba/smb.conf
In the editor, first look for the following line:
workgroup = WORKGROUP
This is obviously your Windows workgroup name. For most of us, “WORKGROUP” is just fine, as this is also what Windows uses as a default. If you use a different workgroup name, please change it here.

Next, move further down until you find the “Authentication” section. There should be a line like this:
# security = user
Simply remove the hash symbol in the beginning of the line to activate user security.

Finally, we add a completely new section at the end of the file (scroll all the way down)

[Shared]
comment = Shared Disk
path = /media/usbhd1
valid users = @users
force group = users
create mask = 0660
directory mask = 0771
read only = no

The section name (the text inside the brackets – here “Shared”) is going to be the name of the folder as it will appear on the network share. You can of course change it to whatever you like; Likewise the comment value.

Once again: Ctrl-O to save, press Enter, Ctrl-X to exit the editor.

Add Users

Next we need to add user accounts that can connect to the server:

The following line adds a new user “user01” (that’s just an example, you may want to use another name) and adds it to the group “users”:
sudo useradd user01 -m -G users
Immediately set the password of this new user:
sudo passwd user01
And enter the new password twice.

Finally add this new user also to the Samba system:
sudo smbpasswd -a sascha
That’s it. Please repeat these steps for all users you want to add.

When you are done, restart the Raspberry:
sudo shutdown -r now
and then try to connect from a Windows machine. It should find the server by its machine name in the network and you should be able to connect to the shared folder.

3. Install the Print Server

In order to be able to use your Raspberry as a print server as well, you should first install the CUPS software:

Setup CUPS

Load and install the CUPS package:
sudo apt-get install cups
CUPS is set up by default to work as a local print server, to use it in a network we need to change some settings in the config file:
sudo nano /etc/cups/cupsd.conf
Firstly, find the line that says:
Listen localhost:631
This line says from where and under which port the user interface can be accessed. To be able to administer the printers from any computer in the network, change this line to:
Listen *:631
Then look for the different sections that start with
<Location
and simply add the following line to the end of each section (i.e. just before the closing “</Location>” line):
Allow @Local
there should be three places where you have to add this.

Next you should restart the CUPS service. You could simply restart the entire computer (see above), but it is sufficient to just restart CUPS by:
sudo /etc/init.d/cups restart

Before anyone can print, you need to add all users that should be able to print to the ‘lpadmin’ group:

sudo usermod -a -G lpadmin user01

Of course, you should substitute “user01” with the actual user name. Do this for each user you want to add.

Add a Printer

Now connect your printer to the USB port and then use your web browser to connect to the CUPS web interface. If you installed the Avahi daemon as described above, you can probably use a link like:

Alternatively you could use the IP address. In any case you need to add the port number that was specified in the previous step.

Simply follow the instructions on the web pages to add the printer. That’s it, you’re done.

Other ideas

Not tried yet, but may be interesting: it should be possible to share your music library via ZeroConf. Here’s more information.

Since there is no other web service running on the Raspberry, the CUPS web interface might as well listen on port 80 [tested, it works!)