How To Build a Digital Photo Frame From a Raspberry Pi (Preliminary/Scope of Work)

I’ve had a first-generation Raspberry Pi B+ sitting around the house for quite a while now, and I’ve been wanting to build a few projects with it, but I simply haven’t settled on anything interesting until now. One project that I’ve had mulling around in my head for a while has been an internet-connected digital photo frame that a group of authorized users could add photos to remotely. Building a digital photo frame from a Raspberry Pi seemed like a nice project to combine software, hardware, and some light woodworking into a handsome package that I could eventually gift to someone.

With the gift strategy in mind, I’m going to be building this project as a plug-and-play device that I could “set and forget” in my Granny’s house, allow the rest of the family to drop photos into a shared folder, automatically update, and turn on and off at specified times. Taking into account Granny’s flowery language, I’m going to dub this Project Spoofy.

Project Spoofy (Digital Photo Frame From A Raspberry Pi) Workflow:

Set up Raspberry Pi

Set up cloud photo repository

Access cloud photo repository with DDNS/Port forwarding

Set up slideshow

Automatically login

Automatically run DDNS client and slideshow on boot

Automatically reboot system at set time to update slideshow

Power both the monitor and Raspberry Pi from single power supply input.

Automatically power on and off system

Replace default Apache information page with custom landing page

Build frame to house monitor and Raspberry Pi assembly

Naturally, we will need a few parts and supplies as the project goes on, but to start we’ll simply need a Raspberry Pi (with power supply), HDMI monitor and cable, and a keyboard and mouse. Since I’m using an early-generation RPi, I’ll also use a WiFi dongle to connect to the local wireless network.

This isn’t my first foray into the Raspberry Pi, but this will be my first full-on project with a tangible outcome. I’ve tinkered with an RPi-powered XBMC box (which couldn’t run 1080p video, so it was shitcanned) and played some with developing the RPi as a viable lightweight workstation terminal to varying levels of success. Naturally, like everything else in this blog, it’s a learning experience and a work in progress, so stay tuned as I develop and deploy the project!

Getting Started With Raspberry Pi

The Raspberry Pi is proving to be quite an interesting–and capable–little device. It’s a small system-on-a-chip (SoC) board with USB, GPIO, and HDMI interfaces that provides computing power roughly equivalent to a low-end smartphone in an open format for $35. Granted, the “real” price of an RPi depends on what you’re planning to do with it, but will definitely include an SD card (6GB or bigger, depending on your chosen OS flavor) and will often include a monitor, keyboard and mouse, and power supply. Sometimes you can scrounge around the workshop for these parts, but you may need to purchase them. There are a number of outfitters that market “starter kits” with common parts at various price points, so just know that getting started with Raspberry Pi might cost slightly more than the $35 core price tag.

The next thing that you’re going to need to know is how to use Linux. Don’t mess around with that Windows 10 IoT nonsense. Everyone who is anyone who is worth their salt is going to be developing in FOSS (Free/Open-Source Software) because that’s how and why the RPi was made. Besides, putting Windows 10 on RPi requires that you install Windows 10 on your desktop, and I wouldn’t entirely recommend that. Don’t worry if you’ve never used Linux, it’s all part of the fun! The Raspberry Pi was developed as an educational tool to help people learn how to better interact with sophisticated computer systems–how to read new languages and write in code. There are lots of resources online that can get you familiar with the basics, including an entire section of this very website.

Getting Started With Raspberry Pi

Once you’re ready to begin working with the Pi, you’re going to need an operating system. This–if you didn’t know–is the set of instructions that tell the computer how to process information and how to behave under certain general conditions. By default, Raspberry Pi uses Raspbian, a specially-designed version of the Debian Linux distro. You could use Ubuntu Mate, OpenELEC, but I like the “official” support that comes from Raspbian, and it’s what I’ll be using for most of my projects.

Download the NOOBS installer from the Raspberry Pi Foundation and unzip it to a convenient location on your main computer. Stock NOOBS comes with Raspbian and WiFi support by default while NOOBS Lite will require a hardline connection to the internet to download your OS of choice.

Download the SD Card Formatter from the SD Association and install it according to their instructions. Insert your SD card into your card reader and format it with the application.

Copy the extracted contents of the NOOBS zip file to the formatted SD card, eject it, and insert the card into the slot on the Raspberry Pi.

Make sure that your Raspberry Pi has keyboard, mouse, and monitor plugged in, then plug the USB power cable into the Raspberry Pi. The device will boot into the NOOBS installer and allow you to choose your operating system. Select “Raspbian” from the list and click “Install”. The process may take a few minutes, so fix a cuppa tea and have a sit. When installation is finished, the configuration menu will appear. Make the appropriate adjustments to settings, then click the “Finish” button.

If you are dumped out to a text screen asking for login information, the default user is “pi” (always lower-case user names in Linux) and the password is “raspberry”. You can always change these credentials later. If you prefer to play with the graphical user interface, type startx and hit enter/return.

How To Install ownCloud on Raspberry Pi

OwnCloud is a clever self-hosted alternative to Dropbox and its ilk that provides the same services without the expense of subscriptions or the likelihood that government or marketer’s eyes are prying into your documents. For most consumers, this might be considered more trouble than it’s worth, but rolling your own cloud server under your control is essential to keeping the free and open web–well, free and open. The Raspberry Pi’s $35 price tag makes it especially handsome for a low-cost cloud server using free and open source software. In addition to being an excellent option for cloud storage–especially for those of us with terabytes of material to store–ownCloud is going to provide us with easy online access to photo storage for Project Spoofy. We’ll just point the slideshow application to the ownCloud folders for simplicity later! For now, let’s get started with how to install ownCloud on Raspberry Pi.

How to install ownCloud on Raspberry Pi

First, we need to add the ownCloud repository to the Pi’s sources list. At the command prompt, type sudo nano /etc/apt/sources.list.d/owncloud.list and hit return. This will create a new text file in the Nano text editor. On the first line of the text file, type deb /

Type CTRL+x to exit Nano, then Y and return to save.

Now we need to add the repository key so we can access the repository. Download the key by typing wget at the command prompt. Once the key is downloaded, add it to the repository by invoking sudo apt-key add - < Release.key

After adding the key, update the repositories by typing sudo apt-get update and return.

Now, we can install ownCloud by typing sudo apt-get install owncloud and return. Press Y for any questions the system asks you, and sit back while ownCloud and MySQL are installed. At some point, MySQL will prompt for a  root password. Choose something interesting and note it for later.

Setting Up ownCloud’s Directory Permissions

Once everything is finished installing, it’s time to set up ownCloud’s directory permissions. First thing, we need to make sure that HTTP has ownership of the ownCloud directory. To do this, make www-data the owner of owncloud by invoking the following command:

chown -R www-data:www-data /var/www/owncloud

Now that HTTP has ownership, we need to adjust the permissions for maximum security. ownCloud has actually provided a script to set all the permissions automatically. Copy the following, paste into a shell script (*.sh file, such as “” for example) using Nano, and save to a convenient location on the Pi.


printf "Creating possible missing Directories\n"
mkdir -p $ocpath/data
mkdir -p $ocpath/assets

printf "chmod Files and Directories\n"
find ${ocpath}/ -type f -print0 | xargs -0 chmod 0640
find ${ocpath}/ -type d -print0 | xargs -0 chmod 0750

printf "chown Directories\n"
chown -R ${rootuser}:${htgroup} ${ocpath}/
chown -R ${htuser}:${htgroup} ${ocpath}/apps/
chown -R ${htuser}:${htgroup} ${ocpath}/config/
chown -R ${htuser}:${htgroup} ${ocpath}/data/
chown -R ${htuser}:${htgroup} ${ocpath}/themes/
chown -R ${htuser}:${htgroup} ${ocpath}/assets/

chmod +x ${ocpath}/occ

printf "chmod/chown .htaccess\n"
if [ -f ${ocpath}/.htaccess ]
  chmod 0644 ${ocpath}/.htaccess
  chown ${rootuser}:${htgroup} ${ocpath}/.htaccess
if [ -f ${ocpath}/data/.htaccess ]
  chmod 0644 ${ocpath}/data/.htaccess
  chown ${rootuser}:${htgroup} ${ocpath}/data/.htaccess

Now, make the script executable by typing chmod u+x / and enter, then execute it by typing

Set up MySQL

One last step before we run the installation wizard: we must create a MySQL database. When we installed ownCloud, MySQL was installed by default, so we have that going already. Now, just log into the MariaDB client as root by typing mysql -u root -p and return at the command prompt. MySQL will ask for the root password you set earlier then display a new command prompt.

You’ll need to choose a database name, user, and password for ownCloud. In this example, I’ll be using some generics (dbname, dbuser, dbpw), but feel free to make it your own.

Type the following commands at the MySQL prompt (case-sensitive):


GRANT ALL ON dbname.* TO dbuser@localhost IDENTIFIED BY 'dbpw';
Then, exit the client by typing quit and return.

Lastly, reboot the Raspberry Pi to make sure all the changes are updated.

Run the ownCloud Installation Wizard

We’re finally ready to start running ownCloud! From the Raspberry Pi command prompt, type startx and return to enter the GUI so we can launch a web browser. Using the browser, navigate to http://localhost/owncloud. If everything was set up correctly, you should see the following screen:

Install Owncloud on Raspberry Pi

Fill in the blanks with whatever you would like your ownCloud administrator account credentials to be, click the “Storage & database” drop-down and verify that the storage directory is correct and that MySQL is selected. Also enter the MySQL account credentials that you set up in the last section. Click the “Finish setup” button and you should be dropped into ownCloud’s web interface.

It is possible (if you’re accessing ownCloud from a different computer using the Raspberry Pi’s IP address) that you may run across a “Trusted Domains” error. If that happens, follow the instructions on the screen. If you are unable to automatically add your domain to the whitelist, you will need to do so manually by editing the config.php file in the owncloud directory.

Install Owncloud on Raspberry Pi

Open a terminal window and type sudo nano /var/www/owncloud/config/config.php to edit the configuration file. Look for the section that looks like the following:

'trusted_domains' =>
  array (
   0 => 'localhost',

and change it to look like

'trusted_domains' =>
  array (
   0 => 'localhost', 'IP OR URL ADDRESS HERE',

where you simply add the IP or URL addresses that you wish to use to access ownCloud. This will come in handy later when we set up remote access. Save the config.php file and reload ownCloud. You should be now able to access the application without a problem!

For more information, please see the ownCloud documentation as well as detailed instructions here and here. I’ve done my best to parse all the pertinent instructions from these sources into something simpler for even the novice to be able to follow.

How To Set Up Dynamic DNS Using No-IP on Raspberry Pi

Now that we have a working ownCloud installation on our Raspberry Pi, we need a way to be able to remotely access the device from across the internet. Knowing the IP address and forwarding the appropriate ports on the router is only part of the story: most residential ISPs will periodically change the external IP address of their customers for logistical reasons that we won’t get into here (it’s a matter of traditional infrastructure limitations and convenience for the ISP). We’re going to need a way to automatically keep track of the IP address of the device as it potentially changes; as a fortuitous consequence, we’re going to be able to get an easy-to-remember URL in exchange. To do all this, we’re going to set up dynamic DNS using No-IP on Raspberry Pi.

No-IP is a service that allows you to assign a static domain name to a dynamic IP address. Their basic level of service is free, but only affords a limited selection of domains and has to be renewed every 30 days. There are paid offerings available with more features, but for our purposes, we’ll stick with the free product. To get started, sign up for an account at Once logged into your account, click the “Add a Host” button and fill in the appropriate information: choose a domain, host type [which should be DNS Host (A)], and the external IP address for the network to which the Raspberry Pi is connected. Click the “Add Host” button at the bottom, and then it’s time to set up the client on the RPi.

Using No-IP on Raspberry PI

On the Raspberry Pi, open a terminal session. The first thing we’ll need is a directory to install the Dynamic Update Client. Type mkdir /home/pi/noip and press enter, then navigate to the directory by typing cd /home/pi/noip.

Download the client by typing wget then unzar the archive file by invoking tar vzxf noip-duc-linux.tar.gz and enter the newly written directory with cd noip-2.1.9-1

Now we can install the client using sudo make and then sudo make install. During the installation process, you will be asked for your NoIP credentials as well as your preferred refresh interval (in minutes). Enter them when prompted, then wait for the setup to complete.

Once the installation is complete, run the client by invoking sudo /usr/local/bin/noip2. You can always check on the status of the client by invoking sudo noip2 -S (for status!)

Port Forwarding

Now, all you have to do is set up port forwarding on your router to point port 80 to the Raspberry Pi. Every router’s instructions are going to be slightly different, so check your particular model’s documentation. My Linksys router hides the port forwarding options under the security section and the “Apps and gaming” section. If you make sure that HTTP (port 80) points to the internal IP address for the  RPi, you should be able to navigate to the domain you previously set up on No-IP and reach the default Apache information page. If you get this page, everything is working!

Create a Linux slideshow using fbi

Fbi (Frame Buffer Imageviewer, not that other FBI) is a great lightweight Linux slideshow viewer that’s executable from the command line. It’s super simple to install, too:

sudo apt-get install fbi

Fbi will take any file or folder you specify in the command and create a slideshow. All the parameters are specified in the command line, for example:

fbi -noverbose -a -u -t 180 /PATH/TO/PHOTOS/*.jpg

For Project Spoofy, I’m going to point the fbi path to the ownCloud installation, but there’s a hitch: ownCloud has strict permissions, so it can only be accessed by root. In order to run fbi, we’ll need to run it as root. We can’t do this through sudo, though, as that only elevates privileges of the current user (pi). We’ll have to enable the root account either by logging in or by invoking the sudo -i command.

For more information on the fbi application, check out the manpage here.

How to Automatically Login to Linux

For Project Spoofy, I’m using fbi to pull photos from ownCloud and display them automatically on screen with no further input. In order to do this properly, the system must automatically login to Linux without a password. What’s more, I need the system to login as root so that fbi will have access to the proper folders to display images. Since we’re working on a Raspberry Pi, note that these instructions are specific to Debian and it’s derivatives.

How to automatically login to Linux

To do this, we simply need to edit the getty@.service file

sudo nano /lib/systemd/system/getty@.service

Then change the file that reads ExecStart=-/sbin/agetty --noclear %I $TERM to ExecStart=-/sbin/agetty --noclear -a USERNAME %I $TERM

Adding the -a option will enable autologin for the USERNAME that follows, so -a root will automatically login to the root account.

How to schedule a task in Linux

Sometimes, you need a task to run at a particular time on a particular schedule. For Project Spoofy, I need the Raspberry Pi to reboot periodically so that any new photos added to ownCloud will be subsequently added to the fbi slideshow. For simplicity, I’m going to schedule a task in Linux to reboot the Pi each night at about 2:30AM, so no one should be affected by the short break in the slideshow.

Schedule a task in Linux

To schedule a task in Linux, use the cron utility to define the schedule as well as the command to be executed. Cron has to be edited by the root account, so a standard user (pi) would need to execute the following command:

cron -e -u root

If logged in as root already, simply execute cron -e

Debian will ask which utility to use to edit the crontab file; I prefer using nano as with everything else. Once the crontab file is open in nano, you will see some information as well as some example formatting. Basically, every task should exist on a separate line starting with the scheduling:
┌───────────── min (0 – 59)
│ ┌────────────── hour (0 – 23)
│ │ ┌─────────────── day of month (1 – 31)
│ │ │ ┌──────────────── month (1 – 12)
│ │ │ │ ┌───────────────── day of week (0 – 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
│ │ │ │ │
│ │ │ │ │
* * * * * command to execute
To reboot at 2:30AM every day, the following line must be appended to the end of the file:

30 2 * * * /sbin/shutdown -r now

The biggest thing to remember is ensuring that the time and time zone are correct. As a pilot, I understand the importance of UTC (or Zulu) time for coordinating across time zones, so I prefer to keep my remote machines set to UTC and do the math accordingly!