These are some notes on infrastructure & deployment.
- Rails Stack
- Deployment
- VPN
- Monit
- Munin
- Mongodb
- Redis
- God
- Servers
Locally:
cap deploy:ownership -s user=admin
cap deploy:setup
Verify & tweak yaml configs, Aloha, etc (most of which were generated by socialist) in /var/www/dashboard.app/shared
.
cap deploy
Remotely:
Install any misc dependencies the app might have for the app environment to load, or dev headers for gems with c extensions:
sudo apt-get install libxml2-dev libxslt-dev
sudo gem install nokogiri
cd /var/www/dashboard.app/current
rake db:setup RAILS_ENV=production
Setup Apache:
cap apache:config apache:enable apache:restart
Done!
ssh root@fiona
Get rid of that obnoxious motd.
echo '' > /etc/motd
Set the hostname
echo 'fiona' > /etc/hostname
/etc/init.d/hostname.sh start
Update and install some essentials.
aptitude update
aptitude upgrade
aptitude install build-essential zlib1g-dev libssl-dev git-core curl
mkdir /usr/local/src && cd /usr/local/src
curl -LO http://rubyforge.org/frs/download.php/64479/ruby-enterprise_1.8.7-20090928_i386.deb
dpkg -i ruby-enterprise_1.8.7-20090928_i386.deb
curl http://sysoev.ru/nginx/nginx-0.7.62.tar.gz | tar xvz
gem install passenger
passenger-install-nginx-module
Prompts:
"Automatically download and install Nginx?": 2 "Where is your Nginx source code located?": /root/src/nginx-0.7.62 "Where do you want to install Nginx to?": /usr/local/nginx "Extra Nginx configure options": --sbin-path=/usr/local/sbin --with-http_ssl_module
curl http://gist.github.com/raw/213678/789a5a71bbddf065e68aabc4c7d13c80059994f2/nginx > /etc/init.d/nginx
chmod +x /etc/init.d/nginx
update-rc.d -f nginx defaults
curl http://gist.github.com/raw/213678/19c4dc655ac196222652bebd6be6b017f29dcc6a/nginx.conf > /usr/local/nginx/conf/nginx.conf
/etc/init.d/nginx start
adduser ci
adduser ci admin
exit
ssh ci@fiona
curl http://gist.github.com/raw/97747/2378011069e8655dd71187f1c94c32bdb3151569/gistfile1.txt > .gemrc
echo 'set nocompatible' > .vimrc
sudo vi /etc/nginx/integrity.conf
server { listen 80; server_name ci.grays.im; root /home/ci/integrity/public; passenger_enabled on; }
sudo aptitude install sqlite3 libsqlite3-dev
gem install integrity
sudo gem install do_sqlite3 --version=0.9.11
sudo gem uninstall data_objects --version=0.9.12
integrity install ~/integrity
cd integrity
vi config.yml
:base_uri: http://ci.grays.im :database_uri: sqlite3:///home/ci/integrity/integrity.db :export_directory: /home/ci/integrity/builds :log: /home/ci/integrity/log/integrity.log :build_all_commits: true :use_basic_auth: true :admin_username: '' :admin_password: f7d225c0fd69b47618aa410226f8c22a091cbc78 :hash_admin_password: true
integrity migrate_db config.yml
mkdir public
sudo /etc/init.d/nginx reload
cd /usr/local/src
sudo git clone git://github.com/defunkt/rip.git
cd rip
sudo ruby setup.rb
sudo chown -R ci:ci ~/.rip
sudo -i
cd /usr/local/src
aptitude install tcl8.4 tk8.4
curl http://kernel.org/pub/software/scm/git/git-1.6.5.1.tar.gz | tar zxv
cd git-1.6.5.1/
./configure
make
make install
(for mysql gem)
sudo aptitude install libmysqlclient-dev mysql-client mysql-server
(for image_science)
sudo aptitude install libfreeimage-dev
(for nokogiri)
sudo aptitude install libxml2-dev libxslt1-dev
sudo apt-get install ufw
sudo ufw default deny
sudo ufw allow http/tcp
sudo ufw allow https/tcp
sudo ufw allow from 10.42.0.0/24
sudo ufw enable
sudo ufw status verbose
Unfortunately, this negates the client certificate authentication. So we're not going with it.
cd /usr/local/sbin
sudo curl -O http://gist.github.com/raw/255249/52d2756f767006e52409d2bf4583c0ab9fb2adc7/auth-aloha.rb
sudo chmod +x auth-aloha.rb
sudo vi /etc/openvpn/server.conf
Add:
auth-user-pass-verify /usr/local/sbin/auth-aloha.rb via-file client-cert-not-required tmp-dir /dev/shm
sudo /etc/init.d/openvpn restart
sudo apt-get install bind9 dnsutils
sudo vi /etc/bind/named.conf.local
zone "grays.local" { type master; file "/etc/bind/db.grays.local"; }; zone "0.42.10.in-addr.arpa" { type master; file "/etc/bind/rev.0.42.10.in-addr.arpa"; };
sudo vi /etc/bind/db.grays.local
$TTL 604800 @ IN SOA ns.grays.local. admin.grays.local. ( 1 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS ns.grays.local. @ IN A 10.42.0.1 fiona IN A 10.42.0.1
sudo vi /etc/bind/rev.0.42.10.in-addr.arpa
$TTL 604800 @ IN SOA ns.grays.local. admin.grays.local. ( 1 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS ns. 1 IN PTR ns.grays.local.
sudo /etc/init.d/bind9 restart
vi /etc/resolv.conf
search grays.local members.linode.com nameserver 10.42.0.1 nameserver 75.127.97.6 nameserver 75.127.97.7
We're not actually doing this. I couldn't get it work without jumping through hoops on the clients. Intead, just manually configure 10.42.0.1 as a nameserver on the clients
sudo vi /etc/openvpn/server.conf
push "dhcp-option DNS 10.42.0.1" push "dhcp-option DNS 208.67.222.222" push "dhcp-option DNS 208.67.220.220"
sudo /etc/init.d/openvpn restart
sudo apt-get install perl libnet-ssleay-perl openssl libauthen-pam-perl libpam-runtime libio-pty-perl libmd5-perl
cd /usr/local/src
sudo curl -OL http://www.webmin.com/download/deb/webmin-current.deb
sudo dpkg -i webmin-current.deb
On fiona (server):
sudo apt-get install syslog-ng
sudo vi /etc/syslog-ng/syslog-ng.conf
source s_remote { tcp(); }; destination d_clients { file("/var/log/$HOST/$PROGRAM"); }; log { source(s_remote); destination(d_clients); };
sudo /etc/init.d/syslog-ng restart
On hettie (client):
source s_local { internal(); unix-stream("/dev/log"); file("/proc/kmsg" log_prefix("kernel: ")); }; destination d_log_host { tcp("10.42.0.1" port(514)); }; log { source(s_local); destination(d_log_host); };
sudo -i
cd /usr/local/src
curl http://redis.googlecode.com/files/redis-1.2.5.tar.gz | tar zxv
cd redis-1.2.5
make
cp redis-server /usr/local/bin/
cp redis-cli /usr/local/bin/
Install redis.conf
to /etc/redis.conf
sudo cp utils/redis_init_script /etc/init.d/redis-server
vi /etc/init.d/redis-server
Change the conf file path to /etc/redis.conf
chmod +x /etc/init.d/redis-server
update-rc.d -f redis-server defaults
gem install redis redis-namespace yajl-ruby
exit
cd /home/ci
git clone git://github.com/defunkt/resque.git
mkdir resque/public
mkdir resque/tmp
sudo vi /etc/nginx/resque.conf
server { listen 80; server_name resque.grays.im; root /home/ci/resque/public; passenger_enabled on; auth_basic "Restricted"; auth_basic_user_file /etc/nginx/_htpasswd; }
sudo /etc/init.d/nginx reload
sudo /etc/init.d/redis-server start
#!/bin/bash | |
# | |
# god Startup script for God. | |
# | |
# chkconfig: - 85 15 | |
# description: Run god that starts and monitors all Winnow processes | |
# | |
CONF=/etc/god.conf | |
RETVAL=0 | |
# Go no further if config directory is missing. | |
[ -f "$CONF" ] || exit 0 | |
case "$1" in | |
start) | |
/usr/local/bin/god -c $CONF -l /var/log/god.log -P /var/run/god.pid --no-syslog | |
RETVAL=$? | |
;; | |
stop) | |
/usr/local/bin/god quit | |
RETVAL=$? | |
;; | |
restart) | |
/usr/local/bin/god quit | |
/usr/local/bin/god -c $CONF -l /var/log/god.log -P /var/run/god.pid --no-syslog | |
RETVAL=$? | |
;; | |
*) | |
echo "Usage: god {start|stop|restart}" | |
exit 1 | |
;; | |
esac | |
exit $RETVAL |
dir = File.join(File.dirname(__FILE__), "god.conf.d", "*.god") | |
puts "Loading #{dir}" | |
God.load(dir) |
How god is setup on the servers (using hettie as an example).
gem install god
Setup log rotation, edit /etc/logrotate.d/god
:
/var/log/god.log { rotate 6 weekly compress missingok notifempty }
Install god.conf
to /etc/god.conf
mkdir /etc/god.conf.d
Install init.d/god
:
chmod +x /etc/init.d/god
update-rc.d -f god defaults
/etc/init.d/god start
Installing a god config:
cd /etc/god.conf.d/
ln -s /var/www/inventory.app/current/config/resque.god inventory.app-resque.god
/etc/init.d/god restart
sudo -i
apt-get install build-essential curl apache2 apache2-threaded-dev mysql-server libreadline5-dev
cd /usr/local/src
# curl -LO http://rubyforge.org/frs/download.php/68718/ruby-enterprise_1.8.7-2010.01_i386.deb
# dpkg -i ruby-enterprise_1.8.7-2010.01_i386.deb
curl -LO http://rubyforge.org/frs/download.php/68720/ruby-enterprise_1.8.7-2010.01_amd64.deb
dpkg -i ruby-enterprise_1.8.7-2010.01_amd64.deb
In ~/.gemrc
:
:benchmark: false :update_sources: true gem: --no-ri --no-rdoc :bulk_threshold: 1000 :backtrace: false :sources: - https://PRIVATE_GEM_SERVER :verbose: true
gem install passenger
passenger-install-apache2-module
In /etc/apache2/httpd.conf
:
ServerName izzy LoadModule passenger_module /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.11/ext/apache2/mod_passenger.so PassengerRoot /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.11 PassengerRuby /usr/local/bin/ruby RailsMaxPoolSize 5 RailsPoolIdleTime 180 RailsAllowModRewrite on
a2enmod rewrite
sudo -i
Add to /etc/apt/sources.list
:
deb http://downloads.mongodb.org/distros/ubuntu 9.10 10gen
gpg --keyserver pgpkeys.mit.edu --recv-key 9ECBEC467F0CEB10
gpg -a --export 9ECBEC467F0CEB10 | apt-key add -
apt-get update
apt-get install mongodb-stable
sudo adduser deploy
See deployment.md
for other steps.
sudo -i
apt-get install openvpn
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn
tar zxvf izzy.gz -C /etc/openvpn/
vi /etc/openvpn/client.conf
Notable changes:
remote vpn.grays.im 1194 user nobody group nogroup cert izzy.crt key izzy.key tls-auth ta.key 1
/etc/init.d/openvpn restart
sudo dpkg --remove ruby-enterprise
Yes, you need ruby to compile ruby 1.9
sudo apt-get install ruby1.8 libruby1.8 bison autoconf
cd /usr/local/src
Download a tarball of the ruby_1_9_1
branch from github:
sudo curl -O http://download.github.com/ruby-ruby-8acba0b.tar.gz
sudo tar zxvf ruby-ruby-8acba0b.tar.gz
cd ruby-ruby-8acba0b
sudo autoconf
sudo ./configure
sudo make
sudo make install
sudo apt-get remove ruby1.8 libruby1.8
sudo gem update --system
Reinstall the gems we were using:
sudo gem install aloha-engine carrierwave compass god guides \
hoptoad_notifier json_pure mongo_ext mongo_mapper multipass mysql \
newrelic_rpm passenger prawn rails resque socialist will_paginate
Rebuild passenger...
sudo passenger-install-apache2-module
Update /etc/apache2/httpd.conf
.
LoadModule passenger_module /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.11/ext/apache2/mod_passenger.so PassengerRoot /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.11 PassengerRuby /usr/local/bin/ruby
sudo reboot
#!/bin/sh | |
# | |
# init.d script with LSB support. | |
# | |
# Copyright (c) 2007 Javier Fernandez-Sanguino <[email protected]> | |
# | |
# This is free software; you may redistribute it and/or modify | |
# it under the terms of the GNU General Public License as | |
# published by the Free Software Foundation; either version 2, | |
# or (at your option) any later version. | |
# | |
# This is distributed in the hope that it will be useful, but | |
# WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License with | |
# the Debian operating system, in /usr/share/common-licenses/GPL; if | |
# not, write to the Free Software Foundation, Inc., 59 Temple Place, | |
# Suite 330, Boston, MA 02111-1307 USA | |
# | |
### BEGIN INIT INFO | |
# Provides: mongodb | |
# Required-Start: $network $local_fs $remote_fs | |
# Required-Stop: $network $local_fs $remote_fs | |
# Should-Start: $named | |
# Should-Stop: | |
# Default-Start: 2 3 4 5 | |
# Default-Stop: 0 1 6 | |
# Short-Description: An object/document-oriented database | |
# Description: MongoDB is a high-performance, open source, schema-free | |
# document-oriented data store that's easy to deploy, manage | |
# and use. It's network accessible, written in C++ and offers | |
# the following features: | |
# | |
# * Collection oriented storage - easy storage of object- | |
# style data | |
# * Full index support, including on inner objects | |
# * Query profiling | |
# * Replication and fail-over support | |
# * Efficient storage of binary data including large | |
# objects (e.g. videos) | |
# * Auto-sharding for cloud-level scalability (Q209) | |
# | |
# High performance, scalability, and reasonable depth of | |
# functionality are the goals for the project. | |
### END INIT INFO | |
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin | |
DAEMON=/usr/local/bin/mongod | |
DESC=database | |
# Default defaults. Can be overridden by the /etc/default/$NAME | |
NAME=mongodb | |
CONF=/etc/mongodb.conf | |
DATA=/var/lib/mongodb | |
LOGDIR=/var/log/mongodb | |
PIDFILE=/var/run/$NAME.pid | |
LOGFILE=$LOGDIR/$NAME.log # Server logfile | |
ENABLE_MONGODB=yes | |
# Include mongodb defaults if available | |
if [ -f /etc/default/$NAME ] ; then | |
. /etc/default/$NAME | |
fi | |
if test ! -x $DAEMON; then | |
echo "Could not find $DAEMON" | |
exit 0 | |
fi | |
if test "x$ENABLE_MONGODB" != "xyes"; then | |
exit 0 | |
fi | |
if test ! -x $DATA; then | |
mkdir $DATA || exit 0 | |
fi | |
. /lib/lsb/init-functions | |
STARTTIME=1 | |
DIETIME=10 # Time to wait for the server to die, in seconds | |
# If this value is set too low you might not | |
# let some servers to die gracefully and | |
# 'restart' will not work | |
DAEMONUSER=${DAEMONUSER:-mongodb} | |
DAEMON_OPTS=${DAEMON_OPTS:-"--dbpath $DATA --logpath $LOGFILE run"} | |
DAEMON_OPTS="$DAEMON_OPTS --config $CONF" | |
set -e | |
running_pid() { | |
# Check if a given process pid's cmdline matches a given name | |
pid=$1 | |
name=$2 | |
[ -z "$pid" ] && return 1 | |
[ ! -d /proc/$pid ] && return 1 | |
cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1` | |
# Is this the expected server | |
[ "$cmd" != "$name" ] && return 1 | |
return 0 | |
} | |
running() { | |
# Check if the process is running looking at /proc | |
# (works for all users) | |
# No pidfile, probably no daemon present | |
[ ! -f "$PIDFILE" ] && return 1 | |
pid=`cat $PIDFILE` | |
running_pid $pid $DAEMON || return 1 | |
return 0 | |
} | |
start_server() { | |
# Start the process using the wrapper | |
start-stop-daemon --background --start --quiet --pidfile $PIDFILE \ | |
--make-pidfile --chuid $DAEMONUSER \ | |
--exec $DAEMON -- $DAEMON_OPTS | |
errcode=$? | |
return $errcode | |
} | |
stop_server() { | |
# Stop the process using the wrapper | |
start-stop-daemon --stop --quiet --pidfile $PIDFILE \ | |
--user $DAEMONUSER \ | |
--exec $DAEMON | |
errcode=$? | |
return $errcode | |
} | |
force_stop() { | |
# Force the process to die killing it manually | |
[ ! -e "$PIDFILE" ] && return | |
if running ; then | |
kill -15 $pid | |
# Is it really dead? | |
sleep "$DIETIME"s | |
if running ; then | |
kill -9 $pid | |
sleep "$DIETIME"s | |
if running ; then | |
echo "Cannot kill $NAME (pid=$pid)!" | |
exit 1 | |
fi | |
fi | |
fi | |
rm -f $PIDFILE | |
} | |
case "$1" in | |
start) | |
log_daemon_msg "Starting $DESC" "$NAME" | |
# Check if it's running first | |
if running ; then | |
log_progress_msg "apparently already running" | |
log_end_msg 0 | |
exit 0 | |
fi | |
if start_server ; then | |
# NOTE: Some servers might die some time after they start, | |
# this code will detect this issue if STARTTIME is set | |
# to a reasonable value | |
[ -n "$STARTTIME" ] && sleep $STARTTIME # Wait some time | |
if running ; then | |
# It's ok, the server started and is running | |
log_end_msg 0 | |
else | |
# It is not running after we did start | |
log_end_msg 1 | |
fi | |
else | |
# Either we could not start it | |
log_end_msg 1 | |
fi | |
;; | |
stop) | |
log_daemon_msg "Stopping $DESC" "$NAME" | |
if running ; then | |
# Only stop the server if we see it running | |
errcode=0 | |
stop_server || errcode=$? | |
log_end_msg $errcode | |
else | |
# If it's not running don't do anything | |
log_progress_msg "apparently not running" | |
log_end_msg 0 | |
exit 0 | |
fi | |
;; | |
force-stop) | |
# First try to stop gracefully the program | |
$0 stop | |
if running; then | |
# If it's still running try to kill it more forcefully | |
log_daemon_msg "Stopping (force) $DESC" "$NAME" | |
errcode=0 | |
force_stop || errcode=$? | |
log_end_msg $errcode | |
fi | |
;; | |
restart|force-reload) | |
log_daemon_msg "Restarting $DESC" "$NAME" | |
errcode=0 | |
stop_server || errcode=$? | |
# Wait some sensible amount, some server need this | |
[ -n "$DIETIME" ] && sleep $DIETIME | |
start_server || errcode=$? | |
[ -n "$STARTTIME" ] && sleep $STARTTIME | |
running || errcode=$? | |
log_end_msg $errcode | |
;; | |
status) | |
log_daemon_msg "Checking status of $DESC" "$NAME" | |
if running ; then | |
log_progress_msg "running" | |
log_end_msg 0 | |
else | |
log_progress_msg "apparently not running" | |
log_end_msg 1 | |
exit 1 | |
fi | |
;; | |
# MongoDB can't reload its configuration. | |
reload) | |
log_warning_msg "Reloading $NAME daemon: not implemented, as the daemon" | |
log_warning_msg "cannot re-read the config file (use restart)." | |
;; | |
*) | |
N=/etc/init.d/$NAME | |
echo "Usage: $N {start|stop|force-stop|restart|force-reload|status}" >&2 | |
exit 1 | |
;; | |
esac | |
exit 0 |
apt-get upgrade
apt-get -y install tcsh scons g++ xulrunner-1.9.1 xulrunner-1.9.1-dev libpcre++-dev \
libboost-dev libboost-program-options-dev libboost-thread-dev \
libboost-filesystem-dev libboost-date-time-dev
adduser mongodb
chown mongodb /var/lib/mongodb/
cd /usr/local/src
curl ftp://ftp.mozilla.org/pub/mozilla.org/js/js-1.7.0.tar.gz | tar zxv
cd js/src
export CFLAGS="-DJS_C_STRINGS_ARE_UTF8"
make -f Makefile.ref
JS_DIST=/usr/local make -f Makefile.ref export
cd ..
git clone git://github.com/mongodb/mongo.git
cd mongo/
git checkout -b build r1.3.4
scons all
cd ..
apt-get -y install
scons all
scons --prefix=/usr/local install
vi /etc/init.d/mongodb
chmod +x /etc/init.d/mongodb
update-rc.d mongodb defaults
/etc/init.d/mongodb start
adduser mongodb
chown mongodb /var/lib/mongodb/
sudo apt-get install monit
sudo mkdir /etc/monit/conf.d
sudo ln -s /var/www/admin.graysbooks.com/current/config/resque.monit /etc/monit/conf.d/resque_worker_bookstore.monit
sudo vi /etc/monit/monitrc
set daemon 120 set logfile syslog facility log_daemon set httpd port 8080 allow localhost allow 10.42.0.0/24 include /etc/monit/conf.d/*
sudo vi /etc/default/monit
startup=1
sudo /etc/init.d/monit start
visudo:
%deploy ALL=NOPASSWD: /usr/sbin/monit
I seem to have lost my setup notes :(
On the node (client):
sudo apt-get install munin-node
sudo pico /etc/munin/munin-node.conf
allow ^10\.42\.0\.1$
sudo restart munin-node
On the main host:
sudo pico /etc/munin/munin.conf
[Servers;ginger] address 10.42.0.17 use_node_name yes
sudo /usr/share/munin/munin-update --force-root
ssh [email protected]
adduser admin
adduser admin sudo
adduser deploy
visudo
uncomment or add the line: %sudo ALL=NOPASSWD: ALL
logout
Locally:
scp ~/.ssh/id_rsa.pub [email protected]:~/id_rsa.pub
ssh [email protected]
Back on the server:
mkdir .ssh
cat id_rsa.pub > .ssh/authorized_keys
rm id_rsa.pub
touch .sudo_as_admin_successful
touch .hushlogin
Now that you can login without a password, disable root login.
sudo vi /etc/ssh/sshd_config
Change PermitRootLogin yes
to PermitRootLogin no
.
sudo /etc/init.d/ssh restart
Switch to root. (LOL?)
su -l
Put the hostname for the server in /etc/hostname
Add hettie
to /etc/hostname
Add 127.0.0.1 hettie
to /etc/hosts
hostname hettie
Enable the universe repositories (if needed).
sudo vi /etc/apt/sources.list
sudo apt-get update
apt-get upgrade
Install required things.
sudo apt-get -y install build-essential bison openssl \
libreadline5 libreadline-dev curl git-core zlib1g zlib1g-dev \
libssl-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev \
apache2 apache2-threaded-dev mysql-server libmysqlclient15-dev
Just press [enter] whenever prompted for a mysql password.
sudo bash < <( curl -L http://bit.ly/rvm-install-system-wide )
sudo adduser admin rvm
Open a new shell so group permissions are picked up (there's probably a better way to do this).
rvm install 1.9.2
rvm use 1.9.2 --default
Put the following at the end of /etc/bash.bashrc
:
[[ -s "/usr/local/lib/rvm" ]] && . "/usr/local/lib/rvm"
Open a new shell again.
Put the following in .gemrc
gem: --no-ri --no-rdoc
:sources:
- http://rubygems.org
Update gems and install rails
gem update
gem install passenger
passenger-install-apache2-module
Add the lines given by the passenger installation to you Apache configuration
sudo vi /etc/apache2/httpd.conf
LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.2-p0/gems/passenger-2.2.15/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p0/gems/passenger-2.2.15
PassengerRuby /usr/local/rvm/rubies/ruby-1.9.2-p0/bin/ruby
a2enmod ssl
Self-signed cert
mkdir /etc/apache2/ssl
cd /etc/apache2/ssl
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
a2enmod ssl
SSL conf would look something like:
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
Restart apache.
sudo /etc/init.d/apache2 restart
apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
Annoying? Add something like ServerName hettie
to /etc/apache2/httpd.conf
This is available in Ubuntu since at least Lucid.
sudo apt-get install libapache2-mod-xsendfile
sudo pico /etc/apache2/httpd.conf
XSendFile on
sudo /etc/init.d/apache2 restart
In your application's VirtualHost conf:
XSendFileAllowAbove on
# Redis configuration file example | |
# By default Redis does not run as a daemon. Use 'yes' if you need it. | |
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized. | |
daemonize yes | |
#daemonize no | |
# When run as a daemon, Redis write a pid file in /var/run/redis.pid by default. | |
# You can specify a custom pid file location here. | |
pidfile /var/run/redis.pid | |
# Accept connections on the specified port, default is 6379 | |
port 6379 | |
# If you want you can bind a single interface, if the bind option is not | |
# specified all the interfaces will listen for connections. | |
# | |
# bind 127.0.0.1 | |
# Close the connection after a client is idle for N seconds (0 to disable) | |
timeout 300 | |
# Set server verbosity to 'debug' | |
# it can be one of: | |
# debug (a lot of information, useful for development/testing) | |
# notice (moderately verbose, what you want in production probably) | |
# warning (only very important / critical messages are logged) | |
loglevel notice | |
#loglevel debug | |
# Specify the log file name. Also 'stdout' can be used to force | |
# the demon to log on the standard output. Note that if you use standard | |
# output for logging but daemonize, logs will be sent to /dev/null | |
logfile /var/log/redis.log | |
#logfile stdout | |
# Set the number of databases. The default database is DB 0, you can select | |
# a different one on a per-connection basis using SELECT <dbid> where | |
# dbid is a number between 0 and 'databases'-1 | |
databases 16 | |
################################ SNAPSHOTTING ################################# | |
# | |
# Save the DB on disk: | |
# | |
# save <seconds> <changes> | |
# | |
# Will save the DB if both the given number of seconds and the given | |
# number of write operations against the DB occurred. | |
# | |
# In the example below the behaviour will be to save: | |
# after 900 sec (15 min) if at least 1 key changed | |
# after 300 sec (5 min) if at least 10 keys changed | |
# after 60 sec if at least 10000 keys changed | |
save 900 1 | |
save 300 10 | |
save 60 10000 | |
# Compress string objects using LZF when dump .rdb databases? | |
# For default that's set to 'yes' as it's almost always a win. | |
# If you want to save some CPU in the saving child set it to 'no' but | |
# the dataset will likely be bigger if you have compressible values or keys. | |
rdbcompression yes | |
# The filename where to dump the DB | |
dbfilename dump.rdb | |
# For default save/load DB in/from the working directory | |
# Note that you must specify a directory not a file name. | |
dir ./ | |
################################# REPLICATION ################################# | |
# Master-Slave replication. Use slaveof to make a Redis instance a copy of | |
# another Redis server. Note that the configuration is local to the slave | |
# so for example it is possible to configure the slave to save the DB with a | |
# different interval, or to listen to another port, and so on. | |
# | |
# slaveof <masterip> <masterport> | |
# If the master is password protected (using the "requirepass" configuration | |
# directive below) it is possible to tell the slave to authenticate before | |
# starting the replication synchronization process, otherwise the master will | |
# refuse the slave request. | |
# | |
# masterauth <master-password> | |
################################## SECURITY ################################### | |
# Require clients to issue AUTH <PASSWORD> before processing any other | |
# commands. This might be useful in environments in which you do not trust | |
# others with access to the host running redis-server. | |
# | |
# This should stay commented out for backward compatibility and because most | |
# people do not need auth (e.g. they run their own servers). | |
# | |
# requirepass foobared | |
################################### LIMITS #################################### | |
# Set the max number of connected clients at the same time. By default there | |
# is no limit, and it's up to the number of file descriptors the Redis process | |
# is able to open. The special value '0' means no limts. | |
# Once the limit is reached Redis will close all the new connections sending | |
# an error 'max number of clients reached'. | |
# | |
# maxclients 128 | |
# Don't use more memory than the specified amount of bytes. | |
# When the memory limit is reached Redis will try to remove keys with an | |
# EXPIRE set. It will try to start freeing keys that are going to expire | |
# in little time and preserve keys with a longer time to live. | |
# Redis will also try to remove objects from free lists if possible. | |
# | |
# If all this fails, Redis will start to reply with errors to commands | |
# that will use more memory, like SET, LPUSH, and so on, and will continue | |
# to reply to most read-only commands like GET. | |
# | |
# WARNING: maxmemory can be a good idea mainly if you want to use Redis as a | |
# 'state' server or cache, not as a real DB. When Redis is used as a real | |
# database the memory usage will grow over the weeks, it will be obvious if | |
# it is going to use too much memory in the long run, and you'll have the time | |
# to upgrade. With maxmemory after the limit is reached you'll start to get | |
# errors for write operations, and this may even lead to DB inconsistency. | |
# | |
# maxmemory <bytes> | |
############################## APPEND ONLY MODE ############################### | |
# By default Redis asynchronously dumps the dataset on disk. If you can live | |
# with the idea that the latest records will be lost if something like a crash | |
# happens this is the preferred way to run Redis. If instead you care a lot | |
# about your data and don't want to that a single record can get lost you should | |
# enable the append only mode: when this mode is enabled Redis will append | |
# every write operation received in the file appendonly.log. This file will | |
# be read on startup in order to rebuild the full dataset in memory. | |
# | |
# Note that you can have both the async dumps and the append only file if you | |
# like (you have to comment the "save" statements above to disable the dumps). | |
# Still if append only mode is enabled Redis will load the data from the | |
# log file at startup ignoring the dump.rdb file. | |
# | |
# The name of the append only file is "appendonly.log" | |
# | |
# IMPORTANT: Check the BGREWRITEAOF to check how to rewrite the append | |
# log file in background when it gets too big. | |
appendonly no | |
# The fsync() call tells the Operating System to actually write data on disk | |
# instead to wait for more data in the output buffer. Some OS will really flush | |
# data on disk, some other OS will just try to do it ASAP. | |
# | |
# Redis supports three different modes: | |
# | |
# no: don't fsync, just let the OS flush the data when it wants. Faster. | |
# always: fsync after every write to the append only log . Slow, Safest. | |
# everysec: fsync only if one second passed since the last fsync. Compromise. | |
# | |
# The default is "always" that's the safer of the options. It's up to you to | |
# understand if you can relax this to "everysec" that will fsync every second | |
# or to "no" that will let the operating system flush the output buffer when | |
# it want, for better performances (but if you can live with the idea of | |
# some data loss consider the default persistence mode that's snapshotting). | |
appendfsync always | |
# appendfsync everysec | |
# appendfsync no | |
############################### ADVANCED CONFIG ############################### | |
# Glue small output buffers together in order to send small replies in a | |
# single TCP packet. Uses a bit more CPU but most of the times it is a win | |
# in terms of number of queries per second. Use 'yes' if unsure. | |
glueoutputbuf yes | |
# Use object sharing. Can save a lot of memory if you have many common | |
# string in your dataset, but performs lookups against the shared objects | |
# pool so it uses more CPU and can be a bit slower. Usually it's a good | |
# idea. | |
# | |
# When object sharing is enabled (shareobjects yes) you can use | |
# shareobjectspoolsize to control the size of the pool used in order to try | |
# object sharing. A bigger pool size will lead to better sharing capabilities. | |
# In general you want this value to be at least the double of the number of | |
# very common strings you have in your dataset. | |
# | |
# WARNING: object sharing is experimental, don't enable this feature | |
# in production before of Redis 1.0-stable. Still please try this feature in | |
# your development environment so that we can test it better. | |
shareobjects no | |
shareobjectspoolsize 1024 |
sudo -i
cd /etc/openvpn/easy-rsa/
source vars
export clientname=hettie
./pkitool $clientname
cd keys
tar zcvf /home/ci/$clientname.gz $clientname.crt $clientname.key ca.crt ta.key
chown ci:ci /home/ci/$clientname.gz
On the client:
sudo apt-get install openvpn
scp [email protected]:~/$HOSTNAME.gz .
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn
sudo tar zxvf $HOSTNAME.gz -C /etc/openvpn/
sudo vi /etc/openvpn/client.conf
Notable changes:
remote 192.168.150.175 1194 user nobody group nogroup cert hettie.crt key hettie.key tls-auth ta.key 1
sudo /etc/init.d/openvpn restart
sudo -i
apt-get install openvpn
cd /usr/share/doc/openvpn/examples
cp ./sample-config-files/server.conf.gz /etc/openvpn
cp -r ./easy-rsa/2.0 /etc/openvpn
cd /etc/openvpn
mv 2.0 easy-rsa
gzip -d server.conf.gz
cd /etc/openvpn/easy-rsa
vim ./vars
At the bottom of the file
export KEY_COUNTRY="US" export KEY_PROVINCE="FL" export KEY_CITY="Tampa" export KEY_ORG="Gray's College Bookstore" export KEY_EMAIL="[email protected]"
. ./vars
./clean-all
Generate the certificate and key for the server.
./pkitool --initca
./pkitool --server server
./build-dh
cd keys
openvpn --genkey --secret ta.key
cp server.crt server.key ca.crt dh1024.pem ta.key /etc/openvpn/
Creating the server configuration file
vi /etc/openvpn/server.conf
Notable changes:
server 10.42.0.0 255.255.255.0 client-to-client # Allow clients to see eachother tls-auth ta.key 0 user nobody group nogroup
cd /etc/openvpn/easy-rsa/keys
cp ca.crt server.crt server.key dh1024.pem /etc/openvpn
/etc/init.d/openvpn restart
Allow connections through the firewall.
ufw allow 1194/udp
sudo vi /etc/openvpn/server.conf
client-config-dir ccd route 10.42.0.0 255.255.255.0
sudo mkdir /etc/openvpn/ccd
sudo vi /etc/openvpn/ccd/elise
ifconfig-push 10.42.0.9 10.42.0.10
For the last octet of the IP see http://openvpn.net/index.php/open-source/documentation/howto.html#policy.
sudo /etc/init.d/openvpn restart