Jump to content

Nextcloud installation guide updated

wasab

 

This is an updated guide to an old one about how to set up nextcloud, your own cloud storage.

 

This time it is going to be a vanilla install using ubuntu server, nginx, php, and the official nextcloud source code without docker container at all. This is a bit more time consuming than just spinning up docker container but it will allow greater control over the configuration. I may try to containerize this in the future so it becomes much easier to set up but as of now, I have not found a container image whose next cloud is configure to the way i want so I will be installing it natively. 

 

1) prerequisite step, make sure your ubuntu is up to date

sudo apt update && sudo full-upgrade

 

2) install nginx server as well as a convenient firewall utility

sudo apt install nginx ufw -y

 

3) allow inbound connection for both port 80(http) and port 443(https) in your firewall settings, ufw already has a profile for this so just enable it. 

sudo ufw allow 'Nginx Full' && sudo ufw enable

 

4) test by opening up a web browser and type in your server ip address, you can get it using ip route

ip route

if your ip address begins with 192.xxx.xxx... and so on, it is a private ip sitting behind your router and the ip address is going to be with whatever network interface that you are using to connect to the network. in my case, it is my ethernet connection enp34s0 with the ip 192.168.1.10

image.png.3c0d3c3a939233dfece2669f56e59829.png

 

inside your browser, type in http://<your ip address>. If you have desktop enviorment install on your ubuntu server, you can open up the browser in your server machine and do http://localhost but i suggest you do it from another computer so you can verify other computers are able to connect. for private ip, make sure whatever computer your browser is on is connected to the same network as well.

 

if you see something like this, this means your nginx server is working properly. Make sure this is working properly first. If this isnt working, it will be difficult trouble shooting issues in later steps. Don't mind that it says apache2, my index.html file is the one from the apache which i have not deleted yet.

image.thumb.png.cc1bf3c63213c485a96ee2349e763414.png

 

 

5) get a domain for ddns. If you want something free, use https://www.noip.com/ which is what i am going to be using. Go to its website and then register for an account then create a hostname, you can call your website whatever. This is optional and you can also skip this step if you have a public static ip or a domain name already but you will need to configure your nginx config file accordingly which I am not going to go over. 

image.thumb.png.ce71bf3bc430b9e14b6d104e2a9968a2.png

 

install the no ip client to automatically update your server public ip address so web clients can query the dns record and get back the right ip address to your server. 

https://www.noip.com/support/knowledgebase/installing-the-linux-dynamic-update-client/

cd ~/; wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz; tar xzf noip-duc-linux.tar.gz; cd noip-2.1.9-1; make; sudo make install; 

it will ask you for your network interface. type 0, that is usually the proper one. mine is enp34s0 which is my ethernet adaptor interface. wifi interfaces will usually begins with wlps or wlan something. Note, running your server on wifi is bad idea.

 

image.png.9e92015c273819f6587d8707bdbefde6.png

 

the rest is self explanatory, enter your no ip user name and password and choose the domain and rest can be just enter and enter key

if you messed up the first time, you can do it again with the command below

sudo /usr/local/bin/noip2 -C

 

6)  create a ssl certificate with cerbot and lets encrypt. again, this is optional but you will be left without ssl encyption and you will need to config your nginx differently which I will not be going over either. Begin by installing the following packages.

sudo apt install certbot python3-certbot-apache

to verify the domain belongs to you, cerbot will need to bind to your server's port 80 and have an outside client connection to verify. for this purposes, we will need to temporaily stop nginx.

sudo systemctl stop nginx

 

NOTE IF YOUR COMPUTER SITS BEHIND A ROUTER, YOU WILL ALSO NEED TO ENABLE PORT FORWARDING IN YOUR ROUTER ADMIN PAGE. if your server has public and static ip and your server is not behind a NAT or already have firewall rules configure, you can skip this step. If you are running aws cloud for example, you dont need to do this. Go to your cloud admin pannel and configure the firewall rules and you should be good to go.  

 

FOR PRIVATE ROUTER

to do port forwarding, check your router's admin page. Mine for example looks like this. make sure it is forwarding both port 80 and port 443 to the private ip of your server machine. mine is 192.168.1.10 like what i showed in the previous step. Be warned that this expose your computer to the public internet so please make sure you have taken care of security like firewall settings on your server machine. Also note, that your server's ip address may also change, to remedy this, have the router assign a static private ip for your server. Check your router manual on the proper how to. 

image.thumb.png.e8dec434de36559eb36656ed07676d3c.png


 

 

Next  generate ssl certificate using certbot

make sure you replace your domain-name.com with your domain name, mine is privatenextcloud123.ddns.net. After that it asks you some questions which is self explanatory. Just answer as prompted.

sudo certbot certonly --standalone --agree-tos --preferred-challenges http -d domain-name.com

if successful, you will see something like this

image.thumb.png.cbe495f89ffcfac9cf13c21fc72e119b.png

now restart nginx

sudo systemctl start nginx

 

do a test run, copy and past your domain name into the browser. if you reach the same webpage, then congrats, you have a domain set up that is reachable from the world wide web.

 

note if your certificate expired, you will need to do cerbot renew to renew it, you will need disable nginx again. You can automate this by using the crontab

 

7) Install database

sudo apt install mariadb-server

 

connect to the db and create database and user for nextcloud

sudo mariadb

then run the following database queries

CREATE DATABASE nextcloud;

and then grant privilege and set password for the nextcloud user. replace mypassword to whatever your password is

GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost' IDENTIFIED BY 'mypassword';

and flush the privileges

FLUSH PRIVILEGES;

exit out of the data base by typing exit and enter

 

8) Install nextcloud

cd ~/; wget https://download.nextcloud.com/server/releases/latest.zip; unzip latest.zip; sudo mv nextcloud /var/www/; sudo chown -R  www-data:www-data /var/www/nextcloud; sudo chmod 755 -R /var/www/nextcloud;

 

9) Install php. Currently, nextcloud has no support for php 8.2 so we will use the older 7.4 

sudo apt install php7.4 php7.4-cli php7.4-common php7.4-json php7.4-fpm php7.4-curl php7.4-mysql php7.4-gd php7.4-opcache php7.4-xml php7.4-zip php7.4-mbstring

 

10) config nginx

sudo nano /etc/nginx/sites-enabled/default

delete everything(crl+k)  and then copy and paste the template below. replace <your domain> with your own domain

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

server {
    listen 80;
    listen [::]:80;
    server_name <your domain>;
    # enforce https
    return 301 https://$server_name:443$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name <your domain>;
	
    access_log /var/log/nginx/nextcloud.access.log;
    error_log /var/log/nginx/nextcloud.error.log;
    ssl_certificate /etc/letsencrypt/live/<your domain>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<your domain>/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
    ssl_session_tickets off;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    error_page 497 301 =307 https://$server_name:443$request_uri;    
    # 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; preload;" always;
    #
    # 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-Download-Options "noopen" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Permitted-Cross-Domain-Policies "none" always;
    add_header X-Robots-Tag "none" always;
    add_header X-XSS-Protection "1; mode=block" always;
	
	# Remove X-Powered-By, which is an information leak
    fastcgi_hide_header X-Powered-By;

    # Path to the root of your installation
    root /var/www/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;

    # The following rule is only needed for the Social app.
    # Uncomment it if you're planning to use this app.
    #rewrite ^/.well-known/webfinger /public.php?service=webfinger 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 100M;
    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\/.+|.+\/richdocumentscode\/proxy)\.php(?:$|\/) {
        fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
        set $path_info $fastcgi_path_info;
        try_files $fastcgi_script_name =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param HTTPS on;
        # Avoid sending the security headers twice
        fastcgi_param modHeadersAvailable true;
        # Enable pretty urls
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
    }

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

    # Adding the cache control header for js, css and map 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_header Referrer-Policy "no-referrer" always;
        add_header X-Content-Type-Options "nosniff" 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 X-Robots-Tag "none" always;
        add_header X-XSS-Protection "1; mode=block" always;

        # Optional: Don't log access to assets
        access_log off;
    }

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

 

save and exit (crl-x and then y and enter) then restart nginx

sudo systemctl restart nginx

 

now if you type your domain in your browser, you should see this. congrats, you are pretty much done. follow through the nextcloud install wizard. Enter "nextcloud" for database user and database name and then whatever password you set for the nextcloud database user in your previous step. 

image.thumb.png.35562e954869509af20186714b5f998b.png

 

After installation, you will see this

image.thumb.png.a114bfd8a088fe2d2bde5bcdf6929566.png
 

feel free to post below if you encounter issues or have questions

Sudo make me a sandwich 

Link to comment
Share on other sites

Link to post
Share on other sites

  • 4 months later...

When I was running certbot it fails at the challenge and when i run

cd ~/; wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz; tar xzf noip-duc-linux.tar.gz; cd noip-2.1.9-1; make; sudo make install; 

It doesnt have me follow any steps it just says


