Skip to content

Installing Nextcloud 12 on CentOS 7

My setup uses three VMs but you can technically do this on one if you want.

  • web01 - nginx proxy

  • app01 - php-fpm and nextcloud install

  • db01 - MariaDB mysql server

I will only cover setting up the first two layers here, not setting up the mysql server or the database.

Web layer

Install nginx.

Setup ''/etc/nginx/conf.d/nextcloud.conf'' like this.

upstream php-handler {                                                
    server app01:9002;                                    

server {                                                              
    listen 80;                                                          
    server_name cloud;                                    
    # enforce https                                                     
    #return 301 https://$server_name$request_uri;                       

#server {                                                             

    #listen 443 ssl;                                                    
    #server_name cloud;                                

    #ssl_certificate /etc/letsencrypt/live/cloud/fullchain.pem;                                                               
    #ssl_certificate_key /etc/letsencrypt/live/cloud/privkey.pem;                                                             

    error_log /var/log/nginx/cloud_error.log;
    access_log /var/log/nginx/cloud_access.log;

    add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
    add_header X-Clacks-Overhead "GNU Terry Pratchett";

    # Path to the root of your installation
    root /var/www/nextcloud;
    # set max upload size
    client_max_body_size 10G;
    fastcgi_buffers 64 4K;

    # Disable gzip to avoid the removal of the ETag header
    gzip off;

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

    rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
    rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
    rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;

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

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

    location ~ ^/(?:\.htaccess|data|config|db_structure\.xml|README){   
    deny all;                                                         

    location / {                                                        
    # The following 2 rules are only needed with webfinger            
    rewrite ^/.well-known/host-meta /public.php?service=host-meta last;                                                                      
    rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;                                                            

    rewrite ^/.well-known/carddav /remote.php/carddav/ redirect;      
    rewrite ^/.well-known/caldav /remote.php/caldav/ redirect;        

    rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;                      

    try_files $uri $uri/ /index.php;                                  

    location ~ \.php(?:$|/) {                                           
    fastcgi_split_path_info ^(.+\.php)(/.+)$;                         
    include fastcgi_params;                                           
    #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;                                                                       
    fastcgi_param SCRIPT_FILENAME /usr/share/owncloud/$fastcgi_script_name;                                                                  
    fastcgi_param PATH_INFO $fastcgi_path_info;                       
    fastcgi_param HTTPS off;                                           
    fastcgi_pass php-handler;                                         

    # Optional: set long EXPIRES header on static assets                
    location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {            
    expires 30d;                                                      
    # Optional: Don't log access to assets                            
    access_log off;                                                   

Some notes.

  • Because it's in my LAN at home only accessible over VPN I didn't bother with ssl.

  • The 2nd line in upstream php-handler defines the app server address where php-fpm is listening.

  • Note ''fastcgi_param SCRIPT_FILENAME'' if you run nginx on a separate server from php because that document_root won't exist on the web frontend. ''document_root'' must match the nextcloud root on the app server.

  • Note ''fastcgi_param HTTPS off'' near the bottom if you ever enable https.

App layer


First install the IUS repo for more recent versions of PHP than what is available in CentOS 7.

If you're running Fedora instead of CentOS you can find php 7.1 natively in its repos.

Then install all these packages at once, if you have an old php install then that must be uninstalled first or it will clash with php71.

$ sudo yum remove 'php*'
$ sudo yum -y install php71u-fpm php71u-cli php71u-gd php71u-mcrypt php71u-mysql \
php70u-pear php71u-xml php71u-mbstring php71u-pdo php71u-json php71u-pecl-apcu \
php71u-pecl-apcu-devel php71u-mysqlnd


Stripped of its comments the file ''/etc/php-fpm.d/nextcloud.conf'' looks like this.

listen = app01:9002
listen.allowed_clients =

user = apache
group = apache

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 2

slowlog = /var/log/php-fpm/nextcloud-slow.log
catch_workers_output = no
access.log = /var/log/php-fpm/nextcloud.access.log

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

php_admin_value[error_log] = /var/log/php-fpm/nextcloud-error.log
php_admin_flag[log_errors] = on
php_admin_value[open_basedir] = "/dev/urandom:/usr/share/nextcloud:/usr/share/nextcloud/config:/usr/share/nextcloud/apps:/tmp"
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
php_value[upload_max_filesize] = 10G
php_value[post_max_size] = 10G
php_value[max_input_time] = 7200
php_value[max_execution_time] = 7200

Some notes:

  • Obviously replace hostnames and IPs with your own.

  • The pm.* settings are heavily reduced compared to the default because this runs at home. A live install used by many people would require more processes to handle the connections.

  • ''catch_workers_output'' and ''access.log'' are good debug tools that don't need to be enabled.

  • My advice is to mount /tmp with noexec flag if you're going to be using it heavily with PHP like this.

  • ''php_admin_value[open_basedir]'' needs to list the nextcloud root, which is different depending on how you installed it. The CentOS package uses /usr/share/nextcloud for example.

Install nextcloud

Download nextcloud and unpack it into ''/var/www/nextcloud''.

For example:

$ sudo tar -xvjf nextcloud-12.0.4.tar.bz2 -C /var/www/

If you have a separate web proxy server you need to repeat the above step on all web proxies to provide static files. But no php execution and no configuration needs to be done there. They also all need to be updated at the same time as your app servers.

Setup selinux contexts and booleans.

$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/data(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/config(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/apps(/.*)?'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '.htaccess'
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t '.user.ini'
$ sudo setsebool -P  httpd_unified  off
$ sudo setsebool -P httpd_can_network_connect_db on
$ sudo setsebool -P httpd_can_sendmail on
$ sudo restorecon -Rv /var/www

All of this is documented in the Nextcloud install docs.

Last update: August 31, 2021