NextCloud is a fantastic solution to manage documents, however the added app features, including integration with Collabora CODE server makes it an invaluable method to store your files and access them remotely.
In this tutorial we will assume that you know the basics of deploying your server with DNS and IP Routing and that subdomain.example.com routes to your chosen Debian 11 server and that you are working as root, if not, you can use a user with sudo privileges, however you will need to append sudo to the appropriate commands listed here.
-
Update Debian:
As always, we want to start on an up-to-date Debian server.apt update && apt upgrade -y
-
Install Prerequisites:
apt install nginx unzip php php-{gd,curl,zip,dom,xml,simplexml,mbstring,intl,fpm,json,ctype,posix,xmlreader,xmlwriter,fileinfo,bz2} mariadb-server mariadb-client certbot -y
-
Configure MariaDB database:
You will need to create a database and user for using NextCloud:mysql
And run the following SQL Commands:
CREATE DATABASE nextcloud_db; CREATE USER 'nextcloud_user'@localhost IDENTIFIED BY 'Strong_Password'; GRANT ALL ON nextcloud_db.* TO 'nextcloud_user'@localhost; FLUSH PRIVILEGES; QUIT;
-
Download the latest version of NextCloud (24.0.3 at the time of writing):
wget https://download.nextcloud.com/server/releases/nextcloud-25.0.2.zip
-
Now unzip the package and move it to your webserver folder:
unzip nextcloud-25.0.2.zip
mv nextcloud /var/www/html/nextcloud
-
You will need to adjust give the WebServer permissions to access the folder:
chown -R www-data:www-data /var/www/html/nextcloud
-
Set Up NextCloud Data Folder:
mkdir /var/www/html/nextcloud/data
chown -R www-data:www-data /var/www/html/nextcloud/data
chown -R 755 /var/www/html/nextcloud/data
-
Generate an SSL Certificate with CertBot:
certbot certonly --webroot --webroot-path /var/www/html/nextcloud -d subdomain.example.com --agree-tos --email admin@example.com
-
Create a VirtualHost for NginX:
Create the virtualhost file:nano /var/nginx/conf.d/nextcloud.conf
And paste the following (Changing the server_name to your own configuration):
upstream php-handler { server unix:/run/php/php7.4-fpm.sock; } map $arg_v $asset_immutable { "" ""; default "immutable"; } server { listen 80; listen [::]:80; server_name subdomain.example.com; server_tokens off; error_log /var/log/nginxnextcloud_error.log; access_log /var/log/nginx/nextcloud_access.log; return 301 https://$server_name$request_uri; } server { listen 443 ssl; # managed by Certbot listen [::]:443 ssl; # managed by Certbot server_name subdomain.example.com; root /var/www/html/nextcloud; server_tokens off; error_log /var/log/nginxnextcloud_error.log; access_log /var/log/nginx/nextcloud_access.log; ssl_certificate /etc/letsencrypt/live/subdomain.example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/subdomain.example.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot add_header Strict-Transport-Security "max-age=31536000" always; # managed by Certbot ssl_trusted_certificate /etc/letsencrypt/live/subdomain.example.com/chain.pem; # managed by Certbot ssl_stapling on; # managed by Certbot ssl_stapling_verify on; # managed by Certbot client_max_body_size 512M; client_body_timeout 300s; fastcgi_buffers 64 4K; 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/wasm 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; client_body_buffer_size 512k; 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; fastcgi_hide_header X-Powered-By; index index.php index.html /index.php$request_uri; location = / { if ( $http_user_agent ~ ^DavClnt ) { return 302 /remote.php/webdav/$is_args$args; } } location = /robots.txt { allow all; log_not_found off; access_log off; } location ^~ /.well-known { location = /.well-known/carddav { return 301 /remote.php/dav/; } location = /.well-known/caldav { return 301 /remote.php/dav/; } location /.well-known/acme-challenge { try_files $uri $uri/ =404; } location /.well-known/pki-validation { try_files $uri $uri/ =404; } return 301 /index.php$request_uri; } location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; } location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; } location ~ \.php(?:$|/) { rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri; 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; fastcgi_param modHeadersAvailable true; fastcgi_param front_controller_active true; fastcgi_pass php-handler; fastcgi_intercept_errors on; fastcgi_request_buffering off; fastcgi_max_temp_file_size 0; } location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map)$ { try_files $uri /index.php$request_uri; add_header Cache-Control "public, max-age=15778463, $asset_immutable"; access_log off; location ~ \.wasm$ { default_type application/wasm; } } location ~ \.woff2?$ { try_files $uri /index.php$request_uri; expires 7d; access_log off; } location /remote { return 301 /remote.php$request_uri; } location / { try_files $uri $uri/ /index.php$request_uri; } }
- Deploye NextCloud:
You can now use your browser to browse to http://subdomain.example.org/ and complete the setup process with the username and database you configured in step 3. -
Manual Installation of Collabora CODE Server (Optional – Might fail in web-interface due to the size):
Due to the size of the installation, this might often fail to update or install from the web-interface, the solution is to use the occ command from within the root of your NextCloud installation folder to manually install this, so first enter that folder:cd /var/www/html/nextcloud
And run the following command:
sudo -u www-data php -d memory_limit=512M ./occ app:install richdocumentscode
Occasionally, you might need to run updates and for the same reason the Collabora CORE Server might fail to update, you can use the occ update command instead:
sudo -u www-data php -d memory_limit=512M ./occ app:update --all
That is it, you have now successfully deployed NextCloud in your Debian Server using a LEMP stack.
Leave a Reply