部署 淘宝威客站点的部署

qhwa · 2013年07月03日 · 最后由 fsword 回复于 2013年07月04日 · 5712 次阅读
本帖已被管理员设置为精华贴

之前做淘宝威客的时候,做了一个子项目 weike-deployment,用来快速部署一台新机器,可以把刚装完系统的 Linux 服务器,很快地变成一个生产环境的节点。

实践下来,感受到了一些好处:

  1. 添加新机器比较容易
  2. 服务器的软件配置也加入了版本控制
  3. 一些安装比较麻烦的软件(例如 imagemagick),不需要每次都去对着教程装了
  4. 整个拓扑结构都有了文档,如果新人加入也可以很快上手(虽然一直没有新人……)

这个项目的目录结构:

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 的方式。

这个有项目地址么?对自动部署一点都不懂。。。求教,也希望能够一键部署整个 vps。

果断收藏!

#2 楼 @Levan 放到 github 上了: https://github.com/qhwa/weike-deployment

不过现在还不能直接用在 VPS 上,仅供参考

在新的 RHEL 服务器上面安装 Ruby 环境是永远的痛...

哪位可以回答一直的疑问,淘宝系一直使用 centos 的初衷是什么呢?

#7 楼 @siko 历史原因吧,第一个人选择的时候,centos 可能是最好的,后面做了很多定制,就不好换了 现在开始用阿里云的云服务器了,操作系统可以选其他的了

#8 楼 @qhwa 从运维管理的角度看,发布版越少越好,实际上这些发布版的差异一般也不会对应用本身有什么限制 #5 楼 @huacnlee 公司内部可以使用 yum,之前一直没人去做,现在 @ruohanc 同学做掉了,详情看内网技术论坛

需要 登录 后方可回复, 如果你还没有账号请 注册新账号