A reference for setting up Linux/Ubuntu server for LAMP, Node.js laboratory.
May be helpful for others, hence this git. If it contains errors, please push them.
This assumes
- modern hardware you have total control of
- running Ubuntu Server 14.04.2 LTS
- running apache, no nginx proxy
- running PHP as
mod_php5
, notmod_fcgid
Extra configuration to run Owncloud installation suggested.
Put together by kroko, renarsvilnis
Get RAM
grep MemTotal /proc/meminfo
Get CPU info
cat /proc/cpuinfo
Get MOBO info
sudo dmidecode -t 2
Get HDD info
sudo hdparm -I /dev/sda
No hardware monitoring is done. We are lazy. Everything is backuped. And backuped again.
always stay up to date. always update before installing something via apt-get.
lsb_release -a
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
We build things from source, not everything is through packages.
sudo apt-get install build-essential openssl libssl-dev
Throw pkg-config in the mix
sudo apt-get install pkg-config
git
sudo apt-get install git
Enable SSH server
sudo apt-get install openssh-server
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.factory-defaults
sudo chmod a-w /etc/ssh/sshd_config.factory-defaults
sudo nano /etc/ssh/sshd_config
Port 22 #change to different port if needed
PermitRootLogin no #altertnatively without-password
StrictModes yes
PasswordAuthentication yes #better no, only key auth allowed
sudo service ssh restart
Just get rid some of warnings down the line.
- apache warnings about locale not set
- sendmail cries
- scss has compile errors
list locales installed
locale -a
if en_US.utf8 locale not installed, do all en installation (or whatever locale you want)
sudo apt-get install language-support-en anguage-pack-en language-pack-en-base manpages
generate
sudo locale-gen en_US en_US.UTF-8
sudo dpkg-reconfigure locales
edit global locale (~/.pam_environment
for user specific overrides, for older Ubuntu versions global setting had to be put in /etc/environment
)
sudo nano /etc/default/locale
LANG="en_US.UTF-8"
LANGUAGE="en_US:en"
# as we set LC_ALL then all LC_* settings are overriden, C was the default for LC_* settings
LC_ALL="en_US.UTF-8"
log out/in to apply
As this webserver runs on desktop mobo it got second NIC via PCIe - Intel EXPI9301CTBLK
We want webservers second NIC to connect directly to our NAS boxes 2nd NIC.
Let us assume that primary NIC is in class C network 192.168.1.0/24, 255.255.255.0.
ls /sys/class/net
ip addr
sudo apt-get update
sudo apt-get install nfs-kernel-server
sudo nano /etc/exports
# allow mounting from anywhere
#/home *(rw,async,insecure,all_squash,no_subtree_check,anonuid=1001,anongid=1001)
#allow mounting only from our class C network
/home 192.168.48.0/24(rw,async,insecure,all_squash,no_subtree_check,anonuid=1001,anongid=1001)
sudo exportfs -a
sudo service rpcbind restart && sudo service nfs-kernel-server restart
second check which ports are used (NFS uses 2049)
rpcinfo -p | grep nfs
sudo apt-get update
sudo apt-get install nfs-common
mounting assumes that UID and GID is the same on server (FreeBSD) and client (Ubuntu). this is desirable for our case. otherwise share directory on server that has been chowned to nobody:nogroup / use no_root_squash
getting ID and GID on Ubuntu
id
- create group on FreeBSD with GID same as Ubuntu
- create user on FreeBSD with UID same as Ubuntu, add to GID
- or vice versa, create new user in Ubuntu
we are using NFS to mount cloud storage, so the UID and GID is actually the apache user that serves cloud vhost using mpm_itk_module
create some subfolder in where Ubuntu user can r/w, set permissions
mount share in Ubuntu
sudo mount -t nfs -o proto=tcp,port=2049 1.2.3.4.:/dir/on/server /dir/on/client/
-t nfs4
can be used
list all currently mounted shares
mount -t nfs
to unmount
sudo umount /mnt/nfs/home
sudo nano /etc/fstab
#add
1.2.3.4:/home /mnt/nfs/home nfs auto,noatime,nolock,bg,nfsvers=4,intr,tcp,actimeo=1800 0 0
1.2.3.4:/var/nfs /mnt/nfs/var/nfs nfs auto,noatime,nolock,bg,nfsvers=4,sec=krb5p,intr,tcp,actimeo=1800 0 0
Or use Autofs
mount -t nfs -o nfsvers=2,resvport,nolocks,locallocks,intr,soft,wsize=32768,rsize=3276 5.6.7.8:/sharepath /Volumes/mountname/
sudo nano /etc/hosts
#minimum
#127.0.0.1 localhost
#correct for mail
127.0.0.1 localhost localhost.localdomain warp-server-01.warp.lv warp-server-01
sudo nano /etc/hostname
#correct for mail
warp-server-01
check resolv.conf, should hold our local nameserver
tail /etc/resolv.conf
configure sendmail.mc if needed
sudo nano /etc/mail/sendmail.mc
#possible to add, but whatever
#define(`confDOMAIN_NAME', `warp-server-01')dnl
restart sendmail
sudo service sendmail restart
reboot needed
sudo reboot
check hostname
/bin/hostname --fqdn
test the sendmail by sending mail with this one liner
echo "Subject: Sendmail test" | /usr/sbin/sendmail [email protected]
senmail related files
- /etc/mail/sendmail.conf
- /etc/cron.d/sendmail
- /etc/mail/sendmail.mc
- /etc/mail/sendmail.cf
sudo apt-get install apache2
sudo a2enmod rewrite setenvif headers mime autoindex deflate filter expires include socache_shmcb ssl
enable modules
- rewrite
- setenvif
- headers
- mime
- autoindex
- deflate
- filter
- expires
- include
- socache_shmcb
- ssl
TL;DR we use mod_php. thus we will use prefork, not worker. well, it needs more memory, but we have plenty of it. whatever. and we use mpm-itk which also dictates this.
Apache2 comes with two MPMs: Prefork and Worker. Prefork MPM which is the default MPM, and probably the one you're using is considered to be thread safe. It uses multiple child processes with one thread each handling one connection at a time. Worker MPM the one we`re interested in, uses many child processes with many threads each, handling one connection at a time. The big deal about Worker MPM is that it uses significantly less memory which is great for high traffic websites, so if all apache libraries you’re using are thread safe(for example mod_php is not) it is probably a good idea to switch from Prefork to Worker.
Apache 2.x supports pluggable concurrency models called Multi-Processing Modules (MPMs). When building Apache, you must choose MPM. Two of the important MPMs are Worker MPM and Prefork MPM. Worker MPM uses multiple child processes, each with multiple threads. Each thread handles one connection at a time. Worker is generally a good choice for high-traffic servers because it has smaller memory footprint than Prefork MPM. Prefork MPM uses multiple child processes with one thread each. Each process handles one connection at a time. Prefork is comparable in speed to worker, but it uses more memory. Prefork's threadless design can be used with non-thread-safe third-party modules and it is easier to debug on platforms with poor thread debugging support.
enable prefork
sudo a2enmod mpm_prefork
With the prefork MPM, it is recommended to set 'KeepAlive' to ‘Off’, a client will tie up an entire process for that span of time, however it is more useful to simply set the 'KeepAliveTimeout' value to something low
Our server has 32GB RAM. Lets consider giving 8GB to Apache.
Apache should be configured that the maximum number of processes allowed x RAM used by one Apache process
is lower than the amount of RAM, we don't want the system to swap and drop performance.
issuing ps -ylC apache2 --sort:rss
gives us, that RSS is ~9k kB in idle mode. use warpstress helper to hit the server hard and check it! we can reach 30MB easily thus ~8000MB/~30MB = 266. Let us use default 256 for now.
the thing that will eat all these connections is cloud. we could use mod_bw, mod_vhost_limit, but in our case not needed.
create warp-global-prefork.conf
in conf-available
configure it
ServerName warp-server-01
###############################
# Keep Alive
KeepAlive On
KeepAliveTimeout 2
MaxKeepAliveRequests 100
###############################
# Prefork
<IfModule prefork.c>
# start with 4 servers
StartServers 4
# at least 2 idle at any given time
MinSpareServers 2
# no more than 10 idle
MaxSpareServers 10
# set the same as MaxClients
ServerLimit 256
#for prefork 256 is default
MaxClients 256
#don't set to 0, we want some cleanups
MaxRequestsPerChild 4000
</IfModule>
###############################
# Speedup general
<IfModule mod_status.c>
ExtendedStatus Off
</IfModule>
enable it
sudo a2enconf warp-global-prefork
sudo apt-get install apache2-mpm-itk
sudo a2enmod mpm_itk
this will enable mpm_prefork if it is not enabled (but it should be already)
recheck if SSL has been enabled
apache2ctl -M | grep ssl
if not, enable
sudo a2enmod ssl
this will also enable modules ssl depends on (if not enabled)
- setenvif
- mime
- socache_shmcb
copy all keys files (3) somewhere on server, chown to root, set permissions
sudo chmod 400 /etc/apache2/ssl/wild.warp.*
sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt php5-cli php5-mysql php5-curl php5-tidy php5-gd
sudo apt-get install mysql-server
sudo mysql_install_db
sudo mysql_secure_installation
To add additional mySQL users
/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h username password 'new-password'
change as follows. keep post_max_size and stuff like that to default as we expect them to be such in deployment environments.
if a project needs change in those, then set those in projects .htaccess top using php_value directive. afterwards we will negotiate with deployment hosting for them to allow htaccess overrides or custom config vhost
- /etc/php5/apache2/php.ini
- /etc/php5/cli/php.ini
default_charset = "UTF-8"
memory_limit = 1024M
date.timezone = Europe/Riga
We are installing Memcached, not Memcache!
sudo apt-get install php5-memcached memcached
sudo service apache2 restart
it is built in as of PHP 5.5+, so just enable it
sudo php5enmod opcache
we do not edit default files for this
- /etc/php5/apache2/php.ini
- /etc/php5/cli/php.ini
but the enabled file
sudo nano /etc/php5/apache2/conf.d/05-opcache.ini
; configuration for php ZendOpcache module
; priority=05
zend_extension=opcache.so
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
note, that this is default suggested configuration as per https://github.com/zendtech/ZendOptimizerPlus, our configuration foe owncloud extremes will differ
We will resue configurations along vhosts. However, as every vhost is special no not overdo it. Do not enable these configurations globally!
create warp-common-ssl.conf
in conf-available
this SSL configuration will not work on IE older than IE8. RC4 is disabled.
###############################
# SSL
SSLEngine on
SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
SSLCertificateFile /path/to/certfile.crt
SSLCertificateKeyFile /path/to/keyfile.key
#for apache <2.4.8
SSLCertificateChainFile /path/to/chain-intermediate-file.crt
#for apache 2.4.8+
#SSLCACertificatePath /path/to/chain-intermediate-file.crt
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [7-9]" ssl-unclean-shutdown
sudo nano /etc/apache2/sites-available/sub.host.tld.conf
use a2ensite sub.host.tld
to enable
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName sub.host.tld
ServerAlias sub2.host.tld
DirectoryIndex index.html index.php
DocumentRoot /path/to/webroot
<IfModule mod_setenvif.c>
SetEnv WARPDEV 1
</ifmodule>
###############################
# UID GID
<ifmodule mpm_itk_module>
AssignUserID ourusername ourusergroup
</ifmodule>
###############################
# LOGS
ErrorLog /path/to/logs/vhots/error.log
CustomLog /path/to/logs/vhots/access.log combined
###############################
# COMMON CONFS
# globally disable custom conf with a2disconf, enable per vhost
#Include conf-available/common-warp-1.conf
###############################
# DIRECTORY
<Directory "/path/to/webroot">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
<FilesMatch "\.(upload-config|sublime-project)$">
Require all denied
</FilesMatch>
</Directory>
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin [email protected]
ServerName sub.host.tld
ServerAlias sub2.host.tld
DirectoryIndex index.html index.php
DocumentRoot /path/to/webroot
<IfModule mod_setenvif.c>
SetEnv WARPDEV 1
</ifmodule>
###############################
# UID GID
<ifmodule mpm_itk_module>
AssignUserID ourusername ourusergroup
</ifmodule>
###############################
# LOGS
ErrorLog /path/to/logs/vhots/ssl_error.log
CustomLog /path/to/logs/vhots/ssl_access.log combined
###############################
# COMMON CONFS
# globally disable custom conf with a2disconf, enable per vhost
Include conf-available/warp-common-ssl.conf
###############################
# DIRECTORY
<Directory "/path/to/webroot">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
<FilesMatch "\.(upload-config|sublime-project)$">
Require all denied
</FilesMatch>
</Directory>
</VirtualHost>
</ifmodule>
This is easy way
curl -sL https://deb.nodesource.com/setup | sudo bash -
sudo apt-get install -y nodejs
sudo install -g n
sudo npm update -g
n latest
Let us build it ourselves so we have total control over it
We want node global modules to be user global, not computer global!
We will follow the recent cannonical way and put stuff in ~/.local
. And set that npm install -g
will put stuff under user dir ~/.npm
. We can forget about sudo in the future.
add npm conf entry to .npmrc conf
nano ~/.npmrc
prefix = ~/.npm
add path to ~/.local/bin
. and also ~/.nmp/bin
, as some modules have executables, i.e., gulp/grunt
echo 'PATH=$PATH:$HOME/.local/bin:$HOME/.npm/bin' >> $HOME/.bashrc
source ~/.bashrc
could add this to .profile, not .bashrc
make apache node aware
sudo nano /etc/apache2/envvars
#export PATH=$PATH:$HOME/.local/bin:$HOME/.npm/bin
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/warpnode/.local/bin:/home/warpnode/.npm/bin"
do the installation under ~/.local/
we use v0.13.0-pre, use v0.12.0-release for stable
mkdir -p ~/.local/src
cd ~/.local/src
git clone git://github.com/joyent/node.git
cd node
git checkout v0.12.0-release
./configure --prefix=$HOME/.local
make
make install
using
netstat -lntu
monitor the ports already used, when starting node apps
all test node projects go inside real dirs in node and/or lamp vhosts, so that paths are logical. in development use apache as simple port 80 forwarder so we do not need to remember ports. in deploy route 80 port (do not run as root).
Options +FollowSymLinks -Indexes -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.*)$ http://host.tld:NODEAPPPORT/$1 [P]
</IfModule>
Configuration for more concurrent requests
su
echo "2048 64512" > /proc/sys/net/ipv4/ip_local_port_range
echo "1" > /proc/sys/net/ipv4/tcp_tw_recycle
echo "1" > /proc/sys/net/ipv4/tcp_tw_reuse
echo "10" > /proc/sys/net/ipv4/tcp_fin_timeout
echo "65535" > /proc/sys/net/core/somaxconn
echo "65536" > /proc/sys/net/ipv4/tcp_max_syn_backlog
#conntrack may not be loaded if no iptables set
#echo "262144" > /proc/sys/net/netfilter/nf_conntrack_max
note: somaxconn fuckup
check the values
cat /proc/sys/net/ipv4/ip_local_port_range
cat /proc/sys/net/ipv4/tcp_tw_recycle
cat /proc/sys/net/ipv4/tcp_tw_reuse
cat /proc/sys/net/ipv4/tcp_fin_timeout
cat /proc/sys/net/core/somaxconn
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
#cat /proc/sys/net/netfilter/nf_conntrack_max
write them across reboots
sudo nano /etc/sysctl.conf
net.ipv4.ip_local_port_range = 2048 64512
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65536
net.netfilter.nf_conntrack_max = 262144
sudo reboot
###SSL
- We run Owncloud with forced SSL (actually, we use SSL everywhere, also when not needed :))
- We have CPU with AES-NI instruction set
- We configured SSL cipher with cipher order honoring and we we favor AES over everything else
openssl version -a
should return >=1.0.1
bingo, we have hardware accelerated HTTPS for our cloud
###RAM DISK
no RAM disk. OS, owncloud webroot, sessions, DB are on SSD (~40x lower than RAM disk). all scripts are cached via opcache. it should be enough. and we need RAM for virtualboxes. opinion may change.
###SWAP
we use default partition layout, so swap is quite big. we do not hybernate. so let's set swappiness to zero.
echo -e "vm.swappiness=0" | sudo tee -a /etc/sysctl.conf
###ACCESS TIME LOGS
although SSD, do not disable access time logging sudo nano /etc/fstab === errors=remount-ro --> noatime,errors=remount-ro
- remember, our owncloud files are not on the server, but FreeNAS box via dedicated NIC and NFS!
- owncloud needs(?) them
###SOFT AND HARD LIMITS
if i remeber correctly, default is 1024, set it to 4096
su
ulimit -a
nano /etc/security/limits.conf
use user that owncloud apache process will run with (use root for root, * for all users)
owncloudapacheusername soft nofile 4096
owncloudapacheusername hard nofile 4096
nano /etc/pam.d/common-session
session required pam_limits.so
reboot
our settings because of owncloud will differ
note the super high revalidate_freq. owncloud is static!
all development sites are in blacklist, we do not want cache there
check if /etc/php5/apache2/opcache-blacklist.txt
exists and edit it correctly
opcache.enable=1 ;default 1
opcache.enable_cli=1 ;default 0
opcache.memory_consumption=256 ;default 64, this is in MB
opcache.interned_strings_buffer=8 ;default 4, this is in MB
opcache.max_accelerated_files=4000 ;default 2000
opcache.max_wasted_percentage=5 ;default 5
opcache.use_cwd=1 ;default 1, multiple php apps on server, so we set it to 1
opcache.validate_timestamps=1 ;default 1
opcache.revalidate_freq=240 ;default 2, !!!60 seconds suggested, !!!we set it so high because of owncloud
opcache.file_update_protection=6 ;default 2
opcache.revalidate_path=0 ;default 0
opcache.save_comments=1 ;default 1, keep PHPDoc
opcache.load_comments=1 ;default 1
opcache.fast_shutdown=1 ;default 0, lets hope ZEMM cleans this
opcache.enable_file_override=0 ;default 0
opcache.optimization_level=0xffffffff ;default 0xffffffff
opcache.inherited_hack=1 ;default , In php-5.3 and above this hack is not neede$
opcache.dups_fix=0 ;default 0
opcache.blacklist_filename=/etc/php5/apache2/opcache-blacklist.txt
opcache.max_file_size=0 ;default 0, allow all file sizes to be cached, we do ha$
opcache.consistency_checks=0 ;default 0, no super checksumming needed
opcache.force_restart_timeout=7200 ;default 180 seconds, lets invalidate cache if 2 hours no cache access activity recorded
;opcache.error_log= ;default empty, all to stderr
opcache.log_verbosity_level=2 ;default 1
;opcache.preferred_memory_model
opcache.protect_memory=0 ;default 0
;opcache.restrict_api= ;default empty, api allowed everywhere
set in config.php
'memcached_servers' => array(
array('127.0.0.1', 11211),
),
default PHP ini values we are about to change
max_input_time 60
post_max_size 8M
upload_max_filesize 2M
memory_limit 128M
output_buffering 4096
default_charset ""
realpath_cache_size 16K
max_execution_time 30
max_file_uploads 20
default_socket_timeout 60
session.gc_maxlifetime = 1440
override in owncloud .htaccess as follows (or better put this in owncloud vhost and wipe htaccess so it does not overwrite)
#existing values in htaccess that we need to change
php_value upload_max_filesize 16G
php_value post_max_size 16G
php_value memory_limit 1024M
php_value mbstring.func_overload 0
php_value always_populate_raw_post_data -1
#WARP ADDITIONS
php_value max_input_time 360
php_value upload_max_filesize 16G
#php_value default_charset "UTF-8"
php_value output_buffering 0
php_value realpath_cache_size 16M
php_value max_execution_time 3600
php_value max_file_uploads 100
php_value default_socket_timeout 3600
php_value session.gc_maxlifetime 86400
#php_value date.timezone = Europe/Riga
sudo apt-get libreoffice-common
needs base as common does not include java, oh well
sudo apt get libreoffice-base
this is a manual test to export doc as pdf, output in tmp
/usr/bin/libreoffice --headless --nologo --nofirststartwizard --invisible --norestore --convert-to pdf --outdir /tmp /path/to/cloud/datadir/clouduser/files/whateverdir/example.doc
if web later does not respond, then just check if the process is not hung
ps ax | grep libre
sudo killall /usr/lib/libreoffice/program/soffice.bin
Every 15 min we need to call cron.php and pass output to dev null
*/15 * * * * /usr/bin/php -f /path/to/owncloud/webroot/cron.php /dev/null 2>&1
we do not worry about web interface perfortmance that much actually, cloud is used via client apps
enable only after all the dependencies are installed!
'forcessl' => true,
'forceSSLforSubdomains' => true,
'enable_previews' => true,
'preview_max_x' => NULL,
'preview_max_y' => NULL,
'preview_max_scale_factor' => 10,
'preview_libreoffice_path' => '/usr/bin/libreoffice',
'preview_office_cl_parameters' => ' --headless --nologo --nofirststartwizard --invisible --norestore --convert-to pdf --outdir ',
'theme' => '',
'maintenance' => false,
'memcached_servers' => array(
array('localhost', 11211),
),
shoud have these changes/additions
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName sub.host.tld
ServerAlias sub2.host.tld
DirectoryIndex index.php
DocumentRoot /path/to/webroot
###############################
# UID GID
<ifmodule mpm_itk_module>
AssignUserID ourusername ourusergroup
</ifmodule>
###############################
# Speedup Owncloud
HostnameLookups Off
###############################
#Keep alive Owncloud
KeepAlive On
#put this up
KeepAliveTimeout 10
#make it mad
MaxKeepAliveRequests 4096
###############################
# LOGS
#only error log
ErrorLog /path/to/logs/vhots/error.log
###############################
# COMMON CONFS
# globally disable custom conf with a2disconf, enable per vhost
#Include conf-available/common-warp-1.conf
###############################
# DIRECTORY
<Directory "/path/to/webroot">
#Multiviews may cause problems with content negotiation in owncloud, disable it
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
Satisfy any
#disable apache DAV module for owncloud as it uses it's own and they collide
<IfModule mod_dav.c>
Dav off
</IfModule>
</Directory>
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin [email protected]
ServerName sub.host.tld
ServerAlias sub2.host.tld
DirectoryIndex index.php
DocumentRoot /path/to/webroot
###############################
# UID GID
<ifmodule mpm_itk_module>
AssignUserID ourusername ourusergroup
</ifmodule>
###############################
# Speedup Owncloud
HostnameLookups Off
###############################
#Keep alive Owncloud
KeepAlive On
#put this up
KeepAliveTimeout 10
#make it mad
MaxKeepAliveRequests 4096
###############################
# LOGS
#only error log
ErrorLog /path/to/logs/vhots/ssl_error.log
###############################
# COMMON CONFS
# globally disable custom conf with a2disconf, enable per vhost
Include conf-available/warp-common-ssl.conf
###############################
# DIRECTORY
<Directory "/path/to/webroot">
#Multiviews may cause problems with content negotiation in owncloud, disable it
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
#disable apache DAV module for owncloud as it uses it's own and they collide
<IfModule mod_dav.c>
Dav off
</IfModule>
</Directory>
</VirtualHost>
</ifmodule>
###MOUNT OWNCLOUD DATA DIR FROM NAS (FreeBSD)
- recheck that FreeBSD UID and GID is same as apache users UID and GID
- recheck directory permissions in FreeBSD
- move cloud data dir from Ubuntu into FreeBSD mount on Ubuntu
- make symlink to mounted data dir on Ubuntu, symlik resides where owncloud data dir path is specified in config.php
'datadirectory' => '/path/to/data/dir',
ln -s /path/to/mounted/data /path/to/datadirectory
Backup webroots "as is" to NAS. No incremental backup, all project versioning and rollbacks is done using git. And we have ZFS snapshotting on NAS.
Backup conf-available, sites-available and some extra files. No incremental backup.
No incremental backup.
- We are not interested in per project modules, as they are managed per project via
package.json
and can be recreated in no-time - Backup all global node module config as
package.json
using ourbackup-global-modules.js
helper to~/.npm/lib/
create a seperate user for this, allow connection from localhost, these privileges should be enough for the task
CREATE USER 'mybackupuser'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT, RELOAD, SHOW DATABASES, LOCK TABLES ON *.* TO 'mybackupuser'@'localhost';
FLUSH PRIVILEGES;
install automysqlbackup
sudo apt-get install automysqlbackup
first create a script that will take care of cleaning too old backups
sudo nano /usr/sbin/automysqlbackup-cleanup
#!/bin/bash
#delete files older than 120 days
find /var/lib/automysqlbackup/* -mtime +120 -exec rm {} \;
sudo chmod a+x /usr/sbin/automysqlbackup-cleanup
edit automysqlbackup configuration
sudo nano /etc/default/automysqlbackup
USERNAME="mybackupuser"
PASSWORD="password"
#remove "grep -v ^mysql$ | " from DBNAMES as we want mysql db backup also for usersbackups
MAILCONTENT=="quiet"
MAILADDR="[email protected]"
BACKUPDIR="/var/lib/automysqlbackup"
LATEST=yes
POSTBACKUP="/usr/sbin/automysqlbackup-cleanup"
make it more secure, as we have password in it
sudo chmod 600 /etc/default/automysqlbackup
by default
- daily folder will contain all of the last seven days
- the weekly folder will contain the databases as it was on Sunday each of the last fifty-two weeks
- monthly will contain the end of all each of the last twelve months
- latest will contain copy of the latest dump
however this will never happen as we delete stuff more than 120 days old
issue
sudo automysqlbackup
to check if it works
ls -la /var/lib/automysqlbackup/latest
should contain your databases
now crontab it for superuser to run every night at 4 o'clock
sudo crontab -e
0 4 * * * /usr/sbin/automysqlbackup
alternatively we could do this without super user. although we do not have a big multiuser setup, this is closed server, all users are trusted, superusering layers responsibilities.
my take on autobackuping this way versus mysqldump. at first mysqldump seems to have the advantage of having all databases in in one sql for restore mysqldump --all-databases
, but
- seperate backup for each database given by automysqlbackup is not only for backup, but a restore in case of simple fuckup.
- for automysqlbackup we have LATEST=yes, so we have a seperate directory of all the databases sqls, in one level. simple
for each databasefile in latestdatabases
mysql -u root -p < databasefile
restores all the databases.
we could backup databases in so many ways and combinations, autobackuping gives a reasonable ultimate restore in case of total server error as well as per database restore in case of some coding error.
We use rsync over SSH, not mounting NAS via NFS to dedicated dataset. We do not have to worry about permissions. Slower, has overhead, whatever. Connecting SSH with special key created only for this. The backuping, crontabing is done via root user. The dataset on NAS has snapshotting, thus some extra rollback possible.
Tasks
- rsync webroots
- rsync mysql dumps located at
/var/lib/automysqlbackup/
- rsync apache configuration
- rsync node (user) global configuration
~/.npm/lib/package.json
create a new special key for this on Ubuntu and save it with custom name, i.e., my_special_id_rsa_for_backup_dest
su
ssh-keygen -t rsa
add this key pair public key to NAS authorized_keys. when connecting to NAS, specify this key explicitly.
mkdir /root/backupscripts
nano /root/backupscripts/push-all-to-nas.sh
#!/bin/bash
# push to nas
/usr/bin/rsync -az -e "/usr/bin/ssh -p NASSSHPORT -i /root/.ssh/my_special_id_rsa_for_backup_dest" /path/to/local/dir1 [email protected]:/path/to/nas/serverbackupdir/dir1
/usr/bin/rsync -az -e "/usr/bin/ssh -p NASSSHPORT -i /root/.ssh/my_special_id_rsa_for_backup_dest" /path/to/local/dirN [email protected]:/path/to/nas/serverbackupdir/dirN
excludes like --exclude=".DS_Store" --exclude="._.DS_Store"
can be set
chmod a+x /root/backupscripts/push-all-to-nas.sh
run every night at 5 o'clock
sudo crontab -e
0 5 * * * /bin/bash /root/backupscripts/push-all-to-nas.sh
use our wvirtual helper app
- https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04
- https://www.digitalocean.com/community/tutorials/additional-recommended-steps-for-new-ubuntu-14-04-servers
- https://help.ubuntu.com/10.04/serverguide/openssh-server.html
- https://help.ubuntu.com/community/SSH/OpenSSH/Configuring
- https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04
- https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2
- http://www.thegeekstuff.com/2011/05/openssh-options/
- https://help.ubuntu.com/community/NetworkConfigurationCommandLine/Automatic#Configuring_an_interface
- http://ubuntuforums.org/showthread.php?t=1329433
- http://ubuntuforums.org/showthread.php?t=1508791
- http://ubuntuforums.org/showthread.php?t=1802563
- http://ubuntuforums.org/showthread.php?t=2158184
- http://ubuntuforums.org/showthread.php?t=2072970
- https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nfs-mount-on-ubuntu-14-04
- https://theredblacktree.wordpress.com/2013/02/16/nfs-shares-between-ubuntu-12-04-and-mac-osx-10-8/