Skip to content

Instantly share code, notes, and snippets.

@ambethia
Created October 18, 2008 01:28
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save ambethia/17575 to your computer and use it in GitHub Desktop.
Save ambethia/17575 to your computer and use it in GitHub Desktop.
All kinda of deployment notes

Deploying an app for the first time

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!

Fiona

Nginx + Passenger (w/ REE) on Ubuntu 9.10

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

Ruby Enterprise Edition

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

Nginx + Passenger

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

Integrity

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

Rip

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 

Git

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

Misc:

(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

Firewall

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

Aloha Auth

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

DNS

THIS NEVER WORKED...

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

Push DNS from OpenVPN

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

Webmin

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

syslog-ng

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);
};

Redis / Resque

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

Firewall

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

On Fiona

#!/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)

God

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

Izzy (Ubuntu 9.10)

Ruby (REE), MySQL and Apache with Passenger

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

MongoDB

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

Setup Deployment

sudo adduser deploy

See deployment.md for other steps.

Setup VPN client

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

Switch to ruby 1.9

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

Private IPs

sudo pico /etc/network/interfaces

auto eth0:0
iface eth0:0 inet static
 address 192.168.XXX.XXX
 netmask 255.255.128.0

sudo /etc/init.d/networking restart

#!/bin/sh
#
# init.d script with LSB support.
#
# Copyright (c) 2007 Javier Fernandez-Sanguino <jfs@debian.org>
#
# 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/

Monit Notes

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

Munin

I seem to have lost my setup notes :(

Adding a new new node

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

Notes on setting up Apache 2 with Passenger and Ruby 1.9.2 on Ubuntu 10.4

ssh root@0.0.0.0

adduser admin
adduser admin sudo
adduser deploy

visudo

uncomment or add the line: %sudo ALL=NOPASSWD: ALL

logout

Locally:

scp ~/.ssh/id_rsa.pub admin@0.0.0.0:~/id_rsa.pub
ssh admin@0.0.0.0

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

Updates

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.

Ruby

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

Apache

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

SSL

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

mod_xsendfile

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

VPN

Client Setup

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 ci@vpn.grays.im:~/$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

Server Setup

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="jason@graysbooks.com"
. ./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

Assign IPs to Clients

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment