build your own cloud server at home with Nextcloud

archiemeng | created on Dec. 7, 2020, 1:29 p.m.

Updated on Feb. 18, 2021, 10:14 a.m. | viewed: 737


From Wikipedia: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. In contrast to proprietary services like Dropbox, the open architecture allows adding additional functionality to the server in form of applications.

Also, Nextcloud is a fork of ownCloud.

Install Nextcloud on the server

Based on different distro, there are many different installation guides. For Ubuntu: For Arch Linux In this post, I am going to based on Arch Linux which is the distro of my server.

To install Nextcloud, it basically needs three components(and they are critical to the performance of Nextcloud):

Additionally, on Arch Linux, it needs a hook to upgrade Nextcloud database on every Nextcloud package upgrades. For more details, see Nextcloud - ArchWiki.

# add contents below to /etc/pacman.d/hooks/nextcloud.hook
Operation = Install
Operation = Upgrade
Type = Package
Target = nextcloud Target = nextcloud-app-* [Action] Description = Update Nextcloud installation When = PostTransaction Exec = /usr/bin/runuser -u http -- /usr/bin/php /usr/share/webapps/nextcloud/occ upgrade

Make it public accessable

However, if the Nextcloud server is behind NAT such as home LAN, people outside the LAN will be unable to gain access to the server. One solution is to use a public server to expose the server port to the public. There is already a tool called FRP which can do this.



Download address:

Download the compiled binary according to your system and CPU Architecture. And done.


Example configurations can be get from page and

For our reverse proxy usage. I recommend simply using tcp protocol. Because the p2p NAT punching protocol xtcp rarely success on my servers. Using tcp can ensure a high rate of usability.

The example configuration is on  Here is a English copy of them.

bind_port = 7000
server_addr = x.x.x.x server_port = 7000 [ssh] type = tcp local_ip = local_port = 80 remote_port = 8080

This example expose http server from local port 80 onto remote port 8080 on server x.x.x.x

Once it is accessible on x.x.x.x:8080, the frp part of exposing server is done.

Reverse Proxy

When we use reverse proxy to expose server, there are some other configurations to be done if you have other requirements like reverse proxy it behind apache, and disable public access to 8080 which is hosted by FRP.

Apache configuration

add following lines to apache configurations. It is usually /etc/apache2/sites-available/000-default.conf for HTTP and /etc/apache2/sites-available/000-default-le-ssl.conf for HTTPS

ProxyPreserveHost on

ProxyPass /nextcloud/ http://localhost:8080/nextcloud/
ProxyPassReverse /nextcloud/ http://localhost:8080/nextcloud/

RewriteEngine On
RewriteRule ^/\.well-known/carddav http://localhost:8080/remote.php/dav/ [R=301,L]
RewriteRule ^/\.well-known/caldav http://local;/remote.php/dav/ [R=301,L]

iptable filter

To only allow local access to port 8080, we need to add some rules in iptable.

sudo iptables -A INPUT -p tcp -s --dport 8080 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8080 -j DROP


remote.phpp behind apache:

if you cannot access nextcloud behind reverse proxy and find strange remote.phpp 404 error in apache. Then it is definitely caused by incorrect Proxypass rules. Check the link below for more details.

Another reverse proxy issue:

Reverse proxy and data directory

login loop:

Upload chunk size setting:

I am talking about command:

sudo -u www-data php occ config:app:set files max_chunk_size

Chunking upload files size DOES NOT SUPPORT UNIT SUFFIXES. So only set numbers for it. I mean, you cannot use suffix like "K", "M", "G".

Possible improvements


enable http2 for apache2 on debian-like distro

enable http2 for apache2 (the official way):

Security harden

Cache chunk timeout


# /usr/share/webapps/nextcloud/config/config.php
'cache_chunk_gc_ttl' => 60*60*24

to avoid filling up temp directory which is default to /tmp.