Install Nextcloud on Ubuntu 18.04 with Nginx – Google Cloud. Nextcloud is a platform to protect your data with on-premises file sync and online collaboration technology.

In this guide you are going to learn how to install Nextcloud 15 on Ubuntu 18.04 with Nginx, PHP 7.3 and connect to Cloud SQL.

This setup can also be done on the following platforms.

PlatformMachine TypeCost (Monthly)
Digitalocean1 GB RAM – 1vCPU$5
Google Cloud Platform600 MB RAM$4.28
Amazon Web Servicest1- micro 1 GB RAM$14

Prerequisites

With the above-completed prerequisites I assume you have your Nginx, PHP installed and Cloud SQL is configured.

Set Up Directory

Nextcloud will be located in the home directory and have the following structure

Replace yourdomainname.com with your original domain name.

home
-- yourdomainname.com
---- logs
---- public

The public directory is your website’s root directory and logs directory for your error logs

Now we create these directories and set correct permissions

You need to SSH into your VM Instance and run these commands

mkdir -p yourdomainname.com/logs yourdomainname.com/public

Download Nextcloud

Once you have your directory set up in Google Compute Engine, you can download Nextcloud using the following command.

cd ~/yourdomainname.com/public
wget https://download.nextcloud.com/server/releases/latest.tar.bz2

Now Nextcloud will be downloaded and you need to extract the downloaded file.

