Complete Guide Rasp Pi 4 for NextCloud + Redis + MySQL + Ext NTFS + Nginx Proxy Manager

10 min read


Use below Guide for Raspberry Pi 4 and OS Ubuntu 20.04 (64 bit only). If you are using older hardware <= Raspberry Pi 3 use this guide instead Complete guide NextCloud + External HDD NTFS + Nginx Proxy Manager.

If you are looking for self-host-dropbox-like you are coming to the right place, I am using OS Ubuntu 20.04 LTS and one 6TB HDD ext which is not ideal, if you possible, use minimum 2 HDD and setup RAID 1 using mdam tools for data safety. With this setup you can stream video normally.

Step 1 – Install PiHole + DNSCrypt-Proxy + Samba (optional)

Why? I will tell you later, follow along this step, however the additional is to install SAMBA when you configure dockstarter

Step 2 – Install Nginx Proxy Manager

You can follow below this blog or watch this

Step 3 – Mount your HDD ext

Open your terminal and SSH/Mosh your Pi and find your mountable drive:

$ sudo fdisk -l


$ lsblk -fp

Mount your ext drive (in my case it’s located at /dev/sda1 and I am going to mount it to /mnt/hdd):

$ sudo mkdir /mnt/hdd
$ sudo mount /dev/sda1 /mnt/hdd

That’s it, now try to list the directory and confirm everything is nice and make nextcloud directory inside the hdd

$ ls /mnt/hdd
$ mkdir /mnt/hdd/nextcloud

and since nextcloud will be using user www-data for the directory (otherwise will not be able to configure nextcloud) let’s add user pi to group www-data

$ sudo usermod -a -G www-data pi

Confirm that user pi is under group 33(www-data)

$ id pi

Finally let’s make sure everytime Raspberry Pi reboot, you will not lose the mount or mount manually

#make backup for fstab first in case anything wrong you can revert back
$ sudo cp /etc/fstab /etc/fstab-bak

#find and copy the UUID of your external HDD
$ lsblk -fp

#edit fstab
$ sudo nano /etc/fstab

Copy below to the last line of fstab don’t forget to modify UUID to your UUID otherwise you will not be able to boot your Pi

UUID=TH1S1SY0URUD1DN0 /mnt/hdd ntfs-3g async,big_writes,noatime,nodiratime,nofail,uid=33,gid=33,permissions,umask=007 0 0

Next reboot your Pi, fingercross everthing is fine, after reboot try listing the directory, to confirm everything is tight.

sudo reboot

Step 4 – Install Nextcloud

Create below directory if not exists:


Go to that directory and create a file called docker-compose.yml inside that directory:

cd /home/ubuntu/.config/nextcloud/
nano docker-compose.yml

Insert below, don’t forget to change the password.

version: '3'

    image: yobasystems/alpine-mariadb:latest
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    restart: always
      - /home/ubuntu/.config/appdata/nextcloud/mysql:/var/lib/mysql
      - /etc/localtime:/etc/localtime:ro
      - db.env

    image: redis:alpine
    command: redis-server --requirepass [COMPLEX_REDIS_PASSWORD]
    restart: always
      - /home/ubuntu/.config/appdata/nextcloud/data:/data
      - /etc/localtime:/etc/localtime:ro

    image: nextcloud:latest
    restart: always
      - 8081:80
      - /mnt/hdd/nextcloud/html:/var/www/html
      - /home/ubuntu/.config/appdata/nextcloud/conf.d:/usr/local/etc/php/conf.d
      - /etc/localtime:/etc/localtime:ro
      - MYSQL_HOST=db
      - REDIS_HOST=redis
      - db.env
      - db
      - redis

    image: nextcloud:latest
    restart: always
      - /mnt/hdd/nextcloud/html:/var/www/html
    entrypoint: /
      - db
      - redis


and then create “db.env” file inside same directory:

cd /home/ubuntu/.config/nextcloud/
nano db.env

