エンジニアブログ

エンジニアブログ
MT技術情報

デザイナー必見!VPSで高速なMovable Type用サーバをゼロから構築する方法

photo.jpg onagatani 2013年05月06日
133.png

まだGW中に間に合いますよ!という事で最近[個人的]にサーバを構築する機会が多いので、サーバ構築のノウハウを公開したいと思います。 Movable Type専用というわけではないですが、PSGIでのサーバ構築手順がほとんど公開されていないようなので なるべく初心者の人でも判るように解説したいと思います。 かなり検証を行ったので、素のCentOS6.4(64ビット)であれば、上から順番にコピー&ペーストでコマンドを実行するだけで、サーバが構築できるはずです。各コマンドについては細かく説明はしておりませんが、まずは構築してみる事から初めては如何でしょうか。わかりづらい箇所があればFBやTwitter等で質問を受け付けますので気軽にどうぞ。需要があれば一日かけてサーバ構築の勉強会でも実施しようかなと思っているので「いいね」と「はてぶ」お願いします!

目標

  • 本番でも使えるサーバ(最低限のセキュリティ設定は行う)
  • 大量アクセスにも耐えられるサーバ(MTが静的再構築なのでYahoo砲なども影響ないと思います)
  • モダンな環境(MTはPSGIで起動)

必要な前提知識

  • SSHでの操作がなんとなくできる方
  • viなどのエディタの操作がなんとなくできる方

サーバ構成

  • CentOS6.4(最新版)
  • MySQL5.5(mysql-buildは使わずにyumで)
  • Perl5.16.3(perl-build)
  • WEBサーバ:Nginx
  • PSGIサーバ:Starman
  • オプション(PHP、Apache)

ポイント

  • PerlはシステムPerlには変更を加えず新規に最新版Perlを導入します
  • MySQLはあまりバージョン変更はしないのでmysql-buildは使用しません
  • WEBサーバはNginxを使用します(動的な管理画面はPSGIサーバで処理し、静的ファイルはNginxで処理する事で高速なサーバを目指します)
  • ダイナミック・パブリッシングを使用する場合はPHPとApacheが必要です

想定するサーバスペック

  • GMOやサクラのVPSやクラウド
  • (VirtualboxやVMwareFusionなどローカルで一回試す事を推奨します)
  • CPUコア1以上
  • メモリ1G以上
  • HDD10G以上

注意

  • ChefやPuppetでバリバリサーバ構築している人は対象じゃありません
  • 構築されたサーバのセキュリティやパフォーマンスを保証ものではありません
  • 誤字脱字誤った情報を記載していた場合には随時修正します
  • 自己責任で読んで下さい

手順

OSインストール

OS自体のインストールはテキストモードで行います。パーテーションなどはデフォルトで行なっております。詳細は記載しませんので参考URLを見て進めて下さい。参考URL:http://centossrv.com/centos6.shtml

OS初期設定

作業は全てrootユーザで実行します

サーバのssh作業用ユーザを作成しパスワードを設定します

useradd -G wheel ユーザ名
passwd ユーザ名

作成したユーザがsudoを行えるように設定変更する

visudo

エディタが開くので以下の行のコメント「#」を外す

%wheel ALL=(ALL) ALL

sshdのセキュリティを向上させます

vi /etc/ssh/sshd_config

エディタが開くので該当箇所を以下のように修正する

# ポート番号を変更します
#Port 22
Port 2022

# rootユーザでのログインを禁止します
#PermitRootLogin yes
PermitRootLogin no

# パスワード無しログインを禁止します
#PermitEmptyPasswords no
PermitEmptyPasswords no

# 最終行にSSHでログインを許可するユーザを指定します(最初に追加したユーザ名になります)
AllowUsers ユーザ名

以下のコマンドを実行しSSHをリロードします(実行後、現在の接続を切らずにポート2022番にてsshできるか確認し、問題があれば設定を元に戻し再度sshdをリロードする)

/etc/init.d/sshd reload

自宅(SSH接続元)が固定IPであれば以下実施し接続元IPを固定する

echo 'all : IPアドレス' >> /etc/hosts.allow

自宅以外からの接続を拒否する

echo 'sshd : all' >> /etc/hosts.deny