sudo tar -xjf latest.tar.bz2
sudo mv ~/yourdomainname.com/public/nextcloud/* ~/yourdomainname.com/public

Now you can setup correct permissions to the files.

sudo chmod -R 755 yourdomainname.com
sudo chown -R username ~/yourdomainname.com

Configure Nginx for Nextcloud

Create a new Nginx configuration for your website in the sites-available directory.

 sudo nano /etc/nginx/sites-available/yourdomainname.com

Copy and paste the following configuration, ensure that you change the server_name, error_log and root directives to match your domain name. Hit CTRL+X followed by Y to save the changes.

server {
listen [::]:80;
listen 80;

server_name yourdomainname.com;

error_log /home/username/yourdomainname.com/logs/error.log;

root /home/username/yourdomainname.com/public/;
index index.php;

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;

fastcgi_hide_header X-Powered-By;

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

location ~* .(svg|svgz)$ {
types {}
default_type image/svg+xml;
}

location = /favicon.ico {
log_not_found off;
access_log off;
}

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

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

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

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)(\/.*|)$;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
fastcgi_read_timeout 3600;
fastcgi_index index.php;
fastcgi_buffers 64 4k;
fastcgi_buffer_size 32k;
include fastcgi_params;
}

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

location ~ .(?:css|js|woff2?|svg|gif)$ {
try_files $uri /index.php$request_uri;

add_header Cache-Control "public, max-age=15778463";
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;

access_log off;
}

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

Hit Ctrl+X followed by Y and Enter to save the file and exit.

To enable this newly created website configuration, symlink the file that you just created into the sites-enabled directory.

sudo ln -s /etc/nginx/sites-available/yourdomainname.com /etc/nginx/sites-enabled/yourdomainname.com

Check your configuration and restart Nginx for the changes to take effect.

sudo nginx -t
sudo service nginx restart

Create SSL certificate and enable HTTP/2

HTTPS
HTTPS is a protocol for secure communication between a server (instance) and a client (web browser). Due to the introduction of Let’s Encrypt, which provides free SSL certificates, HTTPS are adopted by everyone and also provides trust to your audiences.

HTTP/2
HTTP/2 is the latest version of the HTTP protocol and can provide a significant improvement to the load time of your sites. There really is no reason not to enable HTTP/2, the only requirement is that the site must use HTTPS.

sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install python-certbot-nginx

Now we have installed Certbot by Let’s Encrypt for Ubuntu 18.04, run this command to receive your certificates.

sudo certbot --nginx certonly

Enter your email and agree to the terms and conditions, then you will receive the list of domains you need to generate SSL certificate.

To select all domains simply hit Enter

The Certbot client will automatically generate the new certificate for your domain. Now we need to update the Nginx config.

Redirect HTTP Traffic to HTTPS with www in Nginx

Open your site’s Nginx configuration file add replace everything with the following. Replacing the file path with the one you received when obtaining the SSL certificate. The ssl_certificate directive should point to your fullchain.pem file, and the ssl_certificate_key directive should point to your privkey.pem file.

server {
listen [::]:80;
listen 80;

server_name yourdomainname.com www.yourdomainname.com;

return 301 https://yourdomainname.com$request_uri;
}

server {
listen [::]:443 ssl http2;
listen 443 ssl http2;

server_name www.yourdomainname.com;

ssl_certificate /etc/letsencrypt/live/yourdomainname.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomainname.com/privkey.pem;

error_log /home/username/yourdomainname.com/logs/error.log;

root /home/username/yourdomainname.com/public/;
index index.php;

return 301 https://yourdomainname.com$request_uri;
}

server {
listen [::]:443 ssl http2;
listen 443 ssl http2;

server_name yourdomainname.com;

ssl_certificate /etc/letsencrypt/live/yourdomainname.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomainname.com/privkey.pem;

error_log /home/username/yourdomainname.com/logs/error.log;

root /home/username/yourdomainname.com/public/;
index index.php;

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;

fastcgi_hide_header X-Powered-By;

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

location ~* .(svg|svgz)$ {
types {}
default_type image/svg+xml;
}

location = /favicon.ico {
log_not_found off;
access_log off;
}

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

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

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

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)(\/.*|)$;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
fastcgi_read_timeout 3600;
fastcgi_index index.php;
fastcgi_buffers 64 4k;
fastcgi_buffer_size 32k;
include fastcgi_params;
}

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

location ~ .(?:css|js|woff2?|svg|gif)$ {
try_files $uri /index.php$request_uri;

add_header Cache-Control "public, max-age=15778463";
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;
access_log off;
}

location ~ .(?:png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /index.php$request_uri;

access_log off;
}
}

The http2 value is all that is needed to enable the HTTP/2 protocol.

Hit CTRL+X followed by Y to save the changes.

Check your configuration and restart Nginx for the changes to take effect.

sudo nginx -t
sudo service nginx restart

Renewing SSL Certificate

Certificates provided by Let’s Encrypt are valid for 90 days only, so you need to renew them often. Now you set up a cronjob to check for the certificate which is due to expire in next 30 days and renew it automatically.

sudo crontab -e

Add this line at the end of the file

0 0,12 * * * certbot renew >/dev/null 2>&1

Hit CTRL+X followed by Y to save the changes.

This cronjob will attempt to check for renewing the certificate twice daily.

Install Nextcloud

You need to set up Cloud SQL and create a database, user to install Nextcloud 15. Learn to Setup Cloud SQL and connect with Compute Engine

Once Cloud SQL setup is ready and configured to allow connections from your VM Instance.

Visit your domain name in your web browser to install Nextcloud 15 from your browser

You should see the installation wizard to complete the install.

Enter the Cloud SQL details to connect to the database.

Install Nextcloud

For Hostname enter your Cloud SQL IP Address

Enter database name, username, password and click Finish setup to complete the installation.

Wait for the installation to complete.

Once the installation is complete you should see the Nextcloud dashboard.

Conclusion

Now you have learned how to install Nextcloud on your Ubuntu server with Nginx in Google Cloud and secure it with Let’s Encrypt.

Thanks for your time. If you face any problem or any feedback, please leave a comment below.

3 Comments

  1. Cloud Bookleter No. 1 Reply

    Hey,

    first, thank you for the guides. They are really great. However, with this setup I always get a 403 error before I even get to install Nextcloud.
    I redid every step and it always leads to the same result. What am I missing? The error logs only show that access denied due to a rule being present. However, I don’t know which one this can be?

    Do you have any ideas? Thank you already in advance. 🙂

    • Cloudbooklet Reply

      Hi, Please check if you have provided correct permissions

      • Cloud Bookleter No. 1 Reply

        Hi,

        thank you for the fast reply. All permissions were correctly set. The issue was the nginx rule provided in this article. I am referring to this part:

        location ~ ^\/(?:.|autotest|occ|issue|indie|db_|console) {
        deny all;
        }

        Removed the catch-all dot so that:

        location ~ ^\/(?:autotest|occ|issue|indie|db_|console) {
        deny all;
        }

        and the instance is running.

        Thank you though. 🙂

Write A Comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Where Writing Meets Entrepreneurship!

Get FREE Google Cloud Tutorials.
GET NOW
close-link
Please help us get 1000 likes in Facebook. Thank You!
LIKE NOW

Stay Connected!

Get latest tutorials on Google Cloud and Open Source topics
SUBSCRIBE
close-link