Once finished just run below command:

docker-compose up -d

Step 5 – Setup NextCloud

If everything setup correctly you should be able to go to http://raspberrypi:8081 from there you can configure the admin user & password, leave data folder as it is since we already link it in docker to the external hdd, for database:

  • Database user: nextcloud
  • Database password: #yourdbpassword#
  • Database name: nextcloud
  • Database host: db

That’s it your nextcloud is basically up and running!

Step 6 – Make NextCloud in the cloud with triple proxies!

Of course you need to have domain for this step. The proxy that we are going to use:

  • FRP to reverse proxy (recommended with Oracle Cloud or any VPS)
  • Nginx Proxy Manager for HTTPS and better cert management
  • Cloudflare to hide your original oracle cloud IP for better protection

First I need you to setup FRP just follow along my previous blog: How to Setup a Forever Free SSH access to Raspberry Pi without port forward

However for the FRPC or the client side copy and paste and add below text to your frpc config file:

type = http
local_ip =
local_port = 80
custom_domains =

type = https
local_ip =
local_port = 443
use_compression = false
custom_domains =

Don’t forget to restart your frpc service to apply the changes

$ sudo service frpc restart

You can change the subdomain from “cloud” to anything you like. Next on cloudflare you need to setup A record for that subdomain point to your Oracle Cloud / your VPS public IP address make sure Proxy status is DNS only for now.

next open nginx proxy manager in your browser: http://raspberrypi.local:81 go to HostsProxy Hosts – Add Proxy Host

On details tab fill in:

  • Domain Names: your sub domain
  • Forward Hostname / IP: your raspberry pi IP address
  • Forward Port: 8081
  • Block common exploits: Active

Then click on SSL Tab and fill in:

  • SSL Certificate: Request a new SSL Certificate
  • Force SSL: Active
  • Email address for Let’s encrypt: your email address
  • I agree to … : Active

Click on save it will takes time to generate the SSL certificate then edit the connection again and open the SSL tab you will find everything is disabled, please enable: Force SSL, HSTS Enabled and HTTP/2 Support


and then on advanced tab, copy paste below:

location /.well-known/carddav {
  return 301 https://[]/remote.php/dav;

location /.well-known/caldav {
  return 301 https://[]/remote.php/dav;

*poof* your nextcloud goes online!

Next since it goes online you can now proxy the connection by going Cloudflare and edit the subdomain and change the Proxy Status to Proxied. It will takes time to propagate however next time you ping it will change the IP address every time making both your oracle cloud and raspberry pi more secure.

Step 7 – Configuring NextCloud

If you go to SettingSystems you will find that the max upload size by default is 2MB that’s a joke right? here’s how to up the limit including the memory so you get the best performance into this:

Open your terminal and SSH/Mosh your Pi, remember that in the docker compose we mount conf.d volume now let’s go to that directory.

$ cd /mnt/hdd/nextcloud/conf.d
$ nano upload-max-filesize.ini

it should create a new file just copy below:

upload_max_filesize = 16G

Save it and done.

Next for the memory

$ cd /mnt/hdd/nextcloud/conf.d
$ nano memory-limit.ini

We cannot setup more that 2GB since our OS is 32 bit so copy this instead.


Save it and exit. Restart both your Nextcloud App and DB from the portainer and check the system from settings again. Booyah!

Then since https proxy is being setup you need to configure your nextcloud config file by editing /mnt/hdd/nextcloud/html/config/config.php and add below to config:

'overwrite.cli.url' => '',
'overwritehost' => '',
'overwriteprotocol' => 'https',
'trusted_domains' => array (
  0 => '192.168.XX.XX:8081', //Raspberry PI local IP address
  1 => 'raspberrypi.local:8081',
  2 => '',
'trusted_proxies' => array (
  0 => '172.XX.XX.XX/16', //Container IP address
  1 => '192.168.XX.XX/24', //Raspberry Pi Local IP address
  2 => 'XX.XX.XX.XX/16', //VPS Public IP address

Next we need to make sure cronjob are running properly, from nextcloudSettingsBasic Settings make sure that you selected cron like below:

Then we can run the cron outside the container wo if watchtower update the image it won’t affected our nextcloud cron job, from your raspberry terminal edit crontab:

$ crontab -e

and add below:

# Only do this if you mostly copy paste data from FTP or SMB it will scan the file based on profile / username
#0 */1 * * * /usr/bin/docker exec --user www-data nextcloud_app_1 php -f /var/www/html/occ files:scan profile_name >/dev/null
# Recommended to do at least once a week, this will run at 2am
0 2 * * */7 /usr/bin/docker exec --user www-data nextcloud_app_1 php -f /var/www/html/occ files:scan --all >/dev/null
# Recommended to do at least once a week, this will run at 3am
0 3 * * */7 /usr/bin/docker exec --user www-data nextcloud_app_1 php -f /var/www/html/occ files:scan-app-data >/dev/null
# Only enable if you have app preview generator installed
#0 */12 * * * /usr/bin/docker exec --user www-data nextcloud_app_1 php -f /var/www/html/occ preview:pre-generate >/dev/null

Step 8 – Accessing the domain in same LAN as LAN

You don’t want to access your nextcloud over the internet when you are in fact in the same LAN right? Confuse? Okay, Imagine your are in the bedroom and you want to go to the bathroom next your bedroom, but, instead you go outside the house then go back through the gate to the front door and to your bedroom and then finally arrived in the bathroom, that’s stupid right? So you need to tell your DNS where is the bathroom door when you are in LAN, I hope that answer why we need the Step 1 in this guide, now, open pihole by going to http://raspberrypi.local:8008/admin and then go to Local DNS Records add below:

  • Domain: your subdomain for nextcloud
  • IP address: Raspberry pi local address

Don’t forget to go to Pi-Hole settings and restart DNS resolver

That’s it accessing and uploading files inside LAN is gigabit speed now (depends on your hardware)

Step 9 – Checking if NextCloud happy with our setup

Open your go to SettingsOverview make sure All checks passed

you can also open nextcloud security scan and then check out how it goes

Step 10 – BONUS: Install Scrunity to monitor your HDD health

Prepare a directory for scrunity docker:

$ sudo mkdir /home/pi/.config/appdata/scrunity
$ sudo chown pi:pi /home/pi/.config/appdata/scrunity
$ sudo chmod 775 /home/pi/.config/appdata/scrunity

and then execute below command:

$ docker run --name scrutiny -p 8282:8080 \
--privileged \
-v /run/udev:/run/udev:ro \
-v /dev/disk:/dev/disk:ro \
-v /home/pi/.config/appdata/scrutiny/config:/config \
-e PUID=1000 \
-e PGID=1000 \
-e UMASK=002 \
-e TZ="Asia/Singapore" \
-e ARGS="" \
-e DEBUG="yes" \
-e INTERVAL=86400 \
-e API_ENDPOINT="http://localhost:8080" \
-e MODE="both" \
--restart always \
-d hotio/scrutiny

Open your raspberrypi for port 8282 in a browser http://raspberrypi.local:8282/

STEP 11 – MEGA BONUS: Tips on manually upload / copying files

Always do manually copy from SMB or through sftp whenever you can, it will be much faster and then you can have nextcloud to read and update the files structure in database later. Your files should be located at:


if you want to update nextcloud for certain folder only:

$ docker exec -it --user www-data nextcloud_app_1 php occ files:scan --path="/[username]/files/[folder_name]" --verbose

or if you want to update all the folder within the profile, simply:

$ docker exec -it --user www-data nextcloud_app_1 php occ files:scan [username] --verbose

If you are happy with the guide kindly donate to keep this blog alive. If you need any help with this guide or want me to setup for you, kindly contact me at

Be generous and tipshare this post.
How much do you want to tip?

Don't know how to pay?