:~$ cd ~/; wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz; tar xzf noip-duc-linux.tar.gz; cd noip-2.1.9-1; make; sudo make install;
--2023-05-29 18:55:01--  http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz
Resolving www.no-ip.com (www.no-ip.com)... 158.247.7.199
Connecting to www.no-ip.com (www.no-ip.com)|158.247.7.199|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://www.noip.com/client/linux/noip-duc-linux.tar.gz [following]
--2023-05-29 18:55:01--  https://www.noip.com/client/linux/noip-duc-linux.tar.gz
Resolving www.noip.com (www.noip.com)... 158.247.7.200
Connecting to www.noip.com (www.noip.com)|158.247.7.200|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 134188 (131K) [application/x-gzip]
Saving to: ‘noip-duc-linux.tar.gz’

noip-duc-linux.tar.gz                                          100%[====================================================================================================================================================>] 131.04K   644KB/s    in 0.2s

2023-05-29 18:55:01 (644 KB/s) - ‘noip-duc-linux.tar.gz’ saved [134188/134188]


Command 'make' not found, but can be installed with:

sudo apt install make        # version 4.2.1-1.2, or
sudo apt install make-guile  # version 4.2.1-1.2

sudo: make: command not found

 

Any Help would be great.

Link to comment
Share on other sites

Link to post
Share on other sites

On 5/29/2023 at 3:18 PM, Poke314 said:

snip

try sudo apt install make and then cd into noip-2.1.9-1 and do another make and sudo make install

Sudo make me a sandwich 

Link to comment
Share on other sites

Link to post
Share on other sites

@wasab Nice guide, I gotta point out a few potential issues (hope you don't mind).

 

image.png.4620a54146fc5dbf7a9164fcf95b39be.png

Shouldn't data be outside web root?

Also:

On 1/8/2023 at 2:57 AM, wasab said:

8) Install nextcloud

cd ~/; wget https://download.nextcloud.com/server/releases/latest.zip; unzip latest.zip; sudo mv nextcloud /var/www/; sudo chown -R  www-data:www-data /var/www/nextcloud; sudo chmod 755 -R /var/www/nextcloud;

You didn't make the data dir, there is no data dir inside the zip:
image.png.b6ee6896994907294b37acf3552aaddc.png

So Web GUI setup will fail.


Maybe you are not using the data dir inside web root, but you didn't tell the readers what they should do:

On 1/8/2023 at 2:57 AM, wasab said:

now if you type your domain in your browser, you should see this. congrats, you are pretty much done. follow through the nextcloud install wizard. Enter "nextcloud" for database user and database name and then whatever password you set for the nextcloud database user in your previous step. 

(where to make the data directory, who should own it and which permissions should be used)

 

Speaking about permissions, 755?

Edit: Shouldn't that be:

chown -R www-data:www-data nextcloud
find nextcloud/ -type d -exec chmod 750 {} \;
find nextcloud/ -type f -exec chmod 640 {} \;

https://docs.nextcloud.com/server/latest/admin_manual/maintenance/manual_upgrade.html

 

Also it would be nice to mention caching, cron jobs, php settings etc. But I get it, the guide is long enough as is 😀

VGhlIHF1aWV0ZXIgeW91IGJlY29tZSwgdGhlIG1vcmUgeW91IGFyZSBhYmxlIHRvIGhlYXIu

^ not a crypto wallet

Link to comment
Share on other sites

Link to post
Share on other sites

On 6/2/2023 at 9:44 PM, Biohazard777 said:

snip

no problem. i dont mind at all. 

 

i think data dir is auto-generated by the install wizard. i don't recall if i created it manually or not. if not, then good call. That does remind me, all the uploaded contents are store inside the .ocdata within the data dir. it is possible to do a symbolic link and move the data dir to another drive if like say you uploaded a lot of files and you need to move the files to a bigger drive due to lack of disk space. using lvm is great as well since it can combine drive capacities seamlessly.

 

www-data on ubuntu is the default group that server process like nginx and apache runs as by default so changing the ownership of the files should suffice. If you do not change ownership, you probably need to do 777 since www-data won't be able to write inside the data dir. 

Edit: oh i see what you mean. for security purposes, changing permission to 750 or 640 is indeed a good idea. 

 

As for caching and cron jobs, they are a good idea. I have never use them myself however so I left them out(was feeling a bit lazy to implement them😐). for php settings, you may want to increase the memory and the default file upload size limit inside the relevant php-fpm conf file.

Sudo make me a sandwich 

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×