I have been looking for a Debian based NC install script for a while that uses PostgreSQL instead of MySQL/MariaDB and have had no luck. I saw Onryo’s install script and really appreciated how well his script works. This gave me the idea to try and modify his script to work with PostgreSQL. I am not trying to take credit for Onryo’s work, I am just trying to make PostgreSQL work with his configuration.
Changes I made: updated OpenSSL to 1.1.0h and added DDNS client inadyn; swapped out LetsEncrypt with acme.sh; and included UFW firewall due to my needs. I attempted to update the script to include the necessary modifications for these new items.
I would love feed back on how I can improve the PostgreSQL portion of this script as I am a novice when it comes to scripting and PostgreSQL with NC.
#!/bin/sh
###############################################################################
## chmod +x nextcloud.sh && ./nextcloud.sh ##
## This script will install NextCloud on Debian 9 as follows: ##
## php-fpm using unixsocket and own fpm pool for isolation ##
## Apache2 using MPM Event (should be a least as fast as nginx) ##
## APCu for memory local cache ##
## Redis on unixsocket for memory locking cache ##
## SSL using Lets Encrypt with secure TLS defaluts. A+ Rating ##
## ModSecurity for real-time monitoring, logging, and access control ##
## ##
## By Erik Adler aka onryo erik.adler@mensa.se ##
## gpg --keyserver pgp.mit.edu --recv-keys 0x2B4B58FE ##
###############################################################################
# login user name. Change this!
nc_user='user'
# login user password. Change this!
nc_pw='password'
# local static ip. Change this!
staticip='ip'
# Enter your DuckDNS domain name
domainname='domian'
# Enter your DuckDNS token
duckDNStoken='token'
# email for vhost and cert.
email='webmaster@localhost'
# Change to version of NextCloud to download if not latest.
# latest.tar.bz2 is default
nextcloudVersion='latest.tar.bz2'
# Public gpg key used to verify NextCloud
# The key can be found at https://nextcloud.com/nextcloud.asc
# D75899B9A724937A is default
gpgKey='D75899B9A724937A'
# Path to NextCloud. Feel free to change this.
nc_home='/var/www/vhosts'
# Defaut is a random 32 char pw for NextCloud db admin user.
# A backup can be found under /root/admin_pw_backup.txt if needed.
db_admin_pw="$(tr -cd '[:alnum:]' < /dev/urandom | fold -w32 | head -n1)"
###############################################################################
[ "$(id -u)" = 0 ] || { printf 'Must be root to run script\n'; exit 1; }
hostName="$(hostname)"
## Add PostgreSQL Respository
sudo add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main"
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
## Update to openssl 1.1.0h
yes | apt purge openssl && cd /usr/local/src/
wget http://ftp.nl.debian.org/debian/pool/main/o/openssl/libssl1.1_1.1.0h-4_armhf.deb
dpkg -i ./libssl1.1_1.1.0h-4_armhf.deb
wget http://ftp.nl.debian.org/debian/pool/main/o/openssl/openssl_1.1.0h-4_armhf.deb
dpkg -i openssl_1.1.0h-4_armhf.deb
apt update && apt upgrade -y
apt install apt-transport-https lsb-release ca-certificates software-properties-common zip unzip screen curl socat ffmpeg libfile-fcntllock-perl -y
## Install inadyn
apt-get install inadyn
mv /etc/inadyn.conf /etc/inadyn.conf.bk
# Edit inadyn config file
cat >/etc/inadyn.conf<<EOF
--dyndns_server_name www.duckdns.org
--username nouser
--password $duckDNStoken
--update_period 60000
--forced_update_period 320000
--alias $domainname
--verbose 0
--dyndns_server_url /nic/?
--syslog
--background
EOF
# Add Inadyn Crontab
##insert sudo infront of the word "crontab" to insert into sudo crontab#
(crontab -l 2>/dev/null; echo "@reboot /usr/sbin/inadyn") | sort - | uniq - | crontab -
# Apache2 and PHP 7.0
apt-get install apache2 -y
apt-get install php7.0-fpm php7.0-gd php7.0-json php7.0-pgsql php7.0-curl -y
apt-get install php7.0-intl php7.0-mcrypt php7.0-imagick php7.0-xml -y
apt-get install php7.0-gmp php7.0-smbclient php7.0-ldap php7.0-imap -y
apt-get install php7.0-mbstring php7.0-bz2 php7.0-zip -y
a2enmod proxy_fcgi rewrite headers env dir mime setenvif ssl
a2enconf php7.0-fpm
systemctl reload apache2
# Media functions and preview.
apt-get install ffmpeg libreoffice -y
# Setup database
apt install postgresql-10 -y
sudo -u postgres psql <<END
CREATE USER nextcloud WITH PASSWORD '$db_admin_pw';
CREATE DATABASE nextclouddb TEMPLATE template0 ENCODING 'UNICODE';
ALTER DATABASE nextclouddb OWNER TO nextcloud;
GRANT ALL PRIVILEGES ON DATABASE nextclouddb TO nextcloud;
END
service postgresql restart
# If for some reason you feel you need a NC pw backup. Only system root can read this.
echo "$db_admin_pw" > /root/admin_pw_backup.txt
chmod 400 /root/admin_pw_backup.txt
# Set up a php-fpm pool with a unixsocket
cat >/etc/php/7.0/fpm/pool.d/nextcloud.conf<<EOF
[Next Cloud]
user = www-data
group = www-data
listen = /run/php/php7.0-fpm.nextcloud.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200
env[HOSTNAME] = $hostName
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
security.limit_extensions = .php
php_admin_value [cgi.fix_pathinfo] = 1
EOF
# Disable the idling example pool.
mv /etc/php/7.0/fpm/pool.d/www.conf /etc/php/7.0/fpm/pool.d/www.conf.backup
# Get NextCloud and verify the gpg signature. Change to the exact nc version
cd /tmp || { printf 'There is no /tmp dir\n'; exit 1; }
apt-get install dirmngr sudo -y
gpg --recv-keys "$gpgKey" || gpg --keyserver pgp.mit.edu "$gpgKey"
wget "https://download.nextcloud.com/server/releases/$nextcloudVersion"
wget "https://download.nextcloud.com/server/releases/$nextcloudVersion.asc"
gpg --verify "$nextcloudVersion.asc" "$nextcloudVersion" 2>&1 | grep \
'Good signature' || { printf 'BAD GPG SIGNATURE\n'; exit 1; }
tar xjfv "$nextcloudVersion"
mkdir -p $nc_home
mv nextcloud "$nc_home/"
chown -R www-data:www-data $nc_home/nextcloud
# Make SSL Directory
mkdir -p /etc/apache2/2.2/ssl
# Sets up the vhost
cat >/etc/apache2/sites-available/nextcloud.conf<<EOF
<VirtualHost *:80>
ServerAdmin $email
DocumentRoot $nc_home/nextcloud
ServerName $domainname
<Directory $nc_home/nextcloud/>
AllowOverride All
Options -Indexes +FollowSymlinks
<IfModule mod_dav.c>
Dav off
</IfModule>
SetEnv HOME $nc_home/nextcloud
SetEnv HTTP_HOME $nc_home/nextcloud
</Directory>
<Directory $nc_home/nextcloud/data/>
Require all denied
</Directory>
<FilesMatch \\.php$>
SetHandler "proxy:unix:/run/php/php7.0-fpm.nextcloud.sock|fcgi://localhost"
</FilesMatch>
<IfModule mod_headers.c>
Header always add Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
</IfModule>
</virtualhost>
<VirtualHost *:443>
ServerAdmin $email
DocumentRoot $nc_home/nextcloud
ServerName $domainname
<Directory $nc_home/nextcloud/>
AllowOverride All
Options -Indexes +FollowSymlinks
<IfModule mod_dav.c>
Dav off
</IfModule>
SetEnv HOME $nc_home/nextcloud
SetEnv HTTP_HOME $nc_home/nextcloud
</Directory>
<Directory $nc_home/nextcloud/data/>
Require all denied
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php7.0-fpm.nextcloud.sock|fcgi://localhost"
</FilesMatch>
SSLEngine On
SSLCertificateFile /etc/apache2/2.2/ssl/$domainname-cert.pem
SSLCertificateKeyFile /etc/apache2/2.2/ssl/$domainname-key.pem
SSLCertificateChainFile "/etc/apache2/2.2/ssl/letsencrypt.pem"
SSLCACertificatePath "/etc/apache2/2.2/ssl/"
SSLCACertificateFile "/etc/apache2/2.2/ssl/letsencrypt.pem"
<IfModule mod_headers.c>
Header always add Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
</IfModule>
ErrorLog /error.log
#CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
EOF
a2dissite 000-default
a2ensite nextcloud
systemctl reload apache2
systemctl reload php7.0-fpm.service
# Install NextCloud
cd "$nc_home/nextcloud/" || { printf 'No nextcloud dir\n'; exit 1; }
# root uses sudo -u to allow very arcain password strings.
sudo -u www-data php "$nc_home/nextcloud/occ" maintenance:install \
--database 'pgsql' --database-name 'nextclouddb' --database-user 'nextcloud' \
--database-pass "$db_admin_pw" --admin-user "$nc_user" --admin-pass "$nc_pw"
su -m www-data php -c "php $nc_home/nextcloud/occ config:system:set \
trusted_domains 0 --value=$domainname"
su -m www-data php -c "php $nc_home/nextcloud/occ config:system:set \
trusted_domains 1 --value=$staticip"
# Enable all previews
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enable_previews --value=true --type=boolean"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 0 --value='OC\\Preview\\PNG'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 1 --value='OC\\Preview\\JPEG'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 2 --value='OC\\Preview\\GIF'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 3 --value='OC\\Preview\\BMP'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 4 --value='OC\\Preview\\XBitmap'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 5 --value='OC\\Preview\\MarkDown'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 6 --value='OC\\Preview\\MP3'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 7 --value='OC\\Preview\\TXT'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 8 --value='OC\\Preview\\Illustrator'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 9 --value='OC\\Preview\\Movie'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 10 --value='OC\\Preview\\MSOffice2003'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 11 --value='OC\\Preview\\MSOffice2007'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 12 --value='OC\\Preview\\MSOfficeDoc'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 13 --value='OC\\Preview\\OpenDocument'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 14 --value='OC\\Preview\\PDF'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 15 --value='OC\\Preview\\Photoshop'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 16 --value='OC\\Preview\\Postscript'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 17 --value='OC\\Preview\\StarOffice'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 18 --value='OC\\Preview\\SVG'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 19 --value='OC\\Preview\\TIFF'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
enabledPreviewProviders 20 --value='OC\\Preview\\Font'"
## APCu for local memory cache
apt-get install php7.0-apcu -y
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
memcache.local --value='\\OC\\Memcache\\APCu'"
## Redis for distributed caching on unixsocket
apt-get install php7.0-redis redis-server -y
## Generate pw for redis connection
redis_pw="$(tr -cd '[:alnum:]' < /dev/urandom | fold -w32 | head -n1)"
sed -i "s/# requirepass foobared/requirepass ${redis_pw}/g" /etc/redis/redis.conf
sed -i 's/port 6379/port 0/g' /etc/redis/redis.conf
sed -i 's/# unixsocket/unixsocket/g' /etc/redis/redis.conf
sed -i 's/unixsocketperm 700/unixsocketperm 770/g' /etc/redis/redis.conf
usermod -a -G redis www-data
chown -R redis:www-data /var/run/redis
systemctl reload apache2
systemctl reload php7.0-fpm.service
systemctl enable redis-server
systemctl start redis-server
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
memcache.locking --value='\\OC\\Memcache\\Redis'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
filelocking.enabled --value='true' --type=boolean"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
redis host --value='/var/run/redis/redis.sock'"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
redis port --value='0' --type=integer"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
redis timeout --value='0' --type=integer"
su -m www-data -c "php $nc_home/nextcloud/occ config:system:set \
redis password --value=$redis_pw"
systemctl restart redis-server.service
# Secure with https://www.modsecurity.org/about.html
# ModSecurity is a toolkit for real-time web application monitoring, logging, and access control.
# Default is to detect only but you can enable security to be active.
apt-get install libapache2-mod-security2 modsecurity-crs -y
mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
# whitelist to get started https://paste.debian.net/989100/
cd /etc/modsecurity || { printf 'No modsecurity dir\n'; exit 1; }
wget https://paste.debian.net/plain/989100
mv 989100 whitelist.conf
# Do not enable the next line unless you know what you are doing. This will enable active defence.
# sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine on/g' /etc/modsecurity/modsecurity.conf
# You can monitor tail -f /var/log/apache2/modsec_audit.log
systemctl reload apache2
## Back-Up opcache.ini
mv /etc/php/7.0/mods-available/opcache.ini /etc/php/7.0/mods-available/opcache.ini.bk
## Modify PHP opcache.ini
cat >/etc/php/7.0/mods-available/opcache.ini<<EOF
; configuration for php opcache module
; priority=10
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.memory_consumption=256
opcache.save_comments=1
opcache.revalidate_freq=1
EOF
## Install and configure UFW
yes | apt install ufw
ufw allow 80/tcp && ufw allow 443/tcp && ufw allow 22/tcp && ufw logging medium
yes | ufw default deny incoming && yes | ufw enable && service ufw restart
##Clean-up packages not needed
sudo apt autoremove -y
## Install acme.sh
wget -O - https://get.acme.sh | sh
export DuckDNS_Token="$duckDNStoken"