Skip to content

Instantly share code, notes, and snippets.

@renarsvilnis
Last active December 11, 2022 21:48
Show Gist options
  • Save renarsvilnis/6ff612df9e046d45344b to your computer and use it in GitHub Desktop.
Save renarsvilnis/6ff612df9e046d45344b to your computer and use it in GitHub Desktop.
Guide for configuring server for apache, php, ssh etc..

DEV SERVER SETUP


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, not mod_fcgid

Extra configuration to run Owncloud installation suggested.

Put together by kroko, renarsvilnis


UBUNTU OS GENERAL


GET HARDWARE INFO

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.

UPDATES

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

INSTALL BUILD A.O. GENERAL TOOLS

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

SSH/SCP/SFTP INSTALL

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

LOCALE SETTING

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

SECOND NIC CONFIGURATION

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

NFS SERVER SET UP

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

NFS CLIENT SET UP

sudo apt-get update

sudo apt-get install nfs-common

MOUNT NFS ON UBUNTU

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

AUTOMOUNT NFS ON UBUNTU

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 UBUNTU NFS ON OSX

mount -t nfs -o nfsvers=2,resvport,nolocks,locallocks,intr,soft,wsize=32768,rsize=3276 5.6.7.8:/sharepath /Volumes/mountname/

SENDMAIL CONFIGURATION

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

#WEBSERVER

Apache2 install

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

apache2-mpm-prefork setup

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

apache2-mpm-itk install

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)

SSL

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.*

PHP install

sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt php5-cli php5-mysql php5-curl php5-tidy php5-gd

MySQL install

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'

PHP setup

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

Memcached install

We are installing Memcached, not Memcache!

sudo apt-get install php5-memcached memcached

sudo service apache2 restart

Zend OPCache setup

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

DEV PAGE VHOST EXAMPLE


COMMON CONFIGS

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

PER VHOST CONFIGS

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>

#Node.js

Node.js install

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

Node.js .htaccess

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>

#OWNCLOUD

Configure Ubuntu concurrent requests

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

Zend OPCache for extreme setup

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

memcached setup

set in config.php

'memcached_servers' => array(
array('127.0.0.1', 11211),
),

PHP setup

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

Libre Office install

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

crontab setup

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

Notes

we do not worry about web interface perfortmance that much actually, cloud is used via client apps

Owncloud config.php

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),
),

Owncloud vhost configuration

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

BACKUPING


Webroots dump

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.

Apache vhosts dump

Backup conf-available, sites-available and some extra files. No incremental backup.

Node.js global modules dump

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 our backup-global-modules.js helper to ~/.npm/lib/

MySQL dump for databases and users

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.

Push data to NAS using rsync over SSH

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

#VirtualBox managment

use our wvirtual helper app



RESOURCES USED

Guides

SSH

Lamp stack

NETWORK CARD

NFS

NFS AUTOMOUNT VIA AUTOFS

SENDMAIL

OWNCLOUD

Server setup guide

Guide for setting up Linux/Ubuntu server for PHP, Node.js programming

Guides

SSH

Lamp stack

# Setup apache
sudo apt-get install apache2
sudo a2enmod rewrite curl fileinfo openssl exif

# Setup php
sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt php5-cli php5-mysql php5-curl php5-tidy php5-gd

# Setup mySQL
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'

Node

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

.htaccess

Options +FollowSymLinks -Indexes -MultiViews
<IfModule mod_rewrite.c>
     RewriteEngine on

     RewriteRule ^(.*)$ http://dev.warp.lv:3001/$1 [P]
</IfModule>

Opcache

http://www.hostingadvice.com/how-to/enable-php-5-5-opcache-ubuntu-14-04/

/etc/php5/apache2/php.ini
/etc/php5/cli/php.ini
/etc/php5/apache2/conf.d/05-opcache.ini

opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.fast_shutdown=0
;opcache.max_accelerated_files=4000
;opcache.revalidate_freq=2

PHP.ini example

max_input_time = 360
post_max_size = 16G
upload_max_filesize = 16G
default_charset = "UTF-8"
memory_limit = 2048M
output_buffering = 0
date.timezone = Europe/Riga

Virtual host exmaple

File under: /etc/apache2/sites-enabled/my.domain.conf

<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName dev.warp.lv
    ServerAlias studio.warp.lv
    DirectoryIndex index.html index.php
    DocumentRoot /home/warpnode/www_dev

    <IfModule mod_setenvif.c>
        # Dev server definition
        SetEnv WARPDEV 1
    </ifmodule>

    <ifmodule mpm_itk_module>
        AssignUserID warpnode warpnode
    </ifmodule>

    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
    # error, crit, alert, emerg.
    # It is also possible to configure the loglevel for particular
    # modules, e.g.
    #LogLevel info ssl:warn

    ErrorLog /home/warpnode/logs/www_dev/error.log
    CustomLog /home/warpnode/logs/www_dev/access.log combined

    # For most configuration files from conf-available/, which are
    # enabled or disabled at a global level, it is possible to
    # include a line for only one particular virtual host. For example the
    # following line enables the CGI configuration for this host only
    # after it has been globally disabled with "a2disconf".
    #Include conf-available/serve-cgi-bin.conf

    <Directory "/home/warpnode/www_dev">
        Options -Indexes +FollowSymLinks
        AllowOverride All
        #Order allow,deny
        #Allow from all
        Require all granted

        <FilesMatch "\.(upload-config|sublime-project)$">
            Require all denied
        </FilesMatch>

    </Directory>

</VirtualHost>


<VirtualHost *:443>
    SSLEngine on
    SSLProtocol all
    SSLCertificateFile /etc/apache2/ssl/wild.warp.lv.crt
    SSLCertificateKeyFile /etc/apache2/ssl/wild.warp.lv.key
    SSLCACertificateFile /etc/apache2/ssl/wild.warp.lv-intermediate.crt

    ServerAdmin [email protected]
    ServerName dev.warp.lv
    HostnameLookups Off

    DirectoryIndex index.html index.php
    DocumentRoot /home/warpnode/www_dev

    <ifmodule mpm_itk_module>
        AssignUserID warpnode warpnode
    </ifmodule>

    ErrorLog /home/warpnode/logs/www_dev/ssl_error.log
    #CustomLog /home/warpnode/logs/www_dev/ssl_access.log combined

    <Directory "/home/warpnode/www_dev">
        Options -Indexes +FollowSymLinks
        AllowOverride All
        #Order allow,deny
        #Allow from all
        Require all granted

        <FilesMatch "\.(upload-config|sublime-project)$">
            Require all denied
        </FilesMatch>

    </Directory>
</VirtualHost>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment