Technology blog::Life hacks::Linux::Hardware::Gaming

Building a Raspberry Pi based Personal Cloud Server

How to install an Operating System on your new Raspberry Pi

By , Written on in Linux Projects

Building a Raspberry Pi based Personal Cloud Server

2,885 words, estimated reading time 14 minutes.

Now you have your new Raspberry Pi, you may be wondering how to use it. This guide will show you how to flash Raspbian, boot into your Raspberry Pi, configure and build a personal cloud server secured with SSL from Let's Encrypt.

Why a Personal Cloud Server?

Cloud servers such as Google Drive, Apple iCloud, Microsoft OneDrive and Dropbox are all well and good, but the free space they provide isn't very much these days (~5GB) and additional storage can be very expensive.

Most of the top cloud storage providers have had some form of security breach [1], [2] or problems with their platform resulting in data loss [1].


I also wanted a small public facing home web server for a few small personal applications, so I thought, "Why don't I put this Raspberry Pi to good use?" The Raspberry Pi 3 Model B has an impressive spec for a tiny computer, it should be more than enough to run a cloud storage server and a few web applications for a single user. As the Raspberry Pi has a very low energy footprint using it as an always-on web server makes it an ideal choice.

In this guide I'll cover installing Raspbian on the Raspberry Pi, setting up and configuring a web server, network security, nextCloud server and using Let's Encrypt X509 certificates for SSL and HTTPS.

Raspberry Pi
Raspberry Pi

You Will Need

  • Raspberry Pi (I'm using a Pi 3 Model B, other models may work)
  • Ascociated peripherals (moniter, keyboard, cables etc)
  • Micro SD card 8GB+
  • 32GB USB Thumb Drive / Flash Drive (for storing files)

Downloading and Flashing Raspbian

Raspbian is the official OS for the Raspberry Pi. You can install it with NOOBS or download the image and flash it to an SD card yourself. Since the Raspberry Pi has fixed hardware you can flash OS images to the SD card much in the same way as you flash a ROM to an Android smartphone.

For Raspberry Pi, the flashing tool of choice is Etcher. This is a graphical SD card writing tool that works on Mac OS, Linux and Windows, and is the easiest option for most users. Simply download the Raspbian image from the link above, Etcher from here, install and run Etcher. It gives you the option of selecting the image to flash, the destination SD card and a button to start the process. Simples.

Using Etcher to flash Raspberry Pi to SD Card
Using Etcher to flash Raspberry Pi to SD Card

Once the process is complete you simply insert the micro SD card into the Raspberry Pi and turn the power on. The Pi will then boot up into Raspbian.

Getting Started in Raspbian

Raspbian is based on Debian, so if you've used Ubuntu or Linux Mint then the system should be very familiar. If you've not used Linux before, I recommend you to read my tutorial series on getting started with Linux.

The default username and password for Raspbian is:

  • Username: pi
  • Password: raspberry

Once you are logged in, the first things to do are to change the password and run system updates.

To change a password in Linux, simply use the passwd command. In Raspbian you can also use sudo raspi-config to enter the configuration screens. Selecting the password option will allow you to change your password.

Rename Default User

If you wish to rename the default pi username, the process is simple but involves a few steps.

Firstly we need to create a new user.

sudo adduser username

Follow the prompts to set the new user's information. It is fine to accept the defaults to leave all of this information blank.

Use the usermod command to add the user to the sudo group.

sudo usermod -aG sudo username

Now logout of the pi user and log in with the new username.

Now, simply enter these commands into the terminal. The first command renames the user, the second renames the users home directory.

sudo usermod -l techman pi
usermod -d /home/techman -m techman

You can now delete the new user as we won't be needing it again.

userdel username

Running System Updates in Linux

Running system updates is performed by issuing the following command in the terminal.

sudo apt-get update && sudo apt-get upgrade

The next thing to do is setup SSH so I can access the Pi from my desktop. This is easy enough to do as SSH is already installed on the Raspberry Pi, it's just disabled by default. To enable SSH on the Raspberry Pi enter the raspi-config tool, select Interfacing Options and select SSH.

The default hostname for a Raspberry Pi is raspberrypi. Very imaginative. If you would like to change it, you can do that from the raspi-config screen as well. In the remainder of this tutorial simply replace raspberrypi with whatever you chose.

Setting a Fixed IP Address

It is often handy to have servers with a fixed IP address, that way it is easier to remote into them and to setup firewall rules. In my case, later on I will need to port forward the HTTP and HTTPS ports to the Pi and my router requires a static IP address for this.

Simply edit the DHCP daemon config

sudo pico /etc/dhcpcd.conf

And at the bottom, add in eth0 (Ethernet) or wlan0 (Wireless adaptor) these lines. You should change the IP addreses as provided by your network setup or system administrators.

interface eth0
static ip_address=
static routers=
static domain_name_servers=

Reboot for the changes to take effect.

Installing Apache and PHP

In order for your Raspberry Pi to work as a web server, we need to install the Apache web server, PHP for server side scripting and MySql for databases.

To install Apache and PHP, you need to run these commands to start the installation. With the release of Stretch, Debian has removed the obsolete PHP5 package so we must use the newer PHP 7.

sudo apt-get install apache2 php7.0 php7.0-gd libapache2-mod-php7.0 php7.0-curl

When the installation is complete you can start Apache with this command.

sudo service apache2 restart

Now you should be able to access the default web page in a browser on another computer by entering http://raspberrypi.local in your browsers address bar.

For setting up websites in Apache, please refer to the article Apache Administration on Linux

Installing MySQL, MariaDB and Creating Root User

Now to install MySql. This is also simple, just type in these commands.

sudo apt-get install mysql-server python-mysqldb php-mysql

Now for the not so simple part. MySQL 5.7 changed the secure model so that now MySQL root login requires a sudo level execution. This means that root can no longer be used for web logins via PHP. The simplest and safest solution will be create a new user and grant required privileges.

sudo mysql --user=root mysql

Run the following commands, replacing some_pass by the desired password.

  1. CREATE USER 'techmantium'@'localhost' IDENTIFIED BY 'some_pass';
  2. GRANT ALL PRIVILEGES ON *.* TO 'techmantium'@'localhost' WITH GRANT OPTION;

Now you should be able to login with this user later on in this tutorial.

Linux Network Security

Linux server security isn't complicated. There are a few applications to install and configure which will block 99% of attacks an internet facing web server can be exposed to. Follow these step by step and you should be fine, but as with everything, there are no guarantees. If you have any suggestions to add to this list, please let me know in the comments below.

Install Fail2ban

Fail2ban is a daemon that monitors login attempts to a server and blocks suspicious activity as it occurs. It’s well configured out of the box.

apt-get install fail2ban

Install a Firewall

No secure server is complete without a firewall. Linux provides a good firewall called ufw, which makes firewall management easy. Install it with this command:

sudo apt-get install ufw

We now need to configure it thusly.

sudo ufw allow from {your-ip} to any port 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable

This will allow all traffic from your IP address (e.g. a desktop used to SSH into the Raspberry Pi) and from any other address, only port 80 (http) and 443 (https) will be accessible.

That's security on the server sorted. I said it was easy!

When I'm ready to put this Raspberry Pi server live, I'll forward ports 80 and 443 to the Pi IP address on the router. By forwarding these two ports, any attempts to access the Pi on any other port from the internet will be blocked by my router first.

Now is a good time to reboot the Pi so that all the new changes can take effect.

sudo shutdown -r -t 0

Installing NextCloud

NextCloud is a suite of client-server software for creating and using file hosting services. It is functionally similar to Dropbox, although NextCloud is free and open-source, allowing anyone to install and operate it on a private server.

Installing NextCloud to the Raspberry Pi is quite simple, although it is more involved than previous installations.

I'm using the default Apache www directory for this, if you have changed the location then adjust the commands accordingly. Also, note this is the current version as of writing. You should check the NextCloud website download page for the latest file version.

First, change directory to the HTML root.

cd /var/www/html

Now we need to download the NextCloud archive to this folder and extract it. This file was the latest as of time of writing, please refer to the NextCloud website for the most up to date version.

sudo wget
sudo unzip

This will extract all the required files to a new nextcloud directory. Next, we must make the data directory and assign permissions to the www-data user which Apache uses.

sudo mkdir -p /var/www/html/nextcloud/data
sudo chown www-data:www-data /var/www/html/nextcloud/data
sudo chmod 750 /var/www/html/nextcloud/data
cd nextcloud
sudo chown www-data:www-data config apps

The Apache user also needs permissions to config and apps directories, so we change the ownership to www-data.

NextCloud requires a few Apache modules to be installed. They can be added using this command.

sudo apt-get install php7.0-xml php7.0-zip php7.0-mbstring php-xml
sudo service apache2 restart

Now we can start the web interface part of the installation. This can be done by browsing to http://raspberrypi.local/nextcloud.

Configuring NextCloud

If all goes according to plan, you should see the NextCloud installation page when you access the page.

NextCloud installation wizard
NextCloud installation wizard

Enter in details for an admin user to create, and specify the details for the database connection. Don't worry about the storage location just yet, we'll tweak the settings in a minute.

Hopefully, when the process completes, it does take a little while, you should see the screen below.

NextCloud installation wizard
NextCloud installation wizard

Setting the NextCloud Data Directory

Raspberry Pi
Raspberry Pi

This part is optional. For me I'm using an 8GB micro SD card, which doesn't offer much for cloud storage, so to add more space and reduce stress on the micro SD card, I've added a 32GB USB thumb drive to my Pi which I will use exclusively for storing my files. I've created a data directory in /media which will be used to mount the drive.

sudo mkdir /media/data

I will then add the USB mount to the automatic fstab file so that it will mount automatically at boot.

First, you will need to know the uid of the www-data user on your system. This is as easy as typing in

id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Next we need to know the block device associated with the USB drive:

fdisk -l
Disk /dev/sda: 29.7 GiB, 31914983424 bytes, 62333952 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
Disklabel type: dos
Disk identifier: 0x0006c0e4
Device     Boot Start      End  Sectors  Size Id Type
/dev/sda1  *     2048 62333951 62331904 29.7G  c W95 FAT32 (LBA)

Now we know these pieces of information we can proceed to edit the automount entries.

sudo pico /etc/fstab

Now to mount the drive on boot, add the following line

/dev/sda1 /media/data vfat auto,rw,uid=33,gid=33,umask=0027 0 0

This mounts sda1 to /media/data as a FAT32 partition, automounted, read and write enabled with user and group owner of www-data and the permissions of 0755. For more information on the permissions, see this post fstab Permission Masks Explained.

Now to mount the drive run this. If all is well you can cd into the data directory and view any files already there, in my case a test.txt file written in Windows.

sudo mount -a

Next, we can tweak the settings in NextCloud config to point to this directory and improve security a little.

First, change directory to the nextcloud config folder if you're not already there.

cd /var/www/html/nextcloud/config

Next, we'll take a backup, just in case anything gets messed up.

sudo cp -p config.php config.php.bak

Now we'll edit the file in your favourite text editor.

sudo pico config.php

In this config file, we need to locate and change the following line

'datadirectory' => '/var/www/html/nextcloud/data',


'datadirectory' => '/media/data',

Save and close the file. You now need to create the data placeholder marker into the new data directory.

touch /media/data/.ocdata

This will create an empty hidden file which NextCloud looks for. Now you can go back to your NextCloud web browser and refresh the page. Your files should now be served from the new location.

Increasing Nextcloud’s max upload size

The default file upload size is very small by today's standards, it won't even let you upload a photo from the iPhone camera. To change this, we need to modify the php.ini file and increase the limit.

sudo pico /etc/php/7.0/apache2/php.ini

Now we need to find and replace the following two lines.

post_max_size = 8M
upload_max_filesize = 2M


post_max_size = 1024M
upload_max_filesize = 1024M

This will allow files of 1GB to be uploaded. Feel free to change that number to whatever you think is the maximum size file you will upload to your NextCloud.

For these changes to take effect we need to restart Apache.

sudo service apache2 restart

Setting up SSL for Nextcloud

For any web server running on the open internet, it is vital that we use some form of encryption when communicating. For this, we use an X509 certificate and the HTTPS protocol. Because I will be hosting this on my business connection, I have a static IP address and domain name to use. These are required when using the Let's Encrypt service. You can also use a self-signed certificate but you may get security warnings. The data is still encrypted, it's just that your browser cannot verify the server identity with a trusted third party.

Obtaining a certificate from Let's Encrypt

The first thing to do is install the certbot tool. This will do most of the work for us.

sudo apt-get install python-certbot-apache

Next, we need to configure Apache, since certbot will read this file to obtain domain-specific information.

sudo pico /etc/apache2/sites-available/000-default.conf

Within the Virtual Host block, add or uncomment the ServerName directive and set it to your domain name. Save and close the file and test the config using this command.

sudo apache2ctl configtest

If you did the change correctly you should see Syntax OK. Restart Apache then we are good to proceed to obtain the certificate.

sudo certbot --apache

Certbot will read in the apache config and present a list of domains we can install the certificate for. Hopefully, yours is now on the list, so go ahead and select it from the menu.

Which names would you like to activate HTTPS for?
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):

You will need to provide a valid email address which you can receive confirmation and security messages about. Typically these are just notices regarding renewing the certificate.

Finally, accept the terms and conditions, and certbot goes away and does its thing. If you get errors about "Failed authorization procedure." or "The server could not connect to the client to verify the domain" check that your 443 port is forwarded correctly on your router and that the rules are allowed on the firewall (ufw status).

During the process, there is the option to have all requests redirect to the secure site. I recommend doing this so that everything is sent encrypted. All this does is add an entry to the config which redirects all non-https traffic to the https equivilant. You can also manually add this to the .htaccess for the same result.

RewriteEngine on
RewriteCond %{SERVER_PORT} 80 
RewriteCond %{SERVER_NAME} [NC]
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]

The final step is to add the domain name to NextClouds trusted domain list, else you will get a message stating access from an untrusted domain is denied.

sudo pico /var/www/html/nextcloud/config/config.php

Locate the trusted domains and add a new line.

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


Hopefully, you should now have a secure Raspberry Pi web server complete with NextCloud personal cloud storage configured!

Last updated on: Thursday 30th November 2017

Did you Like this Post? Why not Like us on Facebook?


Further Reading
  1. Johnny

    As said in the fstab file, you can use "UUID= as a more robust way to name devices, that works even if disks are added and removed."

    Now to get that UUID it's very easy :
    -get your device's name (e.g. /dev/sda2) with the disk utility gui, or with sudo fdisk -l, or with gparted
    - use this name to get the UUID : sudo blkid /dev/sdax (your device's name)

    Then add the entry to fstab replacing "/dev/sdax" by "UUID=[your device's UUID]".

  2. Roger Smith
    Roger Smith

    Nice write-up, I followed it step by step and worked perfect for me. Only thing I'd add is that after getting everything setup, take a backup image of the SD card in case it gets corrupt. Thanks for your efforts in writing.

Leave a Reply

Your email address will not be published.