Use nginx from another serveur to point to nextcloud

Hi all,

I am using Nextcloud since one year and now I have the project to split my home server into small entities.

The Idea is to let nextcloud (lts) on the server and use a mini server as entry (nginx) for all services accross the house (Plex, grafana, web apps,…). The Big server will go to sleep mode when not use and will be wake UP by the small one. The reason of it, IS to not use apps which do not need to run 24/24 and Split which need it to small one (nginx, home assistant, socket io,…) Until now no issue, but I am facing an issue with nextcloud.

My NC is using php-fpm socket to run, which was easy to point directly with nginx and fast-cgi. But it is another discussion when using a nginx on another server to point to it.

I have searched on Google and I have try many solutions :

  • change php-fpm port to listen to 127.0.0.1:9000 => looks like nginx return a 404
  • try to migrate to docker, but in this case I am not able to link my différents HDD mounted on the Root : /md0 and /md127

I Can share the docker-compose done, but in any case if someone have already done it or has a better solution let me know.

instead of setting php-fpm up to listen on a local socket, just set it up to listen on a TCP socket with a dedicated port, and point to the IP of the PHP-FPM server IP and the designated port in your new NGINX box. Besides changing from local socket in NGINX config, just copy ALL other NGINX config for your nextcloud site to the new NGINX. Stop NGINX on the PHP-FPM server and test. If it works, you can now delete NGINX on the local PHP-FPM server entirely.

Other solution is to leave the nextcloud box as-is and instead use the NGINX on your new tiny server, as reverseproxy to your Nextcloud. This solution is by far, the easiest, but with most overhead.

Thanks for your reply

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

server {
    listen 80;
    listen [::]:80;
    server_name ***.***.com www.***.***.com;
    include snippets/authelia.conf;
    # enforce https
    return 301 https://$server_name:443$request_uri;
}

server {
    server_name ***.***.com www.***.***.com;
    include snippets/authelia.conf;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
   # Use Mozilla's guidelines for SSL/TLS settings
    # https://mozilla.github.io/server-side-tls/ssl-config-generator/
    # NOTE: some settings below might be redundant
    ssl_certificate /etc/letsencrypt/live/***.***.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/***.***.com/privkey.pem; # managed by Certbot

    # 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 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 appli>

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

    location / {
        include snippets/authelia.conf;
        rewrite ^ /index.php;
    }
    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 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 appli>

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

    location / {
        include snippets/authelia.conf;
        rewrite ^ /index.php;
    }

....

It is the nginx file used on the different server, this is the configuration file for php-fpm :

listen = 1**.1**.0.**:9001

I have check if server is running :white_check_mark:

Result from distant server :

pain@tendo:~$ SCRIPT_NAME=/ping SCRIPT_FILENAME=/status REQUEST_METHOD=GET cgi-fcgi -bind -connect 1**.1**.0.**:9001/index.php
Primary script unknownStatus: 404 Not Found
Content-type: text/html; charset=UTF-8

File not found.

Same on nginx, do you have an idea ?

The connection is successfull so PHP-FPM is listening and NGINX connects. Something with your passing of PHP files. On PHP-FPM you would have to define the document root of the listener, and then on NGINX, you will have to comment block the document listener.

Here is a good example from Digital Ocean. It is about wordpress, but the principles remains.

I was not aware of your amount of configs in NGINX for the local nextcloud, so I retracts my “only needs to copy” comment.

You will have to configure PHP-FPM to serve the files accordingly, and the NGINX to do the rest.

Even though it says container, the only difference in this example, is to replace the localhost fastcgi_pass with your actual host.

Thanks again for your reply

https://www.digitalocean.com/community/tutorials/php-fpm-nginx

Concerning this, I forget to mention that this nextcloud.conf :

listen = /var/run/nextcloud.sock

listen.owner = nextcloud
listen.group = www-data

user = nextcloud
group = www-data

pm = ondemand
pm.max_children = 56
pm.process_idle_timeout = 60s
pm.max_requests = 500

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

Concerning this :

https://serverfault.com/questions/1038652/nextcloud-fpm-container-with-nginx-on-the-host

It returns 404 too