Migrating Nextcloud From Apache To Nginx On Ubuntu 16.04

1. Configuring Apache

$ sudo apt-get update
$ sudo nano /etc/apache2/ports.conf

modify the VirtualHost and Listen lines for port 80 to use port 8000 (or any other port number you would like to use).

Note: If you are using a ssl certificate, see ERRORS & SOLUTIONS for a ‘502 Bad Gateway Error' – the solution is to simply delete both ‘Listen 443' lines. :

Listen 8000

<IfModule ssl_module>
 Listen 443
</IfModule>

<IfModule mod_gnutls.c>
 Listen 443
</IfModule>

Ctrl-x, then ‘Y' to save and exit.

Next open the vhost configuration file:

$ sudo nano /etc/apache2/sites-available/000-default.conf

… and change the VirtualHost line at the top to use the IP address 127.0.0.1 and the port 8000:

<VirtualHost 127.0.0.1:8000>
[...]

Ctrl+x, then ‘Y' to save and exit.

Install the Apache module libapache2-mod-rpaf which takes care of logging the correct IP address:

$ sudo apt-get -y install libapache2-mod-rpaf

Next you will need to edit the module configuration file:

$ sudo nano /etc/apache2/mods-available/rpaf.conf

Add the server IP address, in this example we use 192.168.1.100 as the server IP.

RPAFproxy_ips 127.0.0.1 192.168.1.100 ::1

Ctrl+x, then ‘Y' to save and close the file and restart Apache server.

$ sudo /etc/init.d/apache2 restart

You can test rpaf by viewing the Apache access log:

$ sudo tail -f /var/log/apache2/access.log

You should see the following output:

#Before:
127.0.0.1 - - [31/Jun/2016:08:34:07 +0000] "GET /index.html HTTP/1.1"
127.0.0.1 - - [31/Jun/2016:08:34:10 +0000] "GET /index.html HTTP/1.1"

#After
192.168.1.100 - - [31/Jun/2016:08:34:30 +0000] "GET /index.html HTTP/1.1"
192.168.1.100 - - [31/Jun/2016:08:34:34 +0000] "GET /index.html HTTP/1.1"

Restart Apache:

$ sudo /etc/init.d/apache2 restart

Configure the Apache service to start at boot time by running:

$ sudo update-rc.d apache2 defaults

2. Configure nginx

$ sudo apt-get -y install nginx

Create its system startup links and make sure it is started:

$ sudo systemctl enable nginx.service
$ sudo service nginx restart

It should now be listening on port 80.

Create new nginx server block:

$ sudo nano /etc/nginx/sites-available/nextcloud

Add the following content. Note that the path to the original apache ssl certificate is updated and reflected in the path. Also note that this server block is for a nextcloud subdirectory installation (e.g. yoursite.com/nextcloud) and that the root path DOES NOT include ‘/nextcloud' but most of the location lines include the ‘nextcloud' directory while some do not. Referenced from:
https://docs.nextcloud.com/server/11/admin_manual/installation/nginx_nextcloud_9x.html

server {
    listen 80;
    listen [::]:80;
    server_name 192.168.1.100;
    root /var/www/html;
    return 301 https://$server_name$request_uri;
}
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name 192.168.1.100;
    root /var/www/html;
    index index.php index.html index.htm;

    ssl on;
    ssl_certificate     /etc/ssl/certs/apache-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/apache-selfsigned.key;
    ssl_session_timeout 5m;
    ssl_ciphers               'AES128+EECDH:AES128+EDH:!aNULL';
    ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security "max-age=15768000; preload;";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options "SAMEORIGIN";
    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;

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

    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 ^~ /nextcloud {

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

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

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

    location ~ ^/nextcloud/(?:build|tests|config|lib|3rdparty|templates|data)/ {
        deny all;
    }

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

    location ~^/nextcloud/(?: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;
        fastcgi_param HTTPS on;
        #Avoid sending the security headers twice
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
    }

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

    location ~* \.(?:css|js)$ {
        try_files $uri /nextcloud/index.php$uri$is_args$args;
        add_header Cache-Control "public, max-age=7200";
        add_header X-Content-Type-Options nosniff;
        add_header X-Frame-Options "SAMEORIGIN";
        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;
        # Optional: Don't log access to assets
        access_log off;
    }

    location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
        try_files $uri /nextcloud/index.php$uri$is_args$args;
        access_log off;
    }

    location ~ /\.ht {
        deny all;
    }
    }
}

