{"id":255,"date":"2025-05-08T22:58:51","date_gmt":"2025-05-08T20:58:51","guid":{"rendered":"https:\/\/jorisvanhoutven.be\/?p=255"},"modified":"2025-05-08T22:59:13","modified_gmt":"2025-05-08T20:59:13","slug":"guide-host-your-own-private-file-sync-backup-and-note-taking-server-on-a-raspberry-pi","status":"publish","type":"post","link":"https:\/\/jorisvanhoutven.be\/?p=255","title":{"rendered":"Guide: host your own private file sync + backup and note-taking server on a Raspberry Pi"},"content":{"rendered":"\n<p>READ THIS ARTICLE HERE FOR BETTER FORMATTING: <a href=\"https:\/\/pdiracdelta-trilium.ddns.net\/share\/dKJgpg3Ws8x4\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/pdiracdelta-trilium.ddns.net\/share\/dKJgpg3Ws8x4<\/a> <\/p>\n\n\n\n<h2>Introduction<\/h2>\n\n\n\n<h3>What is it and Why do it?<\/h3>\n\n\n\n<ul><li>It&#8217;s a little bit like <strong>your own private cloud server*<\/strong>.&nbsp;<\/li><li>You get to use these <strong>awesome services<\/strong>:<ul><li><strong>Seafile<\/strong> is your <strong>personal file storage and synchronization<\/strong> app, which has multi-client support, a mobile app, and still lets you securely share files (and even collaborate on them) with others.<\/li><li><strong>Trilium<\/strong> is an <em>awesome<\/em> <strong>note-taking and knowledge base app<\/strong> on steroids. I&#8217;ve been a sponsor of the project for a while, check out its features here: <a href=\"https:\/\/www.youtube.com\/watch?v=uIvdzzxjdY8&amp;t=51s\">https:\/\/www.youtube.com\/watch?v=uIvdzzxjdY8&amp;t=51s<\/a> .<\/li><li><strong>Pi-hole<\/strong> can <strong>block ads<\/strong> (for <em>all<\/em> your LAN devices!) and provide <strong>local DNS<\/strong>.<\/li><\/ul><\/li><li>It <strong>can be cheaper<\/strong> than \u2018real\u2019 &nbsp;cloud storage.&nbsp;<\/li><li>You are <strong>in control of your own data<\/strong> and syncing or backing up <strong>large data volumes<\/strong> (on the LAN) <strong>do not consume data on your internet contract<\/strong>.<\/li><\/ul>\n\n\n\n<p>(*) see FAQ#1<\/p>\n\n\n\n<h3>Prerequisites<\/h3>\n\n\n\n<h4>Hardware &amp; static&nbsp;IP:<\/h4>\n\n\n\n<ol><li>\u20ac65 <a href=\"https:\/\/www.raspberrypi.com\/products\/raspberry-pi-4-model-b\/?variant=raspberry-pi-4-model-b-4gb\"><strong>Raspberry Pi<\/strong> 4B<\/a> with 4GB RAM, or better<\/li><li><strong>Storage<\/strong>: get all of the following (do NOT just use a big internal microSD card, see FAQ#3):<br>&#8211; \u20ac9 <a href=\"https:\/\/www.bol.com\/be\/nl\/p\/sandisk-microsdhc-ultra-32gb-120mb-s-c10-uhsi-a1-photo\/9300000014569116\/\">internal SD card<\/a> for the OS and software with 16GB storage or more;<br>&#8211; \u20ac25 HDD <a href=\"https:\/\/www.amazon.nl\/-\/en\/IB-1122-U3-Drive-Docking-Station-Black\/dp\/B085LTKD2S\">docking station<\/a><br>&#8211; \u20ac92 <a href=\"https:\/\/www.amazon.com\/2PR7551-WD10EFRX-3-5quot-Internal-Drive\/dp\/B00F7R07UE\">HDD<\/a> like WD RED since they are made especially for NAS usage;<\/li><li><strong>Static public IP<\/strong>: unless you already have a public IP, set up Dynamic DNS on your router and connect it to a domain name using a free DynDNS service, e.g. <a href=\"https:\/\/www.noip.com\/remote-access\">https:\/\/www.noip.com\/remote-access<\/a>.<br>Make sure you have 3 domain records registered (1 for each service, but 2 are CNAME records)<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>mysite.ddns.net A record \nmysite-trilium.ddns.net CNAME record (point to mysite.ddns.net) \nmysite-seafile.ddns.net CNAME record (point to mysite.ddns.net)<\/code><\/pre>\n\n\n\n<h4>Set up your hardware and&nbsp;routing:<\/h4>\n\n\n\n<ol><li>Connect HDD to RPI via Docking station and hook up your RPI to your LAN router via ethernet (or wifi), then set a static IP (192.168.1.1 is typical router address)<\/li><li>Configure router:&nbsp;<ol><li>set up static IP for RPI: <code>192.168.1.XX<\/code><\/li><li>set up port forwarding to this IP for ports:<ol><li><code>22<\/code> SSH<\/li><li><code>80<\/code> certbot and reverse proxy (for all the other software in the docker containers)<\/li><li><code>81<\/code> nginx proxy manager<\/li><li><code>443<\/code> SSL<\/li><li>(and optionally more e.g. if you want to access pihole DNS from outside the LAN)<\/li><\/ol><\/li><\/ol><\/li><\/ol>\n\n\n\n<h2>Server Setup<\/h2>\n\n\n\n<p>Parameters: if you replace my default values in the guide you should be able to copy paste most lines of code<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Description<\/th><th>Value<\/th><\/tr><\/thead><tbody><tr><td>HDD Mount point<\/td><td>\/media\/hdd\/<\/td><\/tr><tr><td>domain name A DNS record<\/td><td>mysite.ddns.net<\/td><\/tr><tr><td>seafile C DNS record<\/td><td>mysite-seafile.ddns.net<\/td><\/tr><tr><td>trilium C DNS record<\/td><td>mysite-trilium.ddns.net<\/td><\/tr><tr><td>email address for smartmontools notifications, seafile admin, certbot contact<\/td><td>me@example.com<\/td><\/tr><tr><td>local IP of your raspberry pi<\/td><td>192.168.1.XX<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3>Raspberry Pi OS<\/h3>\n\n\n\n<p>Official Instructions: <a href=\"https:\/\/www.raspberrypi.com\/documentation\/computers\/getting-started.html#installing-the-operating-system\">https:\/\/www.raspberrypi.com\/documentation\/computers\/getting-started.html#installing-the-operating-system<\/a>&nbsp;<\/p>\n\n\n\n<ol><li>Install Raspbian OS<ol><li>Plug in the micro SD card into your computer (using an adapter if not natively supported)<\/li><li><code>sudo apt install rpi-imager<\/code><\/li><li>Launch the imager and choose the appropriate OS (Raspberry Pi OS 64-bit for RPI4B) and select the SD card to install on<\/li><li>When asked to customize settings, click Edit Settings and make sure remote access (SSH) is enabled, your LAN network credentials are put in, you&#8217;ve chosen a password, etc.<\/li><\/ol><\/li><li>Boot your RPI, and SSH into it with your chosen password.<\/li><li>Install vim or nano or whatever CLI text editor you prefer: <code>sudo apt-get install vim<\/code><\/li><li>Execute the following to add lines to <code>\/etc\/fstab<\/code> so your HDD will mount properly when your RPI reboots:<ol><li>Make a fixed mounting directory (if you change it: know that I use it throughout the guide): <code>sudo mkdir \/media\/hdd<\/code><\/li><li>figure out the UUID of your device with <code>sudo blkid<\/code> and insert it into the second line below:<br><code>echo \"# external HDD\" | sudo tee -a \/etc\/fstab <br>echo \"UUID=\"INSERT_UUID_HERE\" \/media\/hdd ext4 defaults 0 0\" | sudo tee -a \/etc\/fstab<\/code><\/li><\/ol><\/li><li>set up firewall and fail2ban<ol><li><code>sudo apt-get install ufw<\/code><\/li><li><code>sudo apt-get install fail2ban<\/code><\/li><\/ol><\/li><li>install docker: follow OS-specific instructions on <a href=\"https:\/\/docs.docker.com\/engine\/install\/\">https:\/\/docs.docker.com\/engine\/install\/<\/a>&nbsp;<br>for RPI, this is:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code># Remove old packages if existing\nfor pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done\n\n# Add Docker's official GPG key:\nsudo apt-get update\nsudo apt-get install ca-certificates curl\nsudo install -m 0755 -d \/etc\/apt\/keyrings\nsudo curl -fsSL https:\/\/download.docker.com\/linux\/debian\/gpg -o \/etc\/apt\/keyrings\/docker.asc\nsudo chmod a+r \/etc\/apt\/keyrings\/docker.asc\n\n# Add the repository to Apt sources:\necho \\\n  \"deb &#91;arch=$(dpkg --print-architecture) signed-by=\/etc\/apt\/keyrings\/docker.asc] https:\/\/download.docker.com\/linux\/debian \\\n  $(. \/etc\/os-release &amp;&amp; echo \"$VERSION_CODENAME\") stable\" | \\\n  sudo tee \/etc\/apt\/sources.list.d\/docker.list &gt; \/dev\/null\nsudo apt-get update\n\n# Install Docker latest version\nsudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin<\/code><\/pre>\n\n\n\n<h3>reverse proxy<\/h3>\n\n\n\n<p>One big advantage of using a reverse proxy is that all your traffic is routed through a single point taking care of SSL termination, so you can use a single SSL certificate for all your services. We&#8217;ll use Nginx Proxy Manager (NPM) and request a Letsencrypt certificate using Certbot.<\/p>\n\n\n\n<h4>Certbot<\/h4>\n\n\n\n<p>Official Instructions: <a href=\"https:\/\/certbot.eff.org\/instructions?ws=nginx&amp;os=snap\">https:\/\/certbot.eff.org\/instructions?ws=nginx&amp;os=snap<\/a>&nbsp;<\/p>\n\n\n\n<ol><li>install snap:&nbsp;<br><code>sudo apt install snapd <\/code><br><code>sudo reboot <\/code><br><code>sudo snap install core<\/code><\/li><li>install certbot as a snap:<ol><li>remove pre existing: <code>sudo apt-get remove certbot<\/code><\/li><li><code>sudo snap install --classic certbot<\/code><\/li><li><code>sudo ln -s \/snap\/bin\/certbot \/usr\/bin\/certbot<\/code><\/li><\/ol><\/li><li>(optional) turn off any web server listening on port 80<br><code>sudo docker stop nginxpm<\/code><\/li><li>get a cert in standalone mode (spins up its own webserver) <a href=\"https:\/\/certbot.eff.org\/instructions?ws=nginx&amp;os=snap\">https:\/\/certbot.eff.org\/instructions?ws=nginx&amp;os=snap<\/a>&nbsp;. You can specify multiple domains with <code>-d<\/code> option and also place the certs on the HDD with <code>--config-dir<\/code>:<br><code>sudo certbot certonly --standalone -d mysite.ddns.net -d mysite-seafile.ddns.net -d mysite-trilium.ddns.net --config-dir \/media\/hdd\/certbot<\/code><\/li><li>make sure for certbot to use the working dir to renew:<ol><li><em>either<\/em> with cron: (make sure you adjust the day-of-month and month fields according to your situation! Letsencrypt certificates have to be renewed every 3 months): <code>sudo vim \/etc\/crontab<\/code> add the following lines (after modifying):<br><code># renew SSL cert <\/code><br><code>0 0 1 1,4,7,10 * root \/usr\/bin\/certbot renew --config-dir \/media\/hdd\/certbot<\/code><\/li><\/ol><ol><li><em>or<\/em> by telling certbot it should look into the \/media\/hdd\/certbot directory when renewing (I&#8217;m confused by the manual and don&#8217;t know how to do it exactly &#8211; let me know if you do.<br><a href=\"https:\/\/eff-certbot.readthedocs.io\/en\/stable\/using.html#automated-renewals\">https:\/\/eff-certbot.readthedocs.io\/en\/stable\/using.html#automated-renewals<\/a>&nbsp;<br><a href=\"https:\/\/eff-certbot.readthedocs.io\/en\/stable\/using.html#configuration-file\">https:\/\/eff-certbot.readthedocs.io\/en\/stable\/using.html#configuration-file<\/a>&nbsp;<\/li><\/ol><\/li><li>do a manual test with:<br><code>sudo certbot renew --config-dir \/media\/hdd\/certbot --dry-run<\/code>&nbsp;<\/li><li>(optional) turn on web server again<code>sudo docker start nginxpm<\/code><\/li><\/ol>\n\n\n\n<h4>NPM (nginx reverse proxy manager)<\/h4>\n\n\n\n<p>Official Instructions: <a href=\"https:\/\/nginxproxymanager.com\/guide\/\">https:\/\/nginxproxymanager.com\/guide\/<\/a>&nbsp;<\/p>\n\n\n\n<ol><li>enable ports<ol><li><code>sudo ufw allow 80<\/code><\/li><li><code>sudo ufw allow 81<\/code><\/li><li><code>sudo ufw allow 443<\/code><\/li><\/ol><\/li><li>create proxiable docker network (all your services need to connect to this network! otherwise NPM cannot connect to them using container names):&nbsp;<br><code>sudo docker network create --driver bridge proxiable<\/code><\/li><li><code>sudo mkdir \/media\/hdd\/nginxpm<\/code><\/li><li>create a yaml: <\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>services:\n  app:\n    image: 'jc21\/nginx-proxy-manager:latest'\n    restart: unless-stopped\n    container_name: nginxpm\n    ports:\n      # These ports are in format &lt;host-port&gt;:&lt;container-port&gt;\n      - '80:80' # Public HTTP Port\n      - '443:443' # Public HTTPS Port\n      - '81:81' # Admin Web Port\n      # Add any other Stream port you want to expose\n      # - '21:21' # FTP\n\n    #environment:\n      # Uncomment this if you want to change the location of\n      # the SQLite DB file within the container\n      # DB_SQLITE_FILE: \"\/data\/database.sqlite\"\n\n      # Uncomment this if IPv6 is not enabled on your host\n      # DISABLE_IPV6: 'true'\n\n    volumes:\n      - .\/data:\/data\n      - .\/letsencrypt:\/etc\/letsencrypt\n    networks:\n      - proxiable\nnetworks:\n  proxiable:\n    name: proxiable\n    external: true<\/code><\/pre>\n\n\n\n<ol start=\"5\"><li>install NPM<ol><li><code>sudo docker compose up -d<\/code><\/li><\/ol><\/li><li>login with credentials: <code>admin@example.com:changeme<\/code> and change your password!<\/li><li>add SSL certificate to NPM (upload)<\/li><li>configure proxies (and add SSL to each!):<ol><li>mysite.ddns.net<br>\u2192 http pi-hole:80<\/li><li>mysite-trilium.ddns.net<br>\u2192 http trilium:80<\/li><li>mysite-seafile.ddns.net<br>\u2192 http seafile-caddy:80<\/li><\/ol><\/li><li>optional: create dummy docker for debugging (but then use a different port than pi-hole?<\/li><\/ol>\n\n\n\n<h3>Pi-hole<\/h3>\n\n\n\n<p>Official Instructions: <a href=\"https:\/\/github.com\/pi-hole\/docker-pi-hole\">https:\/\/github.com\/pi-hole\/docker-pi-hole<\/a>&nbsp;<\/p>\n\n\n\n<ol><li>enable port for DNS<ol><li><code>sudo ufw allow 53<\/code><\/li><\/ol><\/li><li>create a yaml file for pi-hole (make sure to change the <code>WEBPASSWORD<\/code>):<br><code>sudo mkdir \/media\/hdd\/pihole <\/code><br><code>sudo vim \/media\/hdd\/pihole\/docker-compose.yaml<\/code><\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code># More info at https:\/\/github.com\/pi-hole\/docker-pi-hole\/ and https:\/\/docs.pi-hole.net\/\nservices:\n  pihole:\n    container_name: pihole\n    image: pihole\/pihole:latest\n    # For DHCP it is recommended to remove these ports and instead add: network_mode: \"host\"\n    ports:\n      - \"53:53\/tcp\"\n      - \"53:53\/udp\"\n      - \"67:67\/udp\" # Only required if you are using Pi-hole as your DHCP server\n      - \"80:80\/tcp\"\n    environment:\n      TZ: 'CET'\n      WEBPASSWORD: 'set a secure password here or it will be random'\n    # Volumes store your data between container upgrades\n    volumes:\n      - '.\/etc-pihole:\/etc\/pihole'\n      - '.\/etc-dnsmasq.d:\/etc\/dnsmasq.d'\n    #   https:\/\/github.com\/pi-hole\/docker-pi-hole#note-on-capabilities\n    cap_add:\n      - NET_ADMIN # Required if you are using Pi-hole as your DHCP server, else not needed\n    restart: unless-stopped\n    networks:\n      - proxiable\nnetworks:\n  proxiable:\n    name: proxiable\n    external: true<\/code><\/pre>\n\n\n\n<ol start=\"3\"><li>configure to use DNS server on clent devices:<br>(I&#8217;m using Cloudflare as fallback)<ol><li>Linux: <a href=\"https:\/\/www.veeble.com\/kb\/how-to-change-dns-server-permanently-on-ubuntu-20-04\/\">https:\/\/www.veeble.com\/kb\/how-to-change-dns-server-permanently-on-ubuntu-20-04\/<\/a>&nbsp;<ol><li><code>sudo vim \/etc\/systemd\/resolved.conf<\/code><\/li><li>add\/uncomment the following line:<br><code>DNS=192.168.1.XX 1.1.1.1<\/code><\/li><\/ol><\/li><li>Windows: <a href=\"https:\/\/www.windowscentral.com\/how-change-your-pcs-dns-settings-windows-10\">https:\/\/www.windowscentral.com\/how-change-your-pcs-dns-settings-windows-10<\/a>&nbsp;<ol><li>go to internet options, adapter properties, IPv4 properties<\/li><li>add <code>192.168.1.XX<\/code> with <code>1.1.1.1<\/code> as fallback<\/li><\/ol><\/li><\/ol><\/li><li>go to the <code>mysite.ddns.net\/admin<\/code> interface, click on Adlists in the left menu and add the following space-separated list:<br><code>https:\/\/raw.githubusercontent.com\/StevenBlack\/hosts\/master\/hosts https:\/\/raw.githubusercontent.com\/PolishFiltersTeam\/KADhosts\/master\/KADhosts.txt https:\/\/raw.githubusercontent.com\/FadeMind\/hosts.extras\/master\/add.Spam\/hosts https:\/\/v.firebog.net\/hosts\/static\/w3kbl.txt https:\/\/adaway.org\/hosts.txt https:\/\/v.firebog.net\/hosts\/AdguardDNS.txt https:\/\/v.firebog.net\/hosts\/Admiral.txt https:\/\/v.firebog.net\/hosts\/Easyprivacy.txt https:\/\/v.firebog.net\/hosts\/Prigent-Ads.txt https:\/\/raw.githubusercontent.com\/anudeepND\/blacklist\/master\/adservers.txt<\/code><\/li><\/ol>\n\n\n\n<h3>Trilium<\/h3>\n\n\n\n<p>Official Instructions: <a href=\"https:\/\/triliumnext.github.io\/Docs\/Wiki\/docker-server-installation.html\">https:\/\/triliumnext.github.io\/Docs\/Wiki\/docker-server-installation.html<\/a>&nbsp;<\/p>\n\n\n\n<ol><li>go to <code>\/media\/hdd\/trilium<\/code> to download docker yaml <a href=\"https:\/\/github.com\/TriliumNext\/Notes\/blob\/develop\/docker-compose.yml\">https:\/\/github.com\/TriliumNext\/Notes\/blob\/develop\/docker-compose.yml<\/a>&nbsp;<\/li><li>in <code>docker-compose.yaml<\/code>, comment out the <code>ports<\/code> section (this is taken care of by NPM)<\/li><li>on client, set sync server to <code>https:\/\/mysite-trilium.ddns.net<\/code><br>be careful to use https and to <em>not<\/em> specify the port<\/li><\/ol>\n\n\n\n<h3>Seafile<\/h3>\n\n\n\n<p>Official Instructions: <a href=\"https:\/\/manual.seafile.com\/12.0\/setup\/setup_ce_by_docker\/#download-and-modify-env\">https:\/\/manual.seafile.com\/12.0\/setup\/setup_ce_by_docker\/#download-and-modify-env<\/a>&nbsp;<\/p>\n\n\n\n<ol><li>go to <code>\/media\/hdd\/seafile<\/code> and download docker yaml and others:<br><code>wget -O .env https:\/\/manual.seafile.com\/12.0\/docker\/ce\/env<\/code><br><code>wget https:\/\/manual.seafile.com\/12.0\/docker\/ce\/seafile-server.yml<\/code><br><code>wget https:\/\/manual.seafile.com\/12.0\/docker\/caddy.yml<\/code><\/li><li>Modify <code>sudo vim .env<\/code> to&nbsp;<ol><li>change the volumes to <code>\/media\/hdd\/seafile\/&lt;volume&gt;<\/code> instead of <code>\/opt\/&lt;volume&gt;<\/code><ol><li><code>SEAFILE_VOLUME<\/code><\/li><li><code>SEAFILE_MYSQL_VOLUME<\/code><\/li><li><code>SEAFILE_CADDY_VOLUME<\/code><\/li><li><code><s>SEADOC_VOLUME<\/s><\/code> optional<\/li><li><code>NOTIFICATION_SERVER_VOLUME<\/code><\/li><\/ol><\/li><li>change <code>INIT_SEAFILE_MYSQL_ROOT_PASSWORD<\/code> and <code>SEAFILE_MYSQL_DB_PASSWORD<\/code> to \u2026<\/li><li>set <code>JWT_PRIVATE_KEY<\/code> with a unique string &gt;32 chars<\/li><li>set <code>SEAFILE_SERVER_HOSTNAME=mysite-seafile.ddns.net<\/code><\/li><li>make note that <code>SEAFILE_SERVER_PROTOCOL=http<\/code> because this concerns the traffic between docker containers<\/li><li>set <code>INIT_SEAFILE_ADMIN_EMAIL=me@example.com<\/code> and also set the <code>INIT_SEAFILE_ADMIN_PASSWORD<\/code><\/li><li>set <code>TIME_ZONE=CET<\/code><\/li><\/ol><\/li><li>add proxiable network<ol><li>to <code>seafile-server.yml<\/code> and <code>caddy.yml<\/code>:<code> <\/code><\/li><\/ol><\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>  networks:\n    - seafile-net\n  \t- proxiable\n...\nnetworks:\n  seafile-net:\n    name: seafile-net\n  proxiable:\n    name: proxiable\n    external: true<\/code><\/pre>\n\n\n\n<ol start=\"3\"><li><ol><li><\/li><li>in <code>caddy.yml<\/code>, comment out the <code>ports<\/code> section (this is taken care of by NPM)<\/li><li>in <code>seafile-server.yml<\/code>, change the seafile version <code>12.0-latest<\/code> to <code>12.0.7-arm<\/code>.<\/li><\/ol><\/li><li><code>docker compose up -d<\/code><\/li><li>on each seafile client, add your account (with email and password) on server <a href=\"https:\/\/pdiracdelta-seafile.ddns.net\"><code>https:\/\/mysite-seafile.ddns.net<\/code><\/a>Tip: use a seafile-ignore.txt file on the root directory of each library to avoid syncing certain folders or files. <a href=\"https:\/\/help.seafile.com\/syncing_client\/excluding_files\/\">https:\/\/help.seafile.com\/syncing_client\/excluding_files\/<\/a>&nbsp;<\/li><\/ol>\n\n\n\n<p>Almost done! Now just set up a monitoring system to detect when you need to replace your HDD\u2026<\/p>\n\n\n\n<h3>Hardware monitoring<\/h3>\n\n\n\n<p>Basically, we&#8217;re going to use <code>smartmontools<\/code> and let it send via gmail smtp (if you don&#8217;t have gmail\u2026 make a free account).<\/p>\n\n\n\n<p>Sources: <a href=\"https:\/\/www.cyberciti.biz\/tips\/monitoring-hard-disk-health-with-smartd-under-linux-or-unix-operating-systems.html\">https:\/\/www.cyberciti.biz\/tips\/monitoring-hard-disk-health-with-smartd-under-linux-or-unix-operating-systems.html<\/a> &nbsp;and <a href=\"https:\/\/gist.github.com\/maleadt\/02a58eb46118c1d8014c\">https:\/\/gist.github.com\/maleadt\/02a58eb46118c1d8014c<\/a> and <a href=\"https:\/\/linuxconfig.org\/how-to-configure-smartd-and-be-notified-of-hard-disk-problems-via-email\">https:\/\/linuxconfig.org\/how-to-configure-smartd-and-be-notified-of-hard-disk-problems-via-email<\/a> and <a href=\"https:\/\/forums.raspberrypi.com\/viewtopic.php?t=50939\">https:\/\/forums.raspberrypi.com\/viewtopic.php?t=50939<\/a>&nbsp;<\/p>\n\n\n\n<ol><li><code>sudo apt-get install smartmontools mailutils msmpt msmtp-mta<\/code>&nbsp;<\/li><li>Create msmtp config<ol><li><code>sudo touch \/etc\/msmtprc # create global config<\/code><br><code>sudo chmod 660 \/etc\/msmtprc # make it accessible. the guide says 664, but this would be a security breach<\/code><\/li><li>Create an app-specific password for your gmail <a href=\"https:\/\/myaccount.google.com\/apppasswords\">https:\/\/myaccount.google.com\/apppasswords<\/a>&nbsp;<br>and use it in the next step<\/li><li>In <code>sudo vim \/etc\/msmtprc<\/code> paste (and insert <code>APP_PASSWORD_WITHOUT_SPACES<\/code>)<code>d<\/code><\/li><\/ol><\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>defaults\nauth on\ntls  on\ntls_trust_file \/etc\/ssl\/certs\/ca-certificates.crt\nlogfile \/var\/log\/msmtp.log\n\n# Gmail configuration\naccount gmail\nhost    smtp.gmail.com\nport    587\nfrom    me@example.com\nuser    me@example.com\npassword APP_PASSWORD_WITHOUT_SPACES \n\naccount default: gmail<\/code><\/pre>\n\n\n\n<ol start=\"3\"><li>Enable logging:<br><code>sudo touch \/var\/log\/msmtp.log<\/code><br><code>sudo chmod 666 \/var\/log\/msmtp.log # there seems to be an issue with msmtp and it won't log unless all users have access. This is relatively harmless.<\/code><\/li><li>Check if SMART support is available<br><code>sudo smartctl -i \/dev\/sda<\/code> (or whatever your device identifier is)<\/li><li>Open <code>sudo vim \/etc\/default\/smartmontools<\/code> and modify\/uncomment the following line:<br><code>enable_smart=\"\/dev\/sda\"<\/code><\/li><li>In <code>sudo vim \/etc\/smartd.conf<\/code> comment out the line with <code>DEVICESCAN<\/code> and add the following lines:<br>(remove the last line after successful test. run <code>sudo systemctl restart smartd<\/code> to re-run the test)<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code># MY SETTINGS\n# check some stuff and track everything (-a), with a Short (-s S) and Long (-s L) test every week and month, respectively.\n# ignore temperature (194 and 231) and power-on hours (9) attributes (-I)\n# email (-m) once (-M) if warnings\n\/dev\/sda -a -I 194 -I 9 -I 231 -m me@example.com -M once -s (S\/..\/..\/6\/00)|(L\/..\/01\/.\/01) # every saturday midnight | every 1st day of the month 1AM\n\/dev\/sda -a -M test -m me@example.com  # remove this line after successful test<\/code><\/pre>\n\n\n\n<ol start=\"3\"><li><code>sudo systemctl reload smartd<\/code> to reload the config (which also executes the test line)<\/li><\/ol>\n\n\n\n<p>Congrats! You&#8217;re done! Enjoy your secure self-hosted setup \ud83d\ude00<\/p>\n\n\n\n<h2>FAQ<\/h2>\n\n\n\n<ol><li><strong>Personal cloud server means my data is backed up, right?<\/strong><br><strong>Yes and no<\/strong>: the data storage is intended to be used as a backup for other devices. In this guide, there is no back-up mechanism for the data on the RPI nor its storage medium. However, I use docker images stored on the harddrive so that when your SSD suddenly fails (which is most likely), then you can simply replace it and you only have to repeat the Raspbian OS section, re-start all docker images, and you&#8217;re back online!<\/li><li><strong>What do you mean it <\/strong><em><strong>can<\/strong><\/em><strong> be cheaper than cloud storage?<\/strong><br>The <strong>payback period<\/strong> compared to cloud via Google\/Microsoft\/\u2026 <strong>varies greatly (1-10 years, but typically 3 years)<\/strong> depending on your needs , the hardware you already have, and whether you want Trilium and pi-hole or just simple storage.<ul><li>Google&#8217;s basic storage offer costs \u20ac20 per year and has file sync (Drive), but does not have a Trilium server nor pi-hole and only gives you 100GB. It does have other benefits (easy sync with Photo&#8217;s on smartphone) but if you want more storage it will cost you \u20ac90 yearly for 2TB.<\/li><li>My recommended 1TB setup costs &lt;\u20ac200, but if you have a spare harddrive or you are not too worried about data loss (because you sync your data across devices constantly so it is easy to recover via those) then you can do it for &lt; \u20ac100<\/li><\/ul><\/li><li><strong>Is this a secure setup? Does it use HTTPS?<\/strong><br><strong>Yes<\/strong>, everything is secure (HTTPS connections even from inside your LAN) and you only need to request\/manage a single SSL certificate. All traffic passes through nginx proxy manager (except maybe the DNS requests?) which relays the traffic via the docker network.<\/li><li><strong>Why use Nginx proxy manager (NPM)?<\/strong><br>Because then we can easily serve <strong>multiple services on the same host machine using only 1 SSL certificate<\/strong>. NPM is the SSL termination point and routes traffic via the docker network, which means <strong>no ports on the docker containers are exposed<\/strong> to attackers.<\/li><li><strong>I can still see ads when using pihole! Is it not working?<\/strong><br>Pi-hole can only block &#8216;regular&#8217; ads based on DNS-based domain name blocking, which means some special ads (like Youtube ads) cannot be blocked using pi-hole (DNS-based blocking just doesn&#8217;t work for these types of ads).<\/li><li><strong>What are the downsides of this setup?<\/strong><br>The \u201cdownside\u201d (read: \u201cthe fun part for hobbyists\u201d) is that <strong>you have to set up and maintain everything yourself<\/strong>, for instance if you move houses, or your HDD\/SSD has an issue, or \u2026 \ud83d\ude42<\/li><\/ol>\n","protected":false},"excerpt":{"rendered":"Seafile is your personal file storage and synchronization app, which has multi-client support, a mobile app, and still lets you securely share files (and even collaborate on them) with others.\nTrilium is an awesome note-taking and knowledge base app on steroids. I&#8217;ve been a sponsor of the project for a while, check out its features here: https:\/\/www.youtube.com\/watch?v=uIvdzzxjdY8&#038;t=51s .\nPi-hole can block ads (for all your LAN devices!) and provide local DNS.","protected":false},"author":1,"featured_media":256,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[12],"tags":[29,25,28,27,30,24,26,23],"_links":{"self":[{"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=\/wp\/v2\/posts\/255"}],"collection":[{"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=255"}],"version-history":[{"count":2,"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=\/wp\/v2\/posts\/255\/revisions"}],"predecessor-version":[{"id":258,"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=\/wp\/v2\/posts\/255\/revisions\/258"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=\/wp\/v2\/media\/256"}],"wp:attachment":[{"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jorisvanhoutven.be\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}