SELinuxをOFFにする

/usr/sbin/setenforce 0
vi /etc/selinux/config

エディタが開くので該当箇所を以下のように修正する

# SELINUX=enforcing
SELINUX=disabled

起動しているサービスのうち余計なサービスを停止する

chkconfig lvm2-monitor off
chkconfig messagebus off
chkconfig netfs off
chkconfig restorecond off

コンソールの数を減らす

vi /etc/sysconfig/init

エディタが開くので該当箇所を以下のように修正する

ACTIVE_CONSOLES=/dev/tty[1]

外部に開放するポートをIPtablesに追記する(実行後、現在の接続を切らずにポート2022番にてsshできるか確認し、問題があれば設定を元に戻し再度sshdをリロードする)

vi /etc/sysconfig/iptables

エディタが開くので該当箇所を以下のように修正する

# SSHを22番ポートから2022番ポートに変更し、80(http),443(https)を追加で許可する
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2022 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

iptablesを再起動する

/etc/init.d/iptables restart

パスを通す

echo '/usr/local/lib' >> /etc/ld.so.conf.d/usr_local.conf
ldconfig

yum関連

yumアップデート

yum update

ライブラリ等追加導入

yum groupinstall "Development Tools"
yum install apr-devel apr-util-devel bison-devel bzip2-devel curl-devel giflib giflib-devel httpd httpd-devel mod_ssl lcms-devel libX11-devel libXext-devel libXt-devel libevent libevent-devel libjpeg-devel libmcrypt-devel libpng libpng-devel librsvg2-devel libtidy-devel libtiff-devel libtool-ltdl-devel libwmf-devel libxml2-devel libxslt-devel logwatch mlocate ncurses-devel nmap ntp openssl-devel perl-ExtUtils-MakeMaker readline-devel perl-devel subversion sysstat vim-enhanced wget xz-libs yum-utils t1lib* libicu-devel aspell-devel libedit-devel net-snmp-devel perl-Module-Build

perl-develをインストールリストに追加しました(thanks @webbingstudio)

ghostscriptのインストール

yumのghostscriptではPDF処理に問題が発生するのでソースからインストールします

cd ~
wget 'http://downloads.sourceforge.net/project/ghostscript/GPL%20Ghostscript/9.09/ghostscript-9.09.tar.gz?r=http%3A%2F%2Fsourceforge.jp%2Fprojects%2Fsfnet_ghostscript%2Fdownloads%2FGPL%2520Ghostscript%2F9.09%2Fghostscript-9.09.tar.gz%2F&ts=1379567700&use_mirror=jaist'
tar zxvf ghostscript-9.09.tar.gz
cd ghostscript-9.09
./configure
make
make install
ln -s /usr/local/bin/gs /usr/bin/gs

yumリポジトリ追加

rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
wget 'http://apt.sw.be/redhat/el6/en/x86_64/rpmforge/RPMS/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm'
rpm -ivh rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6
wget 'http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm'
rpm -ivh epel-release-6-8.noarch.rpm
rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
wget 'http://rpms.famillecollet.com/enterprise/remi-release-6.rpm'
rpm -ivh remi-release-6.rpm
wget 'http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm'
rpm -ivh  nginx-release-centos-6-0.el6.ngx.noarch.rpm

追加リポジトリからMySQLなどをインストール

yum install --enablerepo=nginx nginx
yum install --enablerepo=rpmforge re2c 
yum install --enablerepo=remi,epel mysql mysql-server mysql-devel libmcrypt libmcrypt-devel mcrypt

追加リポジトリを標準では使用できないように編集

以下のファイルの内容を編集しenabled=1を全てenabled=0にする

vi /etc/yum.repos.d/epel.repo
vi /etc/yum.repos.d/remi.repo
vi /etc/yum.repos.d/rpmforge.repo
vi /etc/yum.repos.d/nginx.repo

logwatchのメール送信先を変更する

echo '任意のメールアドレス' >> /root/.forward

ホスト名を変更します

VPSやパブリッククラウド利用している場合には必要ないと思います

vi /etc/sysconfig/network

エディタが開くので該当箇所を以下のように修正する

HOSTNAME=任意のホスト名

自動起動の設定

/etc/init.d/ntpd start
chkconfig ntpd on
/etc/init.d/nginx start
chkconfig nginx on
chkconfig postfix on
chkconfig mysqld on
chkconfig iptables on

MySQL設定

設定ファイル作成

以下のコマンドを実行しファイルを作成する

vi /etc/my.cnf

以下の内容を記載する

[client]
port        = 3306
socket        = /var/lib/mysql/mysql.sock
default-character-set = utf8

[mysqld]
port        = 3306
socket        = /var/lib/mysql/mysql.sock
skip-external-locking

innodb_data_home_dir = /var/lib/mysql/
innodb_file_per_table
innodb_buffer_pool_size=128M
innodb_additional_mem_pool_size=20M
innodb_log_file_size=128M
innodb_log_buffer_size=4M
innodb_flush_log_at_trx_commit=2
thread_cache_size = 32
query_cache_size = 32M
query_cache_limit = 2M
max_connections=128
max_connect_errors=30
character-set-server = utf8
skip-character-set-client-handshake
slow_query_log=ON
slow_query_log_file=mysql-slow.log
long_query_time=0.5
server-id = 1
log-bin = mysql-bin
expire_logs_days = 14
log-error = mysql-error.log
log-bin-index = mysql-bin
sync_binlog = 1
relay-log = relay-bin
relay-log-index = relay-bin
log-slave-updates
skip-slave-start

[mysqldump]
event
quick
no-autocommit
add-drop-table 
single-transaction
skip-extended-insert
hex-blob
default-character-set = utf8
max_allowed_packet = 16M

[mysql]
no-auto-rehash

[mysqlhotcopy]
interactive-timeout

MySQLを起動します

/etc/init.d/mysqld start

MySQLのセキュリティを設定する

パスワード以外は全てYを入力する

mysql_secure_installation

データベースのバックアップを14日保存する設定する

mkdir -p /backup/db
vi /usr/local/bin/mysqlbackup

以下の内容を記載する

#!/bin/sh
BACKDIR=/backup/db
DATE=`date +%y%m%d`
echo "mysql backup start." 
mysqldump -uroot -pパスワード --no-autocommit --add-drop-table --skip-extended-insert --quick --hex-blob --single-transaction --all-databases --default-character-set=utf8 | /usr/bin/gzip > $BACKDIR/mysqldump.$DATE.sql.gz
find $BACKDIR -ctime +14 | xargs rm -rf
echo "mysql backup end." 
chmod 755 /usr/local/bin/mysqlbackup

cronに登録する

crontab -e

エディタが起動するので以下の内容を記載する

MAILTO="任意のメールアドレス"
0 5 * * * /usr/local/bin/mysqlbackup

daemontoolsの導入

daemontoolsを利用するとプロセスの起動を監視し落ちた場合自動に起動する事が可能になります

cd /root
wget -nd http://www.qmailtoaster.com/download/stable/daemontools-toaster-0.76-1.3.6.src.rpm
rpmbuild --rebuild daemontools-toaster-0.76-1.3.6.src.rpm
rpm -Uvh /root/rpmbuild/RPMS/x86_64/daemontools-toaster-0.76-1.3.6.x86_64.rpm
wget -nd http://www.emaillab.org/djb/daemontools/svscan
mv svscan /etc/init.d/
chmod +x /etc/init.d/svscan
useradd -s /bin/false logadmin
mkdir /service
chkconfig svscan on
/etc/init.d/svscan start

daemontoolsを簡単に使うためのスクリプトを設置します

こちらのサイトhttp://blog.hansode.org/archives/51311837.htmlにあるスクリプトが非常に便利なので使用させて頂きます。記事URLのaddsv.shの項にあるスクリプトを以下のように設置します

# ファイルを開いて▼addsv.shの項目をそのまま貼り付けて保存
vi /usr/local/bin/addsv.sh

作成したファイルに実行権限を与えます

chmod 755 /usr/local/bin/addsv.sh

memcachedを導入・設定する

MTの速度向上などに利用するためにmemcachedを導入します(導入時点の最新版を入れて下さい)

cd ~
wget 'http://memcached.googlecode.com/files/memcached-1.4.15.tar.gz'
tar zxvf memcached-1.4.15.tar.gz 
cd memcached-1.4.15
./configure
make
make install

memcachedをdaemontoolsで起動します

以下のコマンドを実行しdaemontoolsにサービスを追加します

addsv.sh memcached

設定ファイルの中身を修正する

vi /service/.memcached/run

エディタが立ち上がるので以下の内容でファイルを保存する

#!/bin/sh
exec 2>&1
exec /usr/local/bin/memcached -p 11211 -u nobody  -m 64 -c 2048

memcachedを起動する

mv /service/.memcached /service/memcached

Perlの最新版の導入

PerlはシステムPerlとは別の場所に最新安定版を導入します(現時点では5.16.3)今後バージョンアップする場合は以下の手順のバージョンを差し替える事で既存バージョンに影響を与えず都度最新版を導入する事ができます

cd ~
wget http://xrl.us/cpanm
chmod 755 cpanm 
./cpanm Perl::Build
perl-build 5.16.3 /usr/local/perl-5.16.3
/usr/local/perl-5.16.3/bin/perl ~/cpanm App::cpanminus
LANG=C /usr/local/perl-5.16.3/bin/cpanm -v Crypt::SSLeay
/usr/local/perl-5.16.3/bin/cpanm Task::Plack Starman Starlet Server::Starter DBI DBD::mysql FCGI YAML Time::HiRes  IO::Socket::SSL Cache::File Crypt::SSLeay Net::LDAP Crypt::DSA Archive::Zip Authen::SASL IPC::Run GD Archive::Tar Digest::SHA1 Mail::Sendmail Web::Scraper Mail::POP3Client IO::Stringy XML::Parser Imager XMLRPC::Transport::HTTP::Plack Net::Server::SS::PreFork Cache::Memcached::Fast

Movable Typeの導入

MT用にMySQLを追加設定します

以下のコマンドを実行しMySQLに入ります

mysql -uroot -p

MTが使用するユーザ・データベースをMySQL上で作成します。以下ではmt_psgiというユーザとデータベースを作成しています。

CREATE USER 'mt_psgi'@'localhost' IDENTIFIED BY  '任意のパスワード';
GRANT USAGE ON * . * TO  'mt_psgi'@'localhost' IDENTIFIED BY  '任意のパスワード' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE DATABASE mt_psgi;
GRANT ALL PRIVILEGES ON mt_psgi . * TO  'mt_psgi'@'localhost';
FLUSH PRIVILEGES;

Movable Type設定(MTOSを使用していますがMTでも問題ありません)

mkdir -p /var/www/MTを設置するドメイン名/{htdocs,logs,cgi-bin}
cd /var/www/MTを設置するドメイン名/cgi-bin
wget https://github.com/movabletype/movabletype/archive/master.zip
unzip master
mv movabletype-master mt
cd mt
mv mt-config.cgi-original mt-config.cgi
chmod 755 mt-config.cgi
mv mt-static ../../htdocs/
find . -name '*.cgi' | xargs perl -i -ple 's{/usr/bin/perl}{/usr/local/perl-5.16.3/bin/perl}g'
chown -R nginx:nginx /var/www/MTを設置するドメイン名/

mt-configをPSGI用に修正します

vi mt-config.cgi

エディタが開くので該当箇所を以下のように修正する。画像のサムネイル生成はImagerを使用するのでImage::Magickは必要ありません

# CGIPathの行を以下のように修正
CGIPath    http://MTを設置するドメイン名/cgi-bin/mt/
ImageDriver Imager
MemcachedNamespace MTを設置するドメイン名
MemcachedDriver Cache::Memcached::Fast
MemcachedServers localhost:11211

# StaticWebPathの行を以下のように修正
StaticWebPath http://MTを設置するドメイン名/mt-static/
StaticFilePath /var/www/MTを設置するドメイン名/htdocs/mt-static/

# データベースの設定を修正
Database 作成したデータベース名
DBUser 作成したユーザ名
DBPassword 任意で設定したデータベースパスワード

# DefaultLanguage en_USを修正し言語設定を変更
#DefaultLanguage en_US
DefaultLanguage ja

PSGIサーバ Starmanの導入

以下のコマンドを実行しdaemontoolsにサービスを追加します

addsv.sh 任意のドメイン名

設定ファイルの中身を修正する

vi /service/.任意のドメイン名/run

エディタが立ち上がるので以下の内容でファイルを保存する。-s Starmanの箇所でPSGIサーバをStarmanとしていますが、これはSixApartの公式情報はStarmanになっていたからという理由だけですがStarletでも問題なく動きます。またパフォーマンスもStarletに方が若干良いようなので試してもよいかもしれません(thanks @aloelight)

#!/bin/sh
PATH=/usr/local/perl-5.16.3/bin:/usr/local/bin:/usr/bin:/bin
export PATH
exec 2>&1
cd /var/www/任意のドメイン名/cgi-bin/mt || exit 1
exec setuidgid nginx envuidgid nginx start_server --port=8080 -- plackup -s Starman -E production --workers=2 --max-reqs-per-child=10000 --interval=1 ./mt.psgi

MTを起動する

mv /service/.任意のドメイン名 /service/任意のドメイン名

プラグインを導入した場合や設定変更を行った場合は以下のコマンドでサービスに影響を与える事なくMTのリロードが可能です

svc -h /service/任意のドメイン名

run-periodic-tasksを仕込む

MTでは予約投稿などで利用する機能です

crontab -u nginx -e

エディタが起動するので以下の内容を追記する

*/5 * * * *    cd /var/www/任意のドメイン名/cgi-bin/mt; /usr/bin/setlock -nx /tmp/任意のドメイン名.lock /usr/local/perl-5.16.3/bin/perl ./tools/run-periodic-tasks

Nginxの導入

NginxをWebサーバ(静的ファイル配信)、リバースプロキシ(MT管理画面へアクセスするために)として利用します

設定ファイルの作成

vi /etc/nginx/conf.d/任意のドメイン名.conf

エディタが起動するので以下の内容でファイルを作成します

upstream psgi_servers {
    server 127.0.0.1:8080;
}

server {
    listen       80;
    server_name 任意のドメイン名;
    root /var/www/任意のドメイン名/htdocs;
    access_log  /var/www/任意のドメイン名/logs/access.log  main;
    error_log   /var/www/任意のドメイン名/logs/error.log warn;
    gzip on;

    server_tokens off;
    ignore_invalid_headers on;

    location /cgi-bin/mt/ {
        client_max_body_size 30M;
        proxy_redirect off;
        proxy_set_header    X-Forwarded-Proto $http_x_forwarded_proto;
        proxy_set_header    X-Forwarded-Host  $host;
        proxy_set_header    Host              $host;
        proxy_set_header    X-Real-IP         $remote_addr;
        proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_pass http://psgi_servers;
    }
}

Nginxのログローテーション設定

Webサーバのログを日時で90日間保存します

vi /etc/logrotate.d/nginx

エディタが開くので以下のように丸ごと修正します

/var/www/*/logs/*log {
    daily
    missingok
    rotate 90
    dateext
    compress
    delaycompress
    notifempty
    create 640 nginx adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

Nginxを再起動する

/etc/init.d/nginx restart

MTのセットアップを行う

やっとここまできました、、MTの管理画面にアクセスし設定を済ませます。http://任意のドメイン名/cgi-bin/mt/mt.cgi 特にアクセス用URLに変更はありません

MTの設定完了後に一度再起動する

svc -h /service/任意のドメイン名

リブート

全ての設定が完了しましたらテストも兼ねて一度再起動を行います。VPSなどで仮想コンソールが存在しない場合は実行しない方がよいかもしれません

shutdown -r now

以下は次回に解説したいと思います

  • 大量アクセス対策(カーネルのチューニング)
  • apacheの導入
  • PHPの導入
  • Muninの導入
  • phpmyadminの導入

まとめ

かなり長くなってしまいましたが如何だったでしょうか。途中わからない事があればなるべく対応したいと思いますのでtwitterで@onagataniまで連絡下さい(忙しい時は無理ですが)。ちなみに今回の記事作成では沢山のサイトを参考にさせて頂きました。特にこちらのページが参考になると思いますCentOSをサーバーとして活用するための基本的な設定