Ctrl+x, then ‘Y' to save and exit.

Verify your Nginx configuration syntax by running the following command:

$ sudo nginx -t

If everything is ok, you should see the following output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Activate the server block by running the following command:

$ sudo ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/nextcloud

Delete the default nginx server block from the ‘sites-enabled' directory (but NOT from ‘site-available'):

$ sudo rm /etc/nginx/sites-enabled/default

Start the Nginx service by running the following command:

$ sudo /etc/init.d/nginx start

Then configure the Nginx service to start at boot time by running the following command:

$ sudo update-rc.d nginx defaults

3. Test Nginx Reverse Proxy

Running the following curl command (the ‘-I' is a hypen and capital ‘I' as in India):

$ curl -I localhost

Example output:

HTTP/1.1 301 Moved Permanently
Server: nginx/1.10.0 (Ubuntu)
Date: Tue, 28 Mar 2017 21:24:49 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://192.168.1.100/

More info on the above output:
https://httpstatuses.com/301

ERRORS & SOLUTIONS


1. If you are getting an error that Nginx will not start/restart after configuring the Nextcloud server block:Solution:
Stop apache > then start nginx > then restart apache. This will allow nginx access to the required ports and let apache run in the back.

$ sudo service apache2 stop
$ sudo /etc/init.d/nginx start
$ sudo service apache2 start

2. If you are getting a ‘502 Bad Gateway Error' when trying to access NextcloudSolution:
Remove the lines ‘Listen 443' from both lines located inside the file ‘/etc/apache2/sites-available/nextcloud.conf':

Reference and more info here:
https://www.scalescale.com/tips/nginx/502-bad-gateway-error-using-nginx/#

original code:

# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 8000

<IfModule ssl_module>
	Listen 443
</IfModule>

<IfModule mod_gnutls.c>
	Listen 443
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Change to look like this:

# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 8000

<IfModule ssl_module>
	
</IfModule>

<IfModule mod_gnutls.c>
	
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

3. If Nginx redirects to the root directory of your site instead of its subdirectory. For example, when trying to access ‘https://yoursite.com/nextcloud‘ nginx will automatically redirect to ‘https://yoursite.com'/login or ‘https://yoursite.com/index.php/login‘, etc.Reference:
https://help.nextcloud.com/t/nginx-reverse-proxy-what-to-write-in-nextclouds-config-php/9149/15

Solution:
1. Double/Triple check the nginx server block code above and make sure it is correct.

2. Make sure that there is no ‘default' file/link in the ‘/etc/nginx/sites-enabled' folder. If there is, remove it. You do not need this enabled.

$ sudo rm /etc/nginx/sites-enabled/default

However, if you have phpmyadmin installed and a corresponding code block set up in ‘default', then it will return a ‘404 Not Found' page when trying to access phpmyadmin.

This is the code block for phpmyadmin located inside the ‘default' file:

# Phpmyadmin Configurations
        location /phpmyadmin {
        root /usr/share/;
        index index.php index.html index.htm;
        location ~ ^/phpmyadmin/(.+\.php)$ {
                try_files $uri =404;
                root /usr/share/;
                #fastcgi_pass 127.0.0.1:9000;
                #fastcgi_param HTTPS on; # <-- add this line
                fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }
        location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
                root /usr/share/;
        }
    }

Will need to attempt an alternative way to access phpmyadmin.


More References:

https://www.howtoforge.com/tutorial/how-to-install-nginx-as-reverse-proxy-for-apache-on-ubuntu-16-04/

https://devops.profitbricks.com/tutorials/configure-nginx-as-a-reverse-proxy-for-apache-on-ubuntu-1604/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.