Nextcloud on CentOS 8 / RHEL 8

So I’m trying to get a complete, clean install of Nextcloud on CentOS 8. I’ve got everything working now except I can’t figure out how to get imagick working. I know I can disable themes in Apps, but I’d like to get it all running. Any help on getting imagick going would be much appreciated!!!

In return for the help, I’m attaching my build script for anyone who wants to install on CentOS8/RHEL8. I started from a clean minimal install that was updated, and nothing more.

DON’T run this on a system that already has mariadb configured or it will fail.

You can run this as is, but I would edit the variables up top to something more appropriate:

#!/bin/sh
# You MUST set the SERVERNAME here:
SERVERNAME=nextcloud.example.com

# These values are used to generate a ssl certificate.  You can/should replace with LetsEncrypt after the build
COUNTRY=US
STATE=California
CITY=Malibu
ORG="Stark Industries"
ORG_UNIT=Nextcloud

# This is the name of the database that will get created for nextcloud
DBNAME=nextcloud
# This is the username that is needed for the nextcloud database.  NOTE: This is not a nextcloud user account
USER=nextclouduser
# This is the name of the nextcloud Admin user
ADMIN=admin

# These values increase the limits for nextcloud:
# BODY sets the client_max_body_size in the nginx nextcloud.conf file
BODY=4096M
# FILESIZE sets the upload_max_filesize in /etc/php.ini
FILESIZE=10240M

# This generates a random password for the root account of mariadb.  You can change it if you wish
MARIADBPASSWORD=`date +%s | sha256sum | base64 | head -c 16`
sleep 1 # We need to sleep 1 to change the password, otherwise we end up with the same hash
# This generates a random password for the nextcloud user account in mariadb.  You can change it if you wish
APPPASSWORD=`date +%s | sha256sum | base64 | head -c 16`
sleep 1 # We need to sleep 1 to change the password, otherwise we end up with the same hash
# This generates a random password for the admin user account password:
ADMINPASS=`date +%s | sha256sum | base64 | head -c 16`

# This will save the values that are needed for setup and accessing mariadb in /root/mariadb.txt
echo -e "MariaDB root password is $MARIADBPASSWORD" >> /root/mariadb.txt
echo -e "App DB is $DBNAME, the Username is $USER and the password is $APPPASSWORD" >> /root/mariadb.txt
# This will save the admin username and password for nextcloud
echo -e "The admin username is $ADMIN and the password is $ADMINPASS" >> /root/nextcloud_admin.txt

##########################################################################
############## NO CHANGES FROM HERE DOWN SHOULD BE REQUIRED ##############
##########################################################################

dnf -y install nginx mariadb-server mariadb php php-mysqlnd php-fpm php-opcache php-gd php-xml php-mbstring wget unzip php-common php-gd php-json php-curl php-zip php-xml php-mbstring php-bz2 php-intl php-process apcu-panel php-pecl-apcu
sed -i 's/user\ =\ apache/user\ =\ nginx/g' /etc/php-fpm.d/www.conf
sed -i 's/group\ =\ apache/group\ =\ nginx/g' /etc/php-fpm.d/www.conf
sed -i "s/upload_max_filesize = 2M/upload_max_filesize = $FILESIZE/g" /etc/php.ini
sed -i 's/opcache.max_accelerated_files=4000/opcache.max_accelerated_files=10000/g' /etc/php.d/10-opcache.ini
echo "opcache.revalidate_freq=1" >> /etc/php.d/10-opcache.ini
sed -i 's/memory_limit\ =\ 128M/memory_limit\ =\ 512M/g' /etc/php.ini

echo "env[PATH] = /usr/local/bin:/usr/bin:/bin" >> /etc/php-fpm.d/www.conf
systemctl enable nginx --now
systemctl enable mariadb --now
systemctl enable php-fpm --now
firewall-cmd --permanent --add-service=https --add-service=http
firewall-cmd --reload
chown nginx:nginx /usr/share/nginx/html -R
mkdir /etc/nginx/ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nextcloud.key -out /etc/nginx/ssl/nextcloud.crt -subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORG/OU=$ORG_UNIT/CN=$SERVERNAME"
cat << EOF >> /tmp/setup.sql
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('$MARIADBPASSWORD');
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
CREATE DATABASE $DBNAME DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER $USER@localhost IDENTIFIED BY '$APPPASSWORD';
GRANT ALL PRIVILEGES ON $DBNAME.* TO $USER@localhost;
FLUSH PRIVILEGES;
quit
EOF
mysql -u root < /tmp/setup.sql
wget https://download.nextcloud.com/server/releases/latest-17.zip
unzip latest-17.zip -d /usr/share/nginx/
chown nginx:nginx /usr/share/nginx/nextcloud/ -R
cat << EOF >> /etc/nginx/conf.d/nextcloud.conf
server {
    listen 80;
    listen 443 ssl;

    server_name $SERVERNAME;
    ssl_certificate /etc/nginx/ssl/nextcloud.crt;
    ssl_certificate_key /etc/nginx/ssl/nextcloud.key;

    # Add headers to serve security related headers
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
    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;

    #I found this header is needed on Debian/Ubuntu/CentOS/RHEL, but not on Arch Linux.
    add_header X-Frame-Options "SAMEORIGIN";

    # Path to the root of your installation
    root /usr/share/nginx/nextcloud/;

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

    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;

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

    location ~ /.well-known/acme-challenge {
      allow all;
    }

    # set max upload size
    client_max_body_size $BODY;
    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;

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

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

    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/.+|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;
       #Avoid sending the security headers twice
       fastcgi_param modHeadersAvailable true;
       fastcgi_param front_controller_active true;
       fastcgi_pass unix:/run/php-fpm/www.sock;
       fastcgi_intercept_errors on;
       fastcgi_request_buffering off;
    }

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

    # Adding the cache control header for js and css files
    # Make sure it is BELOW the PHP block
    location ~* \.(?:css|js)$ {
        try_files \$uri /index.php\$uri\$is_args\$args;
        add_header Cache-Control "public, max-age=7200";
        # Add headers to serve security related headers (It is intended to
        # have those duplicated to the ones above)
        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;
        # Optional: Don't log access to assets
        access_log off;
   }

   location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
        try_files \$uri /index.php\$uri\$is_args\$args;
        # Optional: Don't log access to other assets
        access_log off;
   }
}
EOF
systemctl reload nginx
setsebool -P httpd_execmem 1
systemctl reload php-fpm
chcon -t httpd_sys_rw_content_t /usr/share/nginx/nextcloud/ -R
setsebool -P httpd_can_network_connect 1
setfacl -R -m u:nginx:rwx /var/lib/php/opcache/
setfacl -R -m u:nginx:rwx /var/lib/php/session/
setfacl -R -m u:nginx:rwx /var/lib/php/wsdlcache/
mkdir /usr/share/nginx/nextcloud-data
chown nginx:nginx /usr/share/nginx/nextcloud-data -R
chcon -t httpd_sys_rw_content_t /usr/share/nginx/nextcloud-data/ -R
cd /usr/share/nginx/nextcloud/
sudo -u nginx php occ  maintenance:install --database "mysql" --database-name "$DBNAME"  --database-user "$USER" --database-pass "$APPPASSWORD" --admin-user "$ADMIN" --admin-pass "$ADMINPASS" --data-dir "/usr/share/nginx/nextcloud-data"
sed -i '$d' /usr/share/nginx/nextcloud/config/config.php
# I put three \\\ in the below echo file because \ needs to be escaped out.  The result is two \\
echo "  'memcache.local' => '\\\OC\\\Memcache\\\APCu'," >> /usr/share/nginx/nextcloud/config/config.php
echo ");" >> /usr/share/nginx/nextcloud/config/config.php
# For some reason, when you configure nextcloud from the command line, you need to modify trusted_domains
sed -i "s/0 => 'localhost/0 => '*/g" /usr/share/nginx/nextcloud/config/config.php
cat /root/nextcloud_admin.txt

Highlights above were added by the forum software, not me…

any chance you would give us a blow by blow for dummies? This would be amazing and ty.

https://www.centos.org/forums/viewtopic.php?t=71784

I understand GraphicsMagick replaced ImageMagick MeiRos, but installing it doesn’t seem to work with nextcloud. If you have gotten GraphicsMagick to work with nextcloud, I’d very much appreciate knowing how you got it to work.

#!/bin/sh

You MUST set the SERVERNAME here:

SERVERNAME=nextcloud.example.com

These values are used to generate a ssl certificate. You can/should replace with LetsEncrypt after the build

COUNTRY=US
STATE=California
CITY=Malibu
ORG=“Stark Industries”
ORG_UNIT=Nextcloud

This is the name of the database that will get created for nextcloud

DBNAME=nextcloud

This is the username that is needed for the nextcloud database. NOTE: This is not a nextcloud user account

USER=nextclouduser

This is the name of the nextcloud Admin user

ADMIN=admin

These values increase the limits for nextcloud:

#BODY sets the client_max_body_size in the nginx nextcloud.conf file
BODY=4096M
#FILESIZE sets the upload_max_filesize in /etc/php.ini
FILESIZE=10240M

This generates a random password for the root account of mariadb. You can change it if you wish

MARIADBPASSWORD=date +%s | sha256sum | base64 | head -c 16
sleep 1 # We need to sleep 1 to change the password, otherwise we end up with the same hash

This generates a random password for the nextcloud user account in mariadb. You can change it if you wish

APPPASSWORD=date +%s | sha256sum | base64 | head -c 16
sleep 1 # We need to sleep 1 to change the password, otherwise we end up with the same hash

This generates a random password for the admin user account password:

ADMINPASS=date +%s | sha256sum | base64 | head -c 16

This will save the values that are needed for setup and accessing mariadb in /root/mariadb.txt

echo -e “MariaDB root password is $MARIADBPASSWORD” >> /root/mariadb.txt
echo -e “App DB is $DBNAME, the Username is $USER and the password is $APPPASSWORD” >> /root/mariadb.txt

This will save the admin username and password for nextcloud

echo -e “The admin username is $ADMIN and the password is $ADMINPASS” >> /root/nextcloud_admin.txt

##########################################################################
############## NO CHANGES FROM HERE DOWN SHOULD BE REQUIRED ##############
##########################################################################

Install all of the additional rpm’s we will need:

dnf -y install nginx mariadb-server mariadb php php-mysqlnd php-fpm php-opcache php-gd php-xml php-mbstring wget unzip php-common php-gd php-json php-curl php-zip php-xml php-mbstring php-bz2 php-intl php-process apcu-panel php-pecl-apcu

since we are using nginx instead of appached, we need to change the username for php-fpm

sed -i ‘s/user\ =\ apache/user\ =\ nginx/g’ /etc/php-fpm.d/www.conf

same as above for the group name

sed -i ‘s/group\ =\ apache/group\ =\ nginx/g’ /etc/php-fpm.d/www.conf

This increases the file size that can be uploaded to whatever value you set FILESIZE= to above

sed -i “s/upload_max_filesize = 2M/upload_max_filesize = $FILESIZE/g” /etc/php.ini

nextcloud requires you to increase the opcache.max_accelerated_files value to 10000

sed -i ‘s/opcache.max_accelerated_files=4000/opcache.max_accelerated_files=10000/g’ /etc/php.d/10-opcache.ini

another change required by nextcloud

echo “opcache.revalidate_freq=1” >> /etc/php.d/10-opcache.ini

and yet another value change required

sed -i ‘s/memory_limit\ =\ 128M/memory_limit\ =\ 512M/g’ /etc/php.ini

This is necessary in order to clear a path error you will get when you check your installation

echo “env[PATH] = /usr/local/bin:/usr/bin:/bin” >> /etc/php-fpm.d/www.conf

start and set to always start the following services

systemctl enable nginx --now
systemctl enable mariadb --now
systemctl enable php-fpm --now

Add the necessary rules to your firewall and reload it

firewall-cmd --permanent --add-service=https --add-service=http
firewall-cmd --reload

Since we are running nginx, make all of the files owned by nginx

chown nginx:nginx /usr/share/nginx/html -R

Here we generate a self signed certificate using the values up top

mkdir /etc/nginx/ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nextcloud.key -out /etc/nginx/ssl/nextcloud.crt -subj “/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORG/OU=$ORG_UNIT/CN=$SERVERNAME”

This runs the same thing that you would get if you secured your mariadb installation, creates the databases needed for nextcloud, and creates the nextcloud database user account by putting everything into a file and then piping that file directly into mariadb (mysql)

cat << EOF >> /tmp/setup.sql
SET PASSWORD FOR ‘root’@‘localhost’ = PASSWORD(’$MARIADBPASSWORD’);
DELETE FROM mysql.user WHERE User=’’;
DELETE FROM mysql.user WHERE User=‘root’ AND Host NOT IN (‘localhost’, ‘127.0.0.1’, ‘::1’);
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db=‘test’ OR Db=‘test\_%’;
CREATE DATABASE $DBNAME DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER $USER@localhost IDENTIFIED BY ‘$APPPASSWORD’;
GRANT ALL PRIVILEGES ON $DBNAME.* TO $USER@localhost;
FLUSH PRIVILEGES;
quit
EOF
mysql -u root < /tmp/setup.sql

download and unzip nextcloud 17

wget https://download.nextcloud.com/server/releases/latest-17.zip
unzip latest-17.zip -d /usr/share/nginx/

make nginx own the nextcloud files

chown nginx:nginx /usr/share/nginx/nextcloud/ -R

this creates the necessary configuration file for nginx to properly serve nextcloud, along with all of the necessary entries for nextcloud to run properly

cat << EOF >> /etc/nginx/conf.d/nextcloud.conf
server {
listen 80;
listen 443 ssl;

server_name $SERVERNAME;
ssl_certificate /etc/nginx/ssl/nextcloud.crt;
ssl_certificate_key /etc/nginx/ssl/nextcloud.key;

#Add headers to serve security related headers
add_header Strict-Transport-Security “max-age=15768000; includeSubDomains; preload;”;
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;

#I found this header is needed on Debian/Ubuntu/CentOS/RHEL, but not on Arch Linux.
add_header X-Frame-Options “SAMEORIGIN”;

#Path to the root of your installation
root /usr/share/nginx/nextcloud/;

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

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;

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

location ~ /.well-known/acme-challenge {
allow all;
}

#set max upload size
client_max_body_size $BODY;
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;

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

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

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/.+|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;
#Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}

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

#Adding the cache control header for js and css files
#Make sure it is BELOW the PHP block
location ~* .(?:css|js)$ {
try_files $uri /index.php$uri$is_args$args;
add_header Cache-Control “public, max-age=7200”;
# Add headers to serve security related headers (It is intended to
# have those duplicated to the ones above)
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;
# Optional: Don’t log access to assets
access_log off;
}

location ~* .(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
try_files $uri /index.php$uri$is_args$args;
# Optional: Don’t log access to other assets
access_log off;
}
}
EOF

restart nginx with the new config

systemctl reload nginx

in order to run selinux, you need to set this boolean or things won’t work

setsebool -P httpd_execmem 1

restart php-fm

systemctl reload php-fpm

another selinux necessity. change the context so that nginx can serve the nextcloud files

chcon -t httpd_sys_rw_content_t /usr/share/nginx/nextcloud/ -R

another needed boolean (google them if you want to know what they do)

setsebool -P httpd_can_network_connect 1

Also to use selinux, you need to set the acl (access control list) of the following files/directories to nginx

setfacl -R -m u:nginx:rwx /var/lib/php/opcache/
setfacl -R -m u:nginx:rwx /var/lib/php/session/
setfacl -R -m u:nginx:rwx /var/lib/php/wsdlcache/

We don’t wan’t our data directory in the web path for security, so make one here and set the ownership and selinux context

mkdir /usr/share/nginx/nextcloud-data
chown nginx:nginx /usr/share/nginx/nextcloud-data -R
chcon -t httpd_sys_rw_content_t /usr/share/nginx/nextcloud-data/ -R

this does the nextcloud configuration from the command line instead of launching the web page and filling in all of the values since we already know what they all are

cd /usr/share/nginx/nextcloud/
sudo -u nginx php occ maintenance:install --database “mysql” --database-name “$DBNAME” --database-user “$USER” --database-pass “$APPPASSWORD” --admin-user “$ADMIN” --admin-pass “$ADMINPASS” --data-dir “/usr/share/nginx/nextcloud-data”

in order to use APCu as the memcache, you need to add the entry to the config.php, so I delete the closing ); then add the necessary entry and then put the closing ); back

sed -i ‘$d’ /usr/share/nginx/nextcloud/config/config.php
#I put three \\ in the below echo file because \ needs to be escaped out. The result is two \
echo " ‘memcache.local’ => ‘\\OC\\Memcache\\APCu’," >> /usr/share/nginx/nextcloud/config/config.php
echo “);” >> /usr/share/nginx/nextcloud/config/config.php

For some reason, when you configure nextcloud from the command line, you need to modify trusted_domains

sed -i “s/0 => 'localhost/0 => '*/g” /usr/share/nginx/nextcloud/config/config.php

finally I print out the admin username and password so you can logon to your installation

cat /root/nextcloud_admin.txt

Centminmod answered there that you can find ImageMagick from epel-testing and remi.
I don’t have CentOS 8 so I can’t test it. I just believe that’s true. I’m sorry if it’s not.

Available           Packages                
ImageMagick.x86_64  6.9.10.64-1.el8         epel-testing
ImageMagick.x86_64  1:6.9.10.65-1.el8.remi  remi
ImageMagick.x86_64  1:6.9.10.66-1.el8.remi  remi