NanoPi M4 Server
Table of Contents
- The Result
- The Parts
- Related Work
- The 3D Print
- The Setup
- Adding a Remote Widget
- Setting up a mirrored RAID (level 1)
- Performance Tests (or Playing around with 2 SSDs and mdadm)
The Result
A small (20x16x9cm) server based on the NanoPI M4 + SATA hat. Check my youtube video below:
The Parts
Amount | Part | Type | Datasheet | Links |
---|---|---|---|---|
1 | NanoPi M4 (2 or 4 GB RAM) | 🛒friendlyarm.com | ||
1 | Heat Sink for NanoPi M4 | 🛒friendlyarm.com | ||
1 | 16GB eMMC 5.1 Module for NanoPi M4 | 🛒friendlyarm.com | ||
1 | 4x SATA HAT for NanoPi M4 | 🛒friendlyarm.com | ||
1 | 12V 5A Power Supply | 🛒amazon.de | ||
1 | 80mm Fan | 🛒amazon.de |
Depending on what you do, the 2GB version is sufficient for you. You will need a micro SD card (>= 8GB
) to install your OS. The 16GB eMMC is optional. I chose to use the eMMC because it is faster than (my) micro SD cards, and it frees the micro SD card slot (so I can quickly backup my phone).
The 12V power supply is what I had lying around, and it works. You can use something different here, for example an ATX PSU. Check with the wiki: http://wiki.friendlyarm.com/wiki/index.php/NanoPi_M4_SATA_HAT. Do some calculations as to how much power you will need.
The highest power consumption I could manage with two 2.5” HDDs, Streaming 3 HD Videos via WiFi, and sound via Bluetooth was 20W. You results will vary, especially when starting up 4 HDDs. The idle power consumption with this configuration was 6W (disks spinning).
You can check the wiki for more details about this board: http://wiki.friendlyarm.com/wiki/index.php/NanoPi_M4.
Related Work
The are other approaches to building a NanoPI M4 NAS. For example https://www.thingiverse.com/thing:3484008. Allthough, this version is a lot sturdier than mine (aluminium profiles!), it requires more parts, and aims for bigger (3.5” disks). As I wanted to keep it smaller (in size, not budget), and learn something, I designed my own.
The 3D Print
Download
💾 Download the V2 .STL (2.5” HDD, tested): /assets/prints/nanopim4-server-v2-stl.zip
💾 Download the V2.1 .STL (3.5” HDD, untested): /assets/prints/nanopim4-server-v2.2-3.5-stl.zip
Important (PLA vs Temperature)
⚠️The entire case can be printed with PLA, if and only if you add the 80mm fan and keep it constantly running. If you run this Pi with high loads the temperature of the core will go beyond 80C and the heat sink will go beyond 65C, without the top part of the case. Running it on max load without active cooling, in the closed case will soften the PLA over time. You can try this if you want, and please let me know what your results are, but I don’t recommend it 😉. Afaik, the CPU will throttle if it runs too hot. If you want your components to last, especially the HDDs, add active cooling ❄️.
While idling the cpu temperature remains at 35C, with active cooling inside the case (at 25C ambient temperature).
STL files
The following STL files are in the download zips:
My print settings
Make sure the front and back faces point down. The front and back faces are the faces with flat holes (to avoid support).
The Setup
The OS
I installed Armbian Buster from here: https://www.armbian.com/nanopi-m4/. You will find instructions on how to install it on their page.
The SATA hat was supported out of the box.
The FAN
Wiring
The fan (from the parts list) comes with black cables of which the first on has grey/white stripes. This (first) cable is GND. The middle cable is 12V, the third I left unused. As I didn’t have the right connector I had to wirewrap the cables onto the pins:
Controlling
The socket is connected to a MOSFET which is controlled by GPIO150
. This means when you start the server the fan is default OFF.
To enable the fan you need to run the following as root:
echo 150 > /sys/class/gpio/export
# this will create /sys/class/gpio/gpio150
echo out > /sys/class/gpio/gpio150/direction
echo 1 > /sys/class/gpio/gpio150/value
If you want to control the other GPIOs with WiringPi you need to install a patched version of WiringPi, see http://wiki.friendlyarm.com/wiki/index.php/NanoPi_M4#WiringPi_and_Python_Wrapper.
Starting the fan at boot
Login as root
and create the file /root/bin/initFan.sh
with the content:
#!/bin/bash
echo 150 > /sys/class/gpio/export && echo out > /sys/class/gpio/gpio150/direction && echo 1 > /sys/class/gpio/gpio150/value
Make it executable:
chmod +x /root/bin/initFan.sh
Run crontab -e
and add the line
@reboot /root/bin/initFan.sh
Reboot your system and check with cat /sys/class/gpio/gpio150/value
if the value 1
is returned.
Adding a Remote Widget
The sources are in this repository: https://github.com/pauls-3d-things/mini-stats
An introduction to the Arduino/esp8266 hardware is in my previous post;
Setting up a mirrored RAID (level 1)
The following instructions are for advanced users only, (i.e. if you are unsure what /dev/sdc
is I advise you to get more familiar with your system, fdisk
and linux in general). If your system contains no running disks or data a.k.a. “Grüne Wiese”, feel free to try things out. ;).
Prepare Partitions
In my case the devices where /dev/sdc
and /dev/sdd
. The installation on the eMMC chip is on the device /dev/mmcblk1p1
.
Both disks are the same, and will be formatted the same:
fdisk /dev/sdc
fdisk /dev/sdd
Create a new primary partition with default parameters (i.e. the entire disk):
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):
First sector (2048-500118191, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-500118191, default 500118191):
Created a new partition 1 of type 'Linux' and of size 238.5 GiB.
and set the type to fd
:
Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): fd
Changed type of partition 'Linux' to 'Linux raid autodetect'.
and write the changes to the disk:
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Do this with both identical disks.
Assemble RAID
Then assemble the raid (️⚠️make sure to adapt this to the correct disks first (the /dev/sd[c-d]1
part)!):
mdadm --create /dev/md0 --level=mirror --raid-devices=2 /dev/sd[c-d]1
mdadm: array /dev/md0 started.
As a result your raid will be available as /dev/md0
.
Format it with
mkfs.ext4 /dev/md0
Run blkid
to find the RAIDs UUID:
/dev/md0: UUID=”db42bd5c-291d-4c2b-a3b7-34a185918d57” TYPE=”ext4”
And add it to /etc/fstab
:
# <file system> <mount point> <type> <options> <dump> <pass>
# [ other lines removed by author]
UUID=db42bd5c-291d-4c2b-a3b7-34a185918d57 /mnt/SSD ext4 defaults,nofail 0 3
Make sure to use a sensible value for <pass>
for your system.
Mount your drive either by rebooting or
mount /mnt/SSD
Performance Tests (or Playing around with 2 SSDs and mdadm)
I’m only going to look at bulk write speeds, as everything below that will only be the disk as a bottle neck. If I’m wrong, please let me know :).
I got the following results using two SSD SanDisk SDSSDP256G (2013 era):
Configuration | Write Speed up to |
---|---|
raid 1 | 220 MB/s |
raid 1 (single disk) | 300 MB/s |
raid 0 | 400 MB/s |
The SATA hat shows promising speeds, especially if you consider the size of the setup. With a Marvell 88SE9215 chip which is connected via PCI-E 2.0 (https://www.marvell.com/storage/system-solutions/assets/Marvell-88SE92xx-002-product-brief.pdf), we get max theoretical speeds of up to 500MB/s (https://en.wikipedia.org/wiki/PCI_Express#PCI_Express_2.0).
For the size and cost of the setup, I am more than happy with these results
mdadm raid level=1 (mirror)
The bulk write speed on the NanoPi M4 to a mirrored raid of SSDs (2x SanDisk SDSSDP256G, mirrored) is
root@nasty:/mnt/SSD# dd if=/dev/zero of=./2GB-of-zero bs=1M count=2048
2048+0 records in 2048+0 records out 2147483648 bytes (2.1 GB, 2.0 GiB) copied, 9.74968 s, 220 MB/s
mdadm raid level=1 (single disk)
If we remove a disk
root@nasty:/mnt# mdadm /dev/md0 --fail /dev/sdd1
mdadm: set /dev/sdd1 faulty in /dev/md0
root@nasty:/mnt# mdadm /dev/md0 --remove /dev/sdd1
mdadm: hot removed /dev/sdd1 from /dev/md0
and write data to an an umirrored SSD we get:
root@nasty:/mnt/SSD# dd if=/dev/zero of=./8GB-of-zero bs=100M count=80
80+0 records in 80+0 records out 8388608000 bytes (8.4 GB, 7.8 GiB) copied, 27.3931 s, 306 MB/s
Let’s check if the measured write speeds get better with larger files (in my theory this represents a better average of writespeed, again only for bulk):
root@nasty:/mnt/SSD# dd if=/dev/zero of=./20GB-of-zero bs=100M count=200
200+0 records in 200+0 records out 20971520000 bytes (21 GB, 20 GiB) copied, 71.0981 s, 295 MB/s
Not a significant difference, but close to the advertised speed of
Lightning read and write performance of up to 490mb/s read speeds and 350mb/s write speeds.
So, the drive seems to be a bit of a limiting factor here.
mdadm raid level=0 (stripe)
Let’s try it with a RAID0 configuration.
First stop the raid:
mdadm --stop /dev/md0
Recreate the disks, see above. Some more details how to destroy your raid config: https://forum.ivorde.com/mdadm-how-can-i-destroy-or-delete-an-array-t85.html
Recreating the disks with fdisk
and rebooting already worked for me.
Create a RAID0:
mdadm --create /dev/md0 --level=stripe --raid-devices=2 /dev/sd[c-d]1
And repeat the test of writing 20GB of zeros:
root@nasty:/mnt/SSD# dd if=/dev/zero of=./20GB-of-zero bs=100M count=200
200+0 records in 200+0 records out 20971520000 bytes (21 GB, 20 GiB) copied, 52.7125 s, 398 MB/s
This looks like twice the speed obtained vs the mirrored raid configuration.
Writing via smbd (windows shares)
When writing files via network shares via smbd (nano pi m4) and smb client (linux intel machine) via the 1Gbit/s LAN interface I got write speeds of around 80 MB/s.