之前做淘宝威客的时候,做了一个子项目 weike-deployment,用来快速部署一台新机器,可以把刚装完系统的 Linux 服务器,很快地变成一个生产环境的节点。
实践下来,感受到了一些好处:
这个项目的目录结构:
weike-deployment
|~cmd/ #=> 一些shell脚本
| |-build_weike_server*
| |-restart_haproxy*
| `-restart_nginx*
|~doc/ #=> 文档
| |-install-server.md
| `-readme.md
|~etc/ #=> 软件配置
| |~ssh/
| | |-authorized_keys
| | |-config
| | |-... (ssh keys)
| |-haproxy.cfg
| |-ldpath.lib.conf
| |-nginx.conf
| `-nginx.weike.conf
`~src/ #=> 软件包,预先下载好
|~rvm/
| `~archives/
| `-ruby-1.9.3-p385.tar.bz2
|-ImageMagick-6.8.3-3.tar.bz2
|-jasper-1.900.1.tar.gz
|-libmcrypt-2.5.8.tar.bz2
`-node-v0.8.20.tar.gz
其中最核心的是安装脚本, cmd/build_weike_server
#!/bin/bash
#****************************************************************#
# ScriptName: build-weike-server.sh
# Author: hua.qiuh
# Create Date: 2013-02-21
# Modify Author:
# Modify Date: 2013-02-21
# Function:
#***************************************************************#
BASE_DIR=/home/www
SOURCE_DIR=$BASE_DIR/src
CONFIG_DIR=$BASE_DIR/etc
RUNNER=ads
current_user=`whoami`
function build_weike_server(){
init_base
if [ "$current_user" != "$RUNNER" ]
then
install_global_softwares
else
install_project_softwares
fi
}
function init_base(){
if [ `pwd` != $BASE_DIR ]
then
sudo mkdir -p $BASE_DIR
sudo chown $current_user:users $BASE_DIR -R
cp * -a $BASE_DIR/
cd $BASE_DIR
cmd/build_weike_server
exit
fi
}
function install_global_softwares(){
prepare_libs
install_git
install_nodejs
install_imagemagick
install_mcrypt
install_nginx # web服务器上需要安装
install_haproxy # web服务器上需要安装
add_local_lib_path
install_sendmail_server
}
function prepare_libs(){
sudo yum -y install \
gcc gcc-c++ autoconf libjpeg-devel libpng-devel \
freetype freetype-devel libxml2-devel zlib-devel \
glibc-devel glib2-devel bzip2-devel \
ncurses-devel curl-devel e2fsprogs-devel \
krb5-devel libidn-devel \
openldap-devel openldap-clients openldap-servers \
libmcrypt-devel libxslt-devel libtiff-devel \
|| (echo "requirements installing failed!" && exit)
}
function login_as_runner(){
log 'login as user: ads'
sudo su ads
cd ~
}
function logout(){
log 'logout'
exit
}
function install_git(){
info '>> Installing git'
git --version && celebrate 'git has been installed' && return
sudo yum install git
}
function install_nginx(){
info '>> Installing Nginx'
weike_conf=/home/tops/conf/vhosts/weike.taobao.com.conf
[ -f $weike_conf ] && celebrate 'Nginx has been installed' && return
sudo yum install tops-nginx -y
sudo mkdir -p /home/tops/conf/vhosts
sudo cp $BASE_DIR/etc/nginx.conf /home/tops/conf/
sudo ln -s $BASE_DIR/etc/nginx.weike.conf $weike_conf
}
function install_haproxy(){
info '>> Installing HAProxy'
[ -f /etc/haproxy.cfg ] && celebrate 'HAProxy has been installed' && return
sudo yum install haproxy -y
sudo mv /etc/haproxy.cfg /etc/haproxy.cfg.origin
sudo ln -s $BASE_DIR/etc/haproxy.cfg /etc/haproxy.cfg
}
function add_local_lib_path(){
info '>> Adding /usr/local/lib to global library path'
target=/etc/ld.so.conf.d/local_lib.conf
[ -f $target ] && celebrate 'already added' && return
sudo cp $BASE_DIR/etc/ldpath.lib.conf /etc/ld.so.conf.d/local_lib.conf
sudo ldconfig
}
function install_sendmail_server(){
info '>> Installing sendmail'
sudo yum install -y sendmail > /dev/null
sudo /etc/init.d/sendmail start
sudo chkconfig sendmail on
celebrate 'sendmail has started'
}
function install_imagemagick(){
info '>> Installing ImageMagick'
convert --version && celebrate 'imagemagick has been installed' && return
export CFLAGS="-O2 -fPIC"
export CXXFLAGS=$CFLAGS
install_from_source 'jasper'
install_from_source 'ImageMagick'
}
function install_mcrypt(){
info '>> Installing libmcrypt'
[ -f /usr/local/lib/libmcrypt.so ] && celebrate 'libmcrypt has been installed' && return
install_from_source 'libmcrypt'
}
function install_nodejs(){
info '>> Installing Nodejs'
node --version && celebrate 'Nodejs has been installed' && return
install_from_source 'node'
}
function install_project_softwares(){
install_rvm
install_ruby
install_weike_components
config_ssh_gitlab
celebrate 'done!'
}
function install_rvm(){
info '>> Installing rvm'
rvm --version && celebrate 'rvm has been installed' && return
\curl -L https://get.rvm.io | bash -s stable
echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"' >> ~/.bashrc
source ~/.bashrc
echo 'install: --no-rdoc --no-ri' >> ~/.gemrc
echo 'update: --no-rdoc --no-ri' >> ~/.gemrc
}
function install_ruby(){
info '>> Installing ruby'
ruby --version && celebrate 'Ruby has been installed' && return
cp $BASE_DIR/src/rvm/archives/* ~/.rvm/archives/
rvm install 1.9.3 && rvm use 1.9.3 --default
}
function install_weike_components(){
install_bundler
install_rmagick
install_rubymcrypt
}
function install_bundler(){
info '>> Installing bundler'
bundle --version && celebrate 'bundler has been installed' && return
gem install bundler
}
function install_rmagick(){
info '>> Installing rmagick'
[ `gem list -i rmagick` = "true" ] && celebrate 'rmagick has been installed' && return
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
gem install rmagick
}
function install_rubymcrypt(){
info '>> Installing ruby-mcrypt'
[ `gem list -i ruby-mcrypt` = "true" ] && celebrate 'ruby-mcrypt has been installed' && return
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
gem install ruby-mcrypt -- --with-mcrypt-dir=/usr/local
}
function config_ssh_gitlab(){
mkdir -p ~/.ssh
cp $BASE_DIR/etc/ssh/* ~/.ssh
chown `whoami` ~/.ssh -R
chmod 600 ~/.ssh/*
}
#--------------- helpers --------------
function install_from_source(){
cd $SOURCE_DIR
extract $1 || (warn "$1 source not found!" && return)
log "Compiling $1 $2"
make -s clean
./configure $2 && make -j -s && sudo make -s install && return
warn "installing $1 failed"
}
function extract(){
(tar xzf $1*.tar.gz || tar xzf $1*.tgz || tar xjf $1*.tar.bz2 || tar xjf $1*.tar.bz ) && cd $1*
}
function log(){
echo -e "\e[35m$1\e[0m"
}
function warn(){
echo -e "\e[31m$1\e[0m"
}
function info(){
echo $1
}
function celebrate(){
echo -e "\e[32m$1\e[0m"
}
build_weike_server
可能对很多人来说不是新鲜的东西啦,其实只是受 Unix 的影响,认同这条原则:
所有东西都是文件
后续想更加自动化,借鉴一下 Arch Linux 的方式。