デザイナー必見!VPSで高速なMovable Type用サーバをゼロから構築する方法
まだ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をサーバーとして活用するための基本的な設定。