Installation of nextcloud on nginx (on raspi) without a bought domain

Hi,

I’m having trouble getting to the nextcloud startpage (for final installation).
I already have installed nginx with the whole LEMP stack and downloaded and extracted the zip file from nextcloud.

Now I’m stuck in the nginx config file for nextcloud. Every tutorial and guide I’ve found says that at the field server_name you’ll have to put your domainname.
Since I don’t have a bought domainname I want to have it running over localhost, but what has to be in this field for that purpose???
Everything I tried lead me to display the default nginx startpage when calling the ip of my raspberry in my web browser.

Thanks in advance and with best wishes

Here my nginx config for nextcloud (located at /etc/nginx/config.d/nextcloud):

config file
server {
listen 80;
server_name 192.168.178.24;

# Add headers to serve security related headers
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
add_header Referrer-Policy no-referrer;

#I found this header is needed on Ubuntu, but not on Arch Linux.
add_header X-Frame-Options "SAMEORIGIN";

# Path to the root of your installation
root /usr/share/nginx/nextcloud/;

access_log /var/log/nginx/nextcloud.access;
error_log /var/log/nginx/nextcloud.error;

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json
# last;

location = /.well-known/carddav {
    return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
   return 301 $scheme://$host/remote.php/dav;
}

location ~ /.well-known/acme-challenge {
  allow all;
}

# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;

# Disable gzip to avoid the removal of the ETag header
gzip off;

# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;

error_page 403 /core/templates/403.php;
error_page 404 /core/templates/404.php;

location / {
   rewrite ^ /index.php$uri;
}

location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
   deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
   deny all;
 }

location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
   include fastcgi_params;
   fastcgi_split_path_info ^(.+\.php)(/.*)$;
   fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
   fastcgi_param PATH_INFO $fastcgi_path_info;
   #Avoid sending the security headers twice
   fastcgi_param modHeadersAvailable true;
   fastcgi_param front_controller_active true;
   fastcgi_pass unix:/run/php/php7.2-fpm.sock;
   fastcgi_intercept_errors on;
   fastcgi_request_buffering off;
}

location ~ ^/(?:updater|ocs-provider)(?:$|/) {
   try_files $uri/ =404;
   index index.php;
}

# Adding the cache control header for js and css files
# Make sure it is BELOW the PHP block
location ~* \.(?:css|js)$ {
    try_files $uri /index.php$uri$is_args$args;
    add_header Cache-Control "public, max-age=7200";
    # Add headers to serve security related headers (It is intended to
    # have those duplicated to the ones above)
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    add_header Referrer-Policy no-referrer;
    # Optional: Don't log access to assets
    access_log off;

}

location ~* .(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
try_files $uri /index.php$uri$is_args$args;
# Optional: Don’t log access to other assets
access_log off;
}
}

It should be sufficient to set the ip address in config.php

array (
0 => ‘192.168.178.24’,
),
‘overwrite.cli.url’ => ‘http://192.168.178.24’,

Don’t forget to restart nginx.

EDIT: Do you have this in your nginx config? (if you use php7.3, otherwise adapt it)

upstream php-handler {
    server unix:/var/run/php/php7.3-fpm.sock;
}

server {
    listen 80;

UPDATE:
I’m now able to reach the nextcloud site from my browser. (I renamed the nextcloud config to default.conf and renamed the default.conf to default.conf.bak and then it worked. Somehow it works now too after undoing the changes I did. But I still don’t get redirected from entering the ip to ip/index.php)
How do you mean this, my current /etc/nginx.conf looks like this:

conf
user www-data;

worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
worker_connections 768;
# multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
 # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

}

#mail {

# See sample authentication script at:

# http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript

# auth_http localhost/auth.php;

# pop3_capabilities “TOP” “USER”;

# imap_capabilities “IMAP4rev1” “UIDPLUS”;

server {

listen localhost:110;

protocol pop3;

proxy on;

}

server {

listen localhost:143;

protocol imap;

proxy on;

}

#}

But now after being able to reach the interface I’m stuck creating the first account since somehow its not possible to login to the mariaDB, eventhough my cedentials are correct (setup of the db follows)

So for mariaDB setup I do:
sudo mariadb
create database nextcloudDB;
create user nextcloudAdmin@192.168.178.24 identified by ‘’;
grant all privileges on nextcloudDB.* to nextcloudAdmin@192.168.178.24 identified by ‘’;
flush privileges;
exit;

Now in the webinterface of nextcloud I enter:
Username: admin
PWD:

Database User: nextcloudAdmin
Database pwd:
Database Name: nextcloudDB
Database host: 192.168.178.24

But then I get the Error:
Error

Error while trying to create admin user: Failed to connect to the database: An exception occurred in driver: SQLSTATE[HY000] [2002] Connection refused

Here is my working and I think quite up to date nginx nextcloud setup on a Raspberry Pi 4:
Adapted to your environment (ip and webroot folder).

upstream php-handler {
    server unix:/var/run/php/php7.3-fpm.sock;
}

server {
    listen 80;
    server_name 192.168.178.24;

    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this
    # topic first.
    add_header Strict-Transport-Security "max-age=15768000;includeSubDomains;";
    #
    # WARNING: Only add the preload option once you read about
    # the consequences in https://hstspreload.org/. This option
    # will add the domain to a hardcoded list that is shipped
    # in all major browsers and getting removed from this list
    # could take several months.
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Robots-Tag "none" always;
    add_header X-Download-Options "noopen" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Permitted-Cross-Domain-Policies "none" always;
    add_header Referrer-Policy "no-referrer" always;

    fastcgi_hide_header X-Powered-By;

    # Path to the root of your installation
    root /usr/share/nginx/nextcloud/;

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # The following 2 rules are only needed for the user_webfinger app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
    #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json
    # last;

    location = /.well-known/carddav {
      return 301 $scheme://$host:$server_port/remote.php/dav;
    }
    location = /.well-known/caldav {
      return 301 $scheme://$host:$server_port/remote.php/dav;
    }

    # set max upload size
    client_max_body_size 512M;
    fastcgi_buffers 64 4K;

    # Enable gzip but do not remove ETag headers
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

    # Uncomment if your server is build with the ngx_pagespeed module
    # This module is currently not supported.
    #pagespeed off;

    location / {
        rewrite ^ /index.php;
    }

    location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
        deny all;
    }
    location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
        deny all;
    }

    location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
        fastcgi_split_path_info ^(.+?\.php)(\/.*)$;
        try_files $fastcgi_script_name =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS on;
        #Avoid sending the security headers twice
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
        #fastcgi_read_timeout 1200;
    }

    location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
        try_files $uri/ =404;
        index index.php;
    }

    # Adding the cache control header for js and css files
    # Make sure it is BELOW the PHP block
    location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463";
        # Add headers to serve security related headers (It is intended to
        # have those duplicated to the ones above)
        # Before enabling Strict-Transport-Security headers please read into
        # this topic first.
        # add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
        #
        # WARNING: Only add the preload option once you read about
        # the consequences in https://hstspreload.org/. This option
        # will add the domain to a hardcoded list that is shipped
        # in all major browsers and getting removed from this list
        # could take several months.
        add_header Referrer-Policy "no-referrer" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Robots-Tag "none" always;
        add_header X-Download-Options "noopen" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Permitted-Cross-Domain-Policies "none" always;
        
        # Optional: Don't log access to assets
        access_log off;
    }

    location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
        try_files $uri /index.php$request_uri;
        # Optional: Don't log access to other assets
        access_log off;
    }
}

Now this is the nextcloud.conf right?

Yes, included in nginx.conf

You mean, I should store this as nginx.conf directly instead of in the conf.d folder?

No, it means it is called by nginx.conf (include command)

nginx.conf looks like this on my RPI:

user www-data;
worker_processes 2;
worker_cpu_affinity auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 768;
	# multi_accept on;
}

http {

	##
	# Basic Settings
	##

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	server_tokens off;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_protocols TLSv1.2;
	ssl_prefer_server_ciphers on;

	##
	# Logging Settings
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";

	# gzip_vary on;
	# gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	# gzip_http_version 1.1;
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

	##
	# Virtual Host Configs
	##

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}

Ah right, like all *.conf in the conf.d folder are loaded. Ok cool thanks.

Solved the nginx configuration. Remains the trouble with the creation of the root account in nextcloud, the failure when trying to connect to mariaDB. Any Ideas?

Does it give you a verbose error message?

  • Do you use localhost?
  • Can you login using the credentials with mariadb -u nextcloud -p or whatever name you have given to your database user?

EDIT:

  • Is the php-mysql module installed?
    sudo apt-get install php7.3-mysql (If you are using php 7.3)
  • Did you select mariaDB instead of sqlite?

No this time I explicitly used the specific IP, since I’m not sure whether localhost would work (or do you think it would have worked in the nginx config as well instead of the IP?).
No sadly I don’t get any more error messages from the web interface than the one I’ve already given.

If I try mariadb -u nextcloudAdmin -p I get ERROR 1698 (28000): Access denied for user 'nextcloudAdmin'@'localhost' (but this is as expected since I configured it not with localhost)

Regarding the database you should use localhost. That’s probably the issue.

1 Like

Well now with
create user nextcloudAdmin2@localhost identified by ‘kosmonaut01’;
grant all privileges on nextcloudDB.* to nextcloudAdmin2@localhost identified by ‘’;
flush privileges;

Now at least I’m able to login from the commandline.

Since I only have mariadb installed, I have no such selection in the web interface (mariadb is selected), and yes php7.3 is installed.

Yea it works :smile:
Thank you so much, this is my first experience in terms of servers so I definitly heeded help.

Is it normal that the interactions take a lot of time working on the raspberry pi 4?

You’re welcome, I had a hard time myself on first install :wink:

What exactly do you mean with interactions?

1 Like

The loading of a new page takes quite some time…

RPIs even the 4th generation do not have peak performance, but it shouldn’t take too long.
Check the “settings/overview” page in your cloud for messages regarding performance issues.

There are some things you can enhance, though:

  • A fast Micro SD Card is crucial on a PI (‘A2’ certified should be ok)
  • Use caching (APCu and Redis), it’s not hard to set up on a RPI

https://docs.nextcloud.com/server/18/admin_manual/installation/server_tuning.html

Ok, it isn’t too long, but espacially the loading of the first page after logging in takes much time, but I think this it normal.

When looking into the settings -> overview I get a few warnings:

 The database is missing some indexes. Due to the fact that adding indexes on big tables could take some time they were not added automatically. By running "occ db:add-missing-indices" those missing indexes could be added manually while the instance keeps running. Once the indexes are added queries to those tables are usually much faster.

and

Some columns in the database are missing a conversion to big int. Due to the fact that changing column types on big tables could take some time they were not changed automatically. By running 'occ db:convert-filecache-bigint' those pending changes could be applied manually. This operation needs to be made while the instance is offline. For further details read the documentation page about this.

but running both these commands gets me this error:
An unhandled exception has been thrown:
Doctrine\DBAL\DBALException: Failed to connect to the database: An exception occurred in driver: could not find driver in /usr/share/nginx/nextcloud/lib/private/DB/Connection.php:68
Stack trace:

Did you check this?