CentOS 7 を開発環境として「いい感じ」にセットアップする

日本においても、仕事でUbuntuやDebianを使っている方が増えている印象を受けますが、RedHat系ディストリビューションの雄として、依然としてCentOSの人気も高いです。
商用環境はRedhat、開発環境はCentOS、みたいな使い方してる人は多いんじゃないでしょうか。

[The CentOS Logo](https://wiki.centos.org/ArtWork/Brand/Logo)
![centos-logo-light.png](https://qiita-image-store.s3.amazonaws.com/0/10852/1b5eab2d-1d54-e6db-0a7a-3800437ec773.png)


ただ、CentOSでシステム開発をしていると大変困る事があります。
標準リポジトリにおける各種ミドルウエアの整備です。

商用環境としてガッチリとインストールするパッケージが確定している場合は別として、開発環境へは柔軟にパッケージを導入しながら、テストも実施したい。といった時に、「UbuntuやDebianでは標準リポジリに用意されているのにCentOSには無い！」みたいな事があるとゲンナリするものです。

そんな時のために、VPSやIaaSで提供された直後のCentOS 7を対象に開発環境として「いい感じ」にセットアップしたいと思います。

この記事ではニフティクラウドで標準提供された「CentOS 7.0 64bit Plain」を対象にしていますが、内容としては他のVPSやIaaSで提供されているイメージでも流用出来ると思います。

# 構築環境

今回構築する環境はこんな感じです。

* 対象サーバ：CentOS 7.0 x86_64
* 導入リポジトリ
    * RPMforge
    * EPEL
    * Remi

キモはサードーパーティリポジトリを導入し、標準リポジトリを補完しているところです。（キモというか、コレだけやればOK）

導入するサードパーティリポジトリ紹介

* **RPMforge**
    * RPMforgeは元々CentOSの開発チームにいた [Dag Wieersさんらが公開されているリポジトリ](http://dag.wieers.com/rpm/) です
    * 本家は http://apt.sw.be/ の様ですが、今回は速度を考慮し国内ミラーの http://ftp.riken.jp/Linux/dag/ を参照させていただきます

* **EPEL**
    * EPEL(Extra Packages for Enterprise Linux)は先進的な取り組みを行っているFedoraで開発・テストされている最新のパッケージを、CentOS等のEnterpriseLinuxでも利用出来る様に取り組んでいるリポジトリです
    * 本家は http://download.fedora.redhat.com/pub/epel/ の様ですが、今回は速度を考慮し国内ミラーの http://ftp.riken.jp/Linux/fedora/epel/ を参照させていただきます

* **Remi**
    * Remiは元々Fedoraのパッケージ開発者でもあるRemiさんが、[Fedoraにも含まれない、さらに先進的なパッケージをテストするために公開しているレポジトリ](http://blog.famillecollet.com/pages/English-site-introduction)です
    * こちらは国内ミラーが見つからなかったため、本家を参照させていただきます

# とりあえずワンライナーで実行！

対象サーバへログインし、下記コマンドを実行すれば構築スクリプトがダウンロードされて一発で構築出来ます。
※実行後サーバが再起動しますのでご注意ください。

```bash
# /usr/bin/curl -s https://gist.githubusercontent.com/ysaotome/378205689c7b6ef0a6bf/raw/centos71_64bit_Plain_setup_script_for_niftycloud.sh | /bin/bash
```

# 「いい感じ」か？

ワンライナーによってリポジトリの導入前と導入後でミドルウエアの対応具合を比べてみます。

## 例として **PHP** の場合

導入前は php 5.4系しか選択出来ないのですが、導入後は php54,php55,php56というパッケージが追加されており、5.5系や5.6系をパッケージからインストールする事が可能になります。
```remi-php70``` を有効にすれば7.0系もテスト出来ます。

* 導入前
    
```bash
# yum install php
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * updates: ftp.riken.jp
依存性の解決をしています
.
.
.
依存性を解決しました

=============================================================================================
 Package              アーキテクチャー
                                      バージョン                      リポジトリー      容量
=============================================================================================
インストール中:
 php                  x86_64          5.4.16-36.el7_1                 updates          1.4 M
依存性関連でのインストールをします:
 apr                  x86_64          1.4.8-3.el7                     base             103 k
 apr-util             x86_64          1.5.2-6.el7                     base              92 k
 httpd                x86_64          2.4.6-31.el7.centos.1           updates          2.7 M
 httpd-tools          x86_64          2.4.6-31.el7.centos.1           updates           79 k
 libzip               x86_64          0.10.1-8.el7                    base              48 k
 php-cli              x86_64          5.4.16-36.el7_1                 updates          2.7 M
 php-common           x86_64          5.4.16-36.el7_1                 updates          563 k

トランザクションの要約
=============================================================================================
インストール  1 パッケージ (+7 個の依存関係のパッケージ)
```

* 導入後

```bash
# yum --enablerepo=rpmforge,epel,remi install php56
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * epel: ftp.riken.jp
 * extras: ftp.riken.jp
 * remi: rpms.remirepo.net
 * remi-safe: rpms.remirepo.net
 * rpmforge: ftp.riken.jp
 * updates: ftp.riken.jp
依存性の解決をしています
・
・
・
依存性を解決しました

=============================================================================================
 Package                      アーキテクチャー
                                             バージョン                   リポジトリー  容量
=============================================================================================
インストール中:
 php56                        x86_64         2.1-1.el7.remi               remi         3.1 k
依存性関連でのインストールをします:
 libzip-last                  x86_64         1.0.1-1.el7.remi             remi          43 k
 php56-php-cli                x86_64         5.6.13-1.el7.remi            remi         2.6 M
 php56-php-common             x86_64         5.6.13-1.el7.remi            remi         685 k
 php56-php-pear               noarch         1:1.9.5-12.el7.remi          remi         349 k
 php56-php-pecl-jsonc         x86_64         1.3.9-1.el7.remi             remi          45 k
 php56-php-pecl-zip           x86_64         1.13.1-1.el7.remi            remi          42 k
 php56-php-process            x86_64         5.6.13-1.el7.remi            remi          58 k
 php56-php-xml                x86_64         5.6.13-1.el7.remi            remi         158 k
 php56-runtime                x86_64         2.1-1.el7.remi               remi         1.1 M

トランザクションの要約
=============================================================================================
インストール  1 パッケージ (+9 個の依存関係のパッケージ)
```

```bash
# yum --enablerepo=rpmforge,epel,remi,remi-php70 install php
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * epel: ftp.riken.jp
 * extras: ftp.riken.jp
 * remi: mirrors.thzhost.com
 * remi-php70: mirrors.thzhost.com
 * rpmforge: ftp.riken.jp
 * updates: ftp.riken.jp
依存性の解決をしています
・
・
・
依存性を解決しました

=============================================================================================
 Package              アーキテクチャー
                                     バージョン                     リポジトリー        容量
=============================================================================================
インストール中:
 php                  x86_64         7.0.0-0.5.RC3.el7.remi         remi-php70         2.6 M
依存性関連でのインストールをします:
 apr                  x86_64         1.4.8-3.el7                    base               103 k
 apr-util             x86_64         1.5.2-6.el7                    base                92 k
 httpd                x86_64         2.4.6-31.el7.centos.1          updates            2.7 M
 httpd-tools          x86_64         2.4.6-31.el7.centos.1          updates             79 k
 libzip-last          x86_64         1.0.1-1.el7.remi               remi                43 k
 php-cli              x86_64         7.0.0-0.5.RC3.el7.remi         remi-php70         3.9 M
 php-common           x86_64         7.0.0-0.5.RC3.el7.remi         remi-php70         981 k
 php-json             x86_64         7.0.0-0.5.RC3.el7.remi         remi-php70          50 k
 php-pecl-zip         x86_64         1.13.1-1.el7.remi.7.0          remi-php70          50 k

トランザクションの要約
=============================================================================================
インストール  1 パッケージ (+9 個の依存関係のパッケージ)
```

## リポジトリに登録されているパッケージ数比較

登録パッケージ数はほぼ倍増（10,340→21,348）しています。

* 導入前  

```bash
# yum repolist
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * updates: ftp.riken.jp
リポジトリー ID                           リポジトリー名                              状態
base/7/x86_64                             CentOS-7 - Base                             8,651+1
extras/7/x86_64                           CentOS-7 - Extras                               214
updates/7/x86_64                          CentOS-7 - Updates                          1,475+5
repolist: 10,340
```

* 導入後  

```bash
# yum --enablerepo=rpmforge,epel,remi repolist
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * epel: ftp.riken.jp
 * extras: ftp.riken.jp
 * remi: remi.kazukioishi.net
 * rpmforge: ftp.riken.jp
 * updates: ftp.riken.jp
リポジトリー ID         リポジトリー名                                                状態
base/7/x86_64           CentOS-7 - Base                                               8,651+1
epel/x86_64             Extra Packages for Enterprise Linux 7 - x86_64                  8,519
extras/7/x86_64         CentOS-7 - Extras                                                 214
remi                    Remi's RPM repository for Enterprise Linux 7 - x86_64           2,244
rpmforge                RHEL 7 - RPMforge.net - dag                                       245
updates/7/x86_64        CentOS-7 - Updates                                            1,475+5
repolist: 21,348
```

# シェルスクリプトの説明

実行したワンライナーでは、 [GitHub](https://github.com/) の ```gist``` からシェルスクリプト [centos71_64bit_Plain_setup_script_for_niftycloud.sh](https://gist.github.com/ysaotome/378205689c7b6ef0a6bf) をダウンロードしてきて実行しています。

シェルスクリプト [centos71_64bit_Plain_setup_script_for_niftycloud.sh](https://gist.github.com/ysaotome/378205689c7b6ef0a6bf) の中身を確認してみましょう。

* 初期設定：ユーザ名、パスワード等を変数で設定
    * 元々SSH鍵認証ログインを前提としており、また、開発用途であるため適当に設定していますが、適時スクリプトをフォークやコピーするなどして変更してください。

```bash
#===============================================
# Settings
#===============================================
##rootのパスワード
ROOT_PASSWORD='hoge##123'
##追加する管理ユーザ名
USER_NAME='hoge'
##管理ユーザのパスワード
USER_PASSWORD='hoge##123'
#===============================================
ARC=$(/bin/uname -m)
SALT=$(/usr/bin/uuidgen| /usr/bin/tr -d '-')
```

* ホスト名変更：サーバ名を取得してホスト名として設定
    * vmware-tools導入済みのVMware環境における仮想マシンでは、仮想マシン名を ```vmtoolsd --cmd 'info-get guestinfo.hostname'``` で取得出来るので、その名前をホスト名として設定しています。

```bash
HOSTNAME=$(/usr/bin/vmtoolsd --cmd 'info-get guestinfo.hostname')
/bin/hostname ${HOSTNAME}
/bin/sed -i.org -e 's/localhost.localdomain/'${HOSTNAME}'/' /etc/hostname
```

* rootパスワード変更：rootユーザのパスワードを変更

```bash
/usr/sbin/usermod -p $(/usr/bin/perl -e 'print crypt(${ARGV[0]}, ${ARGV[1]})' ${ROOT_PASSWORD} ${SALT}) root
```

* 管理ユーザ追加と設定：rootユーザに代わる管理ユーザを追加

```bash
/usr/sbin/useradd -G 100 -p $(/usr/bin/perl -e 'print crypt(${ARGV[0]}, ${ARGV[1]})' ${USER_PASSWORD} ${SALT}) -m ${USER_NAME}
/bin/mkdir -p -m 700 /home/${USER_NAME}/.ssh
/bin/cp /root/.ssh/authorized_keys /home/${USER_NAME}/.ssh/.
/bin/chown -R ${USER_NAME}:${USER_NAME} /home/${USER_NAME}/.ssh
```

* ssh経由でのrootユーザ直接ログイン禁止：管理ユーザのみssh経由での直接ログインを許可

```bash
/bin/sed -i.org -e 's/^PermitRootLogin .*/PermitRootLogin no/g' /etc/ssh/sshd_config
```

* サードパーティリポジトリを追加：RPMforge

```bash
/bin/rpm --import http://ftp.riken.jp/Linux/dag/RPM-GPG-KEY.dag.txt
/bin/rpm -ivh http://ftp.riken.jp/Linux/dag/redhat/el7/en/${ARC}/rpmforge/RPMS/rpmforge-release-0.5.3-1.el7.rf.${ARC}.rpm
/bin/sed -i.org -e "s/enabled.*=.*1/enabled=0/g" /etc/yum.repos.d/rpmforge.repo
```

* サードパーティリポジトリを追加：EPEL

```bash
/bin/rpm --import http://ftp.riken.jp/Linux/fedora/epel/RPM-GPG-KEY-EPEL
/bin/rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/7/${ARC}/e/epel-release-7-5.noarch.rpm
/bin/sed -i.org -e "s/enabled.*=.*1/enabled=0/g" /etc/yum.repos.d/epel.repo
 ```

* サードパーティリポジトリを追加：Remi

```bash
/bin/rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
/bin/rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
/bin/sed -i.org -e "s/enabled.*=.*1/enabled=0/g" /etc/yum.repos.d/remi.repo
```

* ツールセットアップ
    * 便利なコマンドをインストールします。
        * zsh
        * screen
        * vim-enhanced
        * chrony
        * git
        * figlet
        * htop
        * sysstat
        * dstat
        * net-snmp
        * java

```bash
/usr/bin/yum --enablerepo=rpmforge,epel,remi -y install zsh.${ARC} screen.${ARC} vim-enhanced.${ARC} chrony.${ARC} git.${ARC} figlet.${ARC}
/usr/bin/yum --enablerepo=rpmforge,epel,remi -y install htop.${ARC} sysstat.${ARC} dstat.noarch net-snmp.${ARC} java-1.8.0-openjdk.${ARC}
```

* zshとscreenの設定ファイル取得

```bash
/usr/bin/wget --no-check-certificate -P /home/${USER_NAME}/ 'https://gist.github.com/ysaotome/1336176/raw/8ec9767aaaaec88cbe8c2b4a4092f16d7839c77b/.screenrc'
/usr/bin/wget --no-check-certificate -P /home/${USER_NAME}/ 'https://gist.github.com/ysaotome/1336176/raw/0388bb029061783bcb2d8bbd3218b04ac4b29ba4/.zshrc'
/bin/chown -R ${USER_NAME}:${USER_NAME} /home/${USER_NAME}/.screenrc /home/${USER_NAME}/.zshrc
/bin/ln -s /home/${USER_NAME}/.screenrc /root/
/bin/ln -s /home/${USER_NAME}/.zshrc /root/
/usr/sbin/usermod -s /bin/zsh root
/usr/sbin/usermod -s /bin/zsh ${USER_NAME}
```

* update-motd設置
    * 詳細は過去記事 [サーバログイン時にカッコイイメッセージを表示する（CentOS 7.1編）](http://qiita.com/ysaotome/items/09dddc9f1efae3065d15) 参照

```bash
/usr/bin/wget --no-check-certificate -O /usr/local/bin/screenfetch https://raw.githubusercontent.com/KittyKatt/screenFetch/master/screenfetch-dev
/bin/chmod 755 /usr/local/bin/screenfetch

/usr/bin/wget --no-check-certificate -P /usr/local/bin/ 'https://gist.github.com/ysaotome/5997652/raw/fecdf757b348debfcdd866df00f6d567ff749623/update_motd_by_screenfetch.sh'
/bin/chmod 755 /usr/local/bin/update_motd_by_screenfetch.sh
/usr/local/bin/update_motd_by_screenfetch.sh
/bin/cat << _UPDATEMOTD_ > /etc/cron.d/update-motd
#update-moted
*/5 * * * * root /usr/local/bin/update_motd_by_screenfetch.sh
_UPDATEMOTD_
```


* 時刻同期設定

```bash
/usr/bin/vmware-toolbox-cmd timesync disable
/bin/sed -i.org -e "s/^server /#server /g" /etc/chrony.conf
/bin/cat << _NTPDCONF_ >> /etc/chrony.conf
server ntp.nict.jp iburst
server ntp1.jst.mfeed.ad.jp iburst
server ntp2.jst.mfeed.ad.jp iburst
server ntp3.jst.mfeed.ad.jp iburst
_NTPDCONF_
/usr/bin/systemctl enable chronyd
/usr/bin/systemctl restart chronyd
/usr/bin/chronyc sources
```

* snmpdの設定
    * これはニフティクラウド固有の設定なので、異なる環境の場合は無視して問題ありません
    * この設定をする事でコントロールパネルから標準監視機能を利用出来る様になります
    * by http://cloud.nifty.com/snmp/

```bash
/bin/cp -p /etc/snmp/snmpd.conf{,.org}
/bin/cat << _SNMPDCONF_ >>/etc/snmp/snmpd.conf
rocommunity niftycloud 10.100.0.14 .1.3.6.1.
rocommunity niftycloud 10.100.8.15 .1.3.6.1.
rocommunity niftycloud 10.100.16.13 .1.3.6.1.
rocommunity niftycloud 10.100.32.15 .1.3.6.1.
rocommunity niftycloud 202.248.175.141 .1.3.6.1.
rocommunity niftycloud 10.100.48.13 .1.3.6.1.
rocommunity niftycloud 175.184.41.60 .1.3.6.1.
rocommunity niftycloud 10.100.64.11 .1.3.6.1.
rocommunity niftycloud 10.100.64.12 .1.3.6.1.
rocommunity niftycloud 202.248.45.254 .1.3.6.1.
rocommunity niftycloud 10.100.128.14 .1.3.6.1.
rocommunity niftycloud 10.100.144.15 .1.3.6.1.
rocommunity niftycloud 10.102.0.31 .1.3.6.1.
rocommunity niftycloud 175.184.41.114 .1.3.6.1.
rocommunity niftycloud 175.184.41.115 .1.3.6.1.
rocommunity niftycloud 10.104.0.31 .1.3.6.1.
rocommunity niftycloud 103.233.199.104 .1.3.6.1.
rocommunity niftycloud 103.233.199.105 .1.3.6.1.
rocommunity niftycloud 10.101.0.21 .1.3.6.1.
disk / 10000
_SNMPDCONF_
/usr/bin/systemctl enable snmpd
/usr/bin/systemctl restart snmpd
```

* NIFTY Cloud API Tools の設定
    * これはニフティクラウド固有の設定なので、異なる環境の場合は無視して問題ありません
    * この設定を行う事で、コマンドラインからニフティクラウドのAPIを利用した操作が可能になります

```bash
/usr/bin/wget -P /home/${USER_NAME}/ 'http://cloud.nifty.com/api/sdk/NIFTY_Cloud_api-tools.zip'
/usr/bin/unzip -d /home/${USER_NAME}/ /home/${USER_NAME}/NIFTY_Cloud_api-tools.zip
/bin/rm -rf /home/${USER_NAME}/NIFTY_Cloud_api-tools.zip
/bin/rm -rf /home/${USER_NAME}/NIFTY_Cloud_api-tools/bin/*.cmd
/bin/chown -R ${USER_NAME}:${USER_NAME} /home/${USER_NAME}/NIFTY_Cloud_api-tools/
/bin/chmod 755 /home/${USER_NAME}/NIFTY_Cloud_api-tools/bin/*

/bin/cat << _NCSSCONF_ >> /home/${USER_NAME}/.zshrc
## NIFTY Cloud API Settings
export NIFTY_CLOUD_HOME=/home/${USER_NAME}/NIFTY_Cloud_api-tools/
export PATH=\${PATH}:\${NIFTY_CLOUD_HOME}/bin
export JAVA_HOME=/usr/lib/jvm/jre

_NCSSCONF_
```

* カーネルアップデートの制約を一時的に開放
    * カーネルアップデートは不測の事態を招く事があるため、通常時は不意にアプデートしない様にしてありますが、一時的に開放してカーネルアップデートを有効にした状態でアップデートを実行します

```bash
/bin/sed -ie 's/exclude=/#exclude=/' /etc/yum.conf

/usr/bin/yum --enablerepo=rpmforge,epel,remi -y update
/bin/sed -ie 's/#exclude=/exclude=/' /etc/yum.conf
```

* カーネルアップデートをしたので再起動します

```bash
/usr/bin/vmtoolsd --cmd 'info-set guestinfo.set_user_data 0'
/sbin/shutdown -r now
```

以上です。


# 余談
## VPSやIaaSが持つサーバ起動時実行スクリプトを利用すると一層便利

最近のVPSやIaaSでは、サーバ起動時や再起動時にシェルスクリプトを実行出来る機能があります。
こういった機能を利用すれば、OSへログインする事無くセットアップを実行する事が出来ます。

例えば、ニフティクラウドのコントロールパネルでは、サーバ作成時にフォームへスクリプトを直接記載するか、ファイルに記載した物をアップロードする事が出来ます。

例としてニフティクラウドの [サーバ起動時スクリプト](http://cloud.nifty.com/service/svscript.htm) 機能を利用した場合はこんな感じになります。

* 入力するスクリプト  

    ```bash
#!/bin/bash
/usr/bin/curl -s https://gist.githubusercontent.com/ysaotome/378205689c7b6ef0a6bf/raw/centos71_64bit_Plain_setup_script_for_niftycloud.sh | /bin/bash
```

* 入力例　　
![Imgur](http://i.imgur.com/hbGV29w.png)


サクっとこれだけで、セットアップした状態でログインが可能となります。