この記事では、Vagrantで管理しているVirtualBox上のCentOS 7にPHP 7の開発環境を整えるまでを紹介します。WEBサーバアプリケーションはApache 2.4、データベース管理システムはMySQL 8を導入します。

公開日時:2021/05/04 13:23 最終更新:2021/06/09 22:16   サーバー
Apache CentOS MySQL PHP Vagrant VirtualBox

CentOS上にPHPの開発環境を作成する

この記事は以下の2つの記事、

で、VirtualBox上にCentOS 7がインストールされている事を前提としています。

CentOSの初期設定

CentOS 7を更新する

上記の2記事を終えた直後のCentOS 7は、Boxファイルが作成されてから時間が経っている為に古く、セキュリティの観点等から好ましくありません。そこで、CentOSのパッケージマネージャ『yum(ヤム)』を使ってCentOS 7自身を最新の状態にしていきましょう。

まず、Vagrantfileのあるディレクトリ(フォルダ)でシェルを起動してください(※Shiftキーを押しながら右クリックで開くコンテキストメニューで『PowerShellウィンドウをここで開く』です)。

開いたシェルで以下のコマンドで仮想マシンを起動します。

vagrant up

仮想マシンの起動

次に、ssh接続で仮想マシンにログインします。

vagrant ssh

sshログイン

ここで、yumを使ってCentOS 7自身のアップデートを行います。sudoは、管理者権限でコマンドを実行する為のコマンドで、Vagrantでインストールした際に作成されているデフォルトユーザvagrantはsudoを実行できるユーザとして作成されています。

sudo yum update

最初に、アップデート可能なパッケージの検査が始まります。

yum update中

アップデート可能なパッケージの検査が終わると、アップデートを行ってもよいか確認のためにプロンプトが返って処理が一時停止します。yを入力してエンターキーを押してください。実際のアップデート処理が走ります。

update確認

結構時間がかかりますが、Windowsと違ってアップデートされるパッケージの総数と、今処理されているのが幾つ目のパッケージなのか分かるため、あとどのくらい時間が掛かりそうかの推測が立て易く、ストレスは少ない筈です。

パッケージのアップデート処理

Complete!と表示されてコマンドプロンプトが返ってくれば、アップデート完了です。

アップデート完了

sudoコマンド脆弱性有無の確認

先ほどyum updateを実行する際に使ったsudoコマンドですが、実はつい最近、2021年1月26日に重大な脆弱性(ソフトウェアの欠陥)が報告されています。

詳しい内容はsudoの脆弱性(CVE-2021-3156)に関する注意喚起ですが、この脆弱性が存在するかは以下のコマンドの実行結果で分かります。

sudoedit -s /

上記コマンドの実行結果が

sudoedit: /: not a regular file

であった場合は脆弱性が存在するので対処が必要です。

この記事の最初の状態、つまりBoxファイルcentos/7を使ってインストールした直後の状態では公開時期の問題から当然CVE-2021-3156が存在していました。

しかし、現在はyum updateを実行する事でこの脆弱性対応済みのsudoへと自動でアップデートされます。ですから上記コマンドで確認すると、このようなメッセージが表示される筈です。

sudoの脆弱性確認

rootパスワードを設定する

Linuxの管理者アカウントであるrootにパスワードを設定します。

sudo passwd root

タイムゾーンを設定する

Boxファイルcentos/7では、タイムゾーンが協定世界時(UTC)に設定されています。

timedatectl

現在のタイムゾーン

これを、日本標準時(JST)に変更します。

sudo timedatectl set-timezone Asia/Tokyo

日本標準時にタイムゾーンを変更

時刻の同期

以下のコマンドでNTPサーバを起動し、時刻の同期を行います。

sudo systemctl start chronyd

ファイアーウォールの無効化

generic/centos7でインストールされたCentOSでは、初期状態でファイアーウォールが有効になっています。

許可されているのはSSH接続のみで、これからApacheやMySQLをインストールしてもそのままでは外部に公開できません。

本番環境ではファイアーウォールで使用する通信プロトコルを許可するのですが、現在構築しているのはローカルの開発環境であるため、余計なトラブルが起きないように一旦ファイアーウォールを無効にします。

ファイアーウォールを無効にするには以下のコマンドを実行してください。

sudo systemctl stop firewalld
sudo systemctl disable firewalld

スナップショットの作成

さて、ここまで行ったら、またスナップショットを作成しておきましょう。そうすれば、このあと様々なパッケージをインストールしていて失敗してもいつでも現在の状態に戻ってくる事ができます。

スナップショットの作成

PHPの導入

まず、yumでインストールされるPHPパッケージのバージョンを確認します。

yum list available | grep php

yumでインストールされるPHP関連パッケージのリスト

5.4.16のようです。かなり古いですね。CentOSはRed Hat Enterprise Linux(RHEL)のクローン製品であり、RHELは商業用の堅牢なLinuxであるため、公式にサポートしているパッケージは十分な検証が終わっており安定している物が選択される傾向にあります。

このためCentOSはDebian系のLinuxと比べると、デフォルトで入るパッケージのヴァージョンが古い事がよくあります。

そこで、PHP 7.4がインストールできるように別のリポジトリ(ソースコード等を管理する場所)を認識させます。

EPELリポジトリの追加

EPEL リポジトリとは、CentOS 標準のリポジトリでは提供されていないパッケージを、yum コマンドでインストールできるようにする為のリポジトリのことです。CentOS 7の場合、このリポジトリの追加自体もyumで提供されています。

sudo yum install epel-release

EPELリポジトリの追加

remiリポジトリの追加

remiリポジトリはCentOS標準ではない、所謂サードパーティーが提供しているリポジトリの一つで、PHPスタックの最新バージョン、フル機能、およびその他のソフトウェアを、FedoraおよびEnterprise Linux(RHEL、CentOS、Oracle、Scientific Linuxなど)のユーザーに提供する為のリポジトリです。

公式サイト:Remi's RPM repository

こちらのリポジトリの追加はyumでは提供されておらず、rpm(RHEL系のLinuxでの標準のパッケージ管理コマンド)を使います。rpmは1つのパッケージに対して管理を行いますが、前述のyumはこれらrpmでの管理を総合的に取り扱い、複数のパッケージについて1つのコマンドで集中管理出来るようにしています。ですから通常、yumコマンドを実行すると裏側で複数のrpmコマンドが実行されている事になります。

今回は理化学研究所のミラーサイトを利用してみましょう。今年のNHK大河ドラマ『青天を衝け』の主人公『渋沢栄一』さんが1917年(大正6年)に設立した国民的研究所ですね。

sudo rpm -ivh http://ftp.riken.jp/Linux/remi/enterprise/remi-release-7.rpm

RIKEN.JP

rpm実行結果

インストール可能なPHPパッケージを再確認

EPELとremiの2リポジトリを追加したので、再度、インストール可能なPHPのバージョンを確認してみます。今回はremiリポジトリを追加した事で膨大なリストが表示されるため、grepのパラメタについてphp..-php.x86_64として、PHP本体パッケージのみに絞り込みを行います。(※ . は、任意の1文字の意)

yum list available | grep php..-php.x86_64

インストール可能なPHPパッケージ

CentOSが標準でサポートしているPHP 5.4から、最新版であるPHP 8.0までインストールが可能になりました。

PHP 7.4をインストールする

今回は、PHP 7.4をインストールします。

まず、インストール可能なパッケージのリストを見て必要なパッケージを見繕います。後で別のパッケージを追加する事も出来ますので、必ずしも全てを網羅している必要はありません。

yum list available | grep php74

php php-cli php-common php-devel php-mbstringといった基本パッケージに加え、PHPの画像処理用ライブラリ(GD)を提供するphp-gd、データベースMySQL及びPostgreSQL用ドライバ、データベースアクセスの為の抽象化ライブラリ(PDO)を提供するphp-pdo、JSONとXMLを扱うためのphp-json、php-xml、暗号化されたPHPソースコード用ローダーphp-ioncube-loaderを入れておきます。

そして、現在のPHPにとっては一番重要な拡張モジュールであるOPcache(オペキャッシュ:コンパイル済みバイトコードをメモリにキャッシュして処理の高速化を図るモジュール)を提供するphp-opcacheは必ず入れましょう

同様に、現在のPHPの開発では様々な便利なライブラリを導入する手段として、Composerというパッケージマネージャを使うのが当たり前になっています。これを利用しないのはもう考えられないので、絶対にインストールしておきましょう

sudo yum install --enablerepo=remi,remi-php74 php php-cli php-common php-devel php-opcache php-mbstring php-gd php-mysqlnd php-pgsql php-pdo php-json php-xml php-ioncube-loader composer

インストールされるパッケージの確認

インストールされるパッケージ一覧が表示されるので確認し、よければyを入力してください。

PHPインストール完了

PHPのバージョン確認コマンドを使って、インストール状況を確認します。

php -v

PHPのインストール状況確認

PHP設定ファイルの編集

PHPはインストール直後の初期状態ではタイムゾーンが設定されていません。以下のPHPコマンドを実行してみると、協定世界時(UTC)の時刻が表示されます。

php -r "echo date('Y-m-d H:i:s') . PHP_EOL;"

時刻確認

そこで、PHPの設定ファイルを修正して日本標準時(JST)が表示されるようにします。

設定ファイルは/etc/php.iniです。CentOSでの標準的なテキストエディタはVimなので、Vimで編集できるようになるのが一番良いですが、操作方法に結構クセがあります。

参考:Vimの使い方 よく使うコマンドまとめ | Memo on the Web

sudo vi /etc/php.ini

※viコマンドを使っていますが、現在のCentOSのviコマンドはvimコマンドのエイリアスとなっています。

/etc/php.ini

php.ini

ファイルが開いたら、/キーを押してください。画面下にカーソルが移動し、後方検索モードになります。

検索モード

ここで、date.timezoneと入力してエンターキーを押すと、PHPのタイムゾーン設定の箇所にカーソルがジャンプします。

timezone設定

Vimではテキストを編集する際にはインサートモードに切り替える必要があります。iキーを押してください。画面下に黄色い文字で-- INSERT --と表示されます。

INSERTモード

この状態でdate.timezoneの行頭のセミコロン;を削除し、値としてAsia/Tokyoを入力します。

[Date] 
; Defines the default timezone used by the date functions 
; http://php.net/date.timezone 
;date.timezone = 
       ↓ 
[Date] 
; Defines the default timezone used by the date functions 
; http://php.net/date.timezone 
date.timezone = Asia/Tokyo 

同様に、以下の項目を検索して設定してください。

前述した/での検索はカーソルのある場所から下方向へ向かっての検索の為、カーソルよりも上にある文字はヒットしません。

その場合はggとタイプするとカーソルをファイルの先頭に移動出来るので併用してください。

session.use_strict_mode = 1
session.cookie_secure = 0
mbstring.language = Japanese
mbstring.detect_order = UTF-8,SJIS-WIN,SJIS,EUC-JP,JIS,ASCII
mbstring.encoding_translation = 0
mbstring.substitute_character = none
post_max_size = 100M
upload_max_filesize = 50M
max_file_uploads = 50

参考:『PHP: セッションに関連する INI 設定をセキュアにする - Manual

参考:『PHP: 実行時設定 - Manual

参考:『PHP: コア php.ini ディレクティブに関する説明 - Manual

編集し終わったらESCキーを押して、INSERTモードを抜けます。

変更を反映して保存する場合は、Shiftキー+ZZ(Zを2回押す)です。

※尚、変更した修正を反映せずにファイルを閉じたい場合は:q!と順番にタイプしてエンターを押してください。

もう一度、現在時刻を表示させてみましょう。

php -r "echo date('Y-m-d H:i:s') . PHP_EOL;"

日本標準時表記

これで、タイムゾーン設定が完了しました。

Apacheの導入

Apacheのインストール

次はWEBサーバの代名詞とも言うべきアプリケーションであるApacheの導入です。

現在は、より新しいWEBサーバアプリケーションであるNginX(エンジンエックス)が台頭してきていますが、ApacheとNginXは得意分野が違っていて、NginXは静的なページを大量に捌くような用途に向いています。

ですから、PHPに限らずプログラムを使って動的なサイトを構築するような場合はApacheの方が向いており、NginXはApacheの前に置いて静的コンテンツと動的コンテンツを振り分けるロードバランサーのような使い方をするのが最も効果的です。

さて、では実際にApacheをインストールしていきますが、CentOSでのApacheのパッケージ名はhttpdです。インストールはやはりyumを使います。

sudo yum install httpd httpd-devel

httpdの情報

なお、httpddは、daemon(デーモン)のdです。daemonの意味は守護神で、UnixやLinuxに於いてバックグラウンドで常に稼働しているアプリケーションの事をデーモンと呼びます。Windowsでは似たようなアプリケーションの事をService(サービス)と呼んでいます。

英語ではdemon(悪魔)とdaemon(守護神)を分けて考えていますが、元々の語源はギリシア神話にでてくるダイモン《神々と人間の間に介在する二次的な神》のようです。ですから、demonもdaemonも、発音記号は全く同じdi:mʌn(英:díːmən)です。

インストールされるバージョンは2.4.6のようですね。問題ないのでyを入力して実行します。

httpdインストール完了

インストール状況確認です。

httpd -v

httpdインストール状況確認

インストールされたApacheのステータスを確認してみましょう。

systemctl status httpd

Apacheのステータス確認

inactive(dead)となっていて、稼働していない事が分かります。WEBブラウザからhttp://192.168.33.10/にアクセスしてみましょう。接続が拒否されます。

ブラウザでのアクセス

それでは、Apacheを起動してみます。

sudo systemctl start httpd
systemctl status httpd

Apacheの起動

状態がactive(running)に変わりました。もう一度http://192.168.33.10/にアクセスしてみると…、

Apacheのデフォルトドキュメント

Apacheが動作している事が分かります。

WEBで公開するディレクトリの設定

Apacheをインストールすると、/varの中に/var/wwwというディレクトリが作られ、更にその中に/var/www/cgi-binと/var/www/htmlが作られています。

/var/wwwディレクトリ

まず、このディレクトリ配下のファイルおよびディレクトリの所有者をvagrant、グループをapacheにします。apacheはApacheのユーザID及びグループIDです。

sudo chown -R vagrant:apache /var/www

/var/wwwディレクトリの所有権を変更

chownはファイルやフォルダの所有権の変更コマンドです。-Rオプションは、指定したディレクトリ配下にあるすべてのファイルおよびディレクトリの所有権を再帰的に変更する為のオプション、vagrant:apacheは、ユーザID:グループIDです。

これで、ホストOSからvagrantユーザーとして/var/wwwディレクトリ内にファイルをアップロード出来るようになります。

ただし、/var/wwwの所有者をvagrant:vagrantにしてしまうと、Apacheからディレクトリ内に新たなファイルを作成したり削除したりといった事が出来なくなってしまいます。

ですから、/var/wwwの所有者はvagrant:apacheとします。

最後に、グループのパーミッション(操作権限)を変更します。現在のグループのパーミッションはr-xで、読み込み及び実行のみ、つまり書き込みや削除権限がありません

Apacheのモジュールとして動作しているPHPはApacheの操作権限でファイル操作を行う為、この状態だとアップローダーのようなファイルを生成するアプリケーションが作れません。

そこで、以下のコマンドでグループ(apache)に対して、書き込み権限(w)を追加します。

sudo chmod -R g+w /var/www

chmodは、パーミッション(操作権限)を設定するコマンドです。

これで、Apacheからも/var/www内に対してファイルの書き出し、ファイルの削除等が出来るようになりました。

なお、パーミッション(操作権限)については、以下を参照してください。

参考:『chmodのパーミッション変更で「u+w」などの文字列指定をしたい - ITmedia エンタープライズ

MySQLの導入

MySQLは、世界で一番利用されているデータベースアプリケーションです。大規模な商業用途の場合は古くから利用されている堅牢なデータベースであるOracleが利用されるケースが多いのですが、中小規模からホビーユースまでを含めた場合、世界で一番利用されているWEBアプリケーションであるWordpressのデフォルトデータベースとなっているMySQLが、実は、世界で一番利用されているデータベースとなります。

歴史

このMySQLは元々はスウェーデンの企業であるMySQL AB社が所有、出資していたものをSun Microsystems社が買収、同社の管理下にありましたが、2010年にOracle社がSunを買収した事により、現在はOracle社の製品となって更なる高機能化が進められています。

Oracle社は既に自社プロダクトであるOracleを所有しておりそのOracle社にMySQLが買収された事で、『MySQLが飼い殺しにされるのではないか?』という懸念が世界中に広まりました。

そこで、元々の開発者であるMichael Widenius氏の手によって当時の安定版であったMySQL 5.5をフォーク(派生プロダクトを作る事)され、新たなデータベースである『MariaDB』がリリースされました。

この為、MySQLとMariaDBはほとんどの部分において全く同じ操作が可能です。今後、万が一Oracle社が独占的な権利を主張するようなライセンス規約の変更を行った場合、非常に多くのシステムのデータベースがMariaDBへと乗り換えられる事になるでしょう。

MariaDBライブラリの削除

とはいえ、ここでは主プロダクトであるMySQLのGPL版、Community Editionをインストールします。理由は、まだまだWEB上にはMySQLの情報の方が多く、初学者がMariaDB特有の機能でつまづくのを防ぐ為です。

CentOS 7では、前述の歴史にある理由からMariaDB関連のライブラリが入っています。以下のコマンドで、そのライブラリの存在を確認できます。

yum list installed | grep mariadb

MariaDBのライブラリ確認

インストールされている事を確認したら、このライブラリをyumで削除します。ライブラリ用に作成されているディレクトリも一緒に削除しておきます。

sudo yum remove mariadb-libs

以下のコマンドで、mariadbライブラリ用のディレクトリも削除しておきます。(※MySQLをフォークしたプロジェクトの為、ディレクトリ名等様々な場所でmysqlの表記が使われています。)

rm -rf /var/lib/mysql/

MariaDBライブラリの削除

インストールの為のリポジトリ設定

これで、晴れてMySQLをインストール出来るようになります。

まず、MySQL 8.0をインストールする為のリポジトリを調べます。

MySQL Community Downloads

MySQL :: Download MySQL Yum Repository

上記サイトの情報を元に、PHPの導入でremiリポジトリを追加した時と同様に、今度はdev.mysq.comのリポジトリを追加します。

sudo rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm

MySQLリポジトリの追加

以下のコマンドで、インストール可能なMySQLの種類が確認できます。

yum repolist all | grep mysql

インストール可能なMySQL関連パッケージリスト

yum installを実行するとenabledとなっているパッケージがインストールされます。上記の状態ではMySQL 8.0 Community Serverがインストールされる事になります。

MySQL 8.0のインストール

yumでMySQLをインストールするコマンドは以下です。

sudo yum install mysql-community-server

mysqlインストール確認

yを入力してインストールします。

インストール完了

インストールされたMySQLのバージョン確認は以下です。CentOSではMySQLはmysqldとして認識しています。

mysqld --version

MySQLのヴァージョン確認

MySQLを起動する

まず、MySQLを起動します。

sudo systemctl start mysqld

デフォルトのrootパスワードを調べる

MySQLの初回起動時に、デフォルトのrootパスワードが設定されます。以下のコマンドでこのデフォルトrootパスワードを調べる事が出来ます。

sudo grep password /var/log/mysqld.log

MySQLの初期設定

以下のコマンドを実行して初期設定を行います。

sudo mysql_secure_installation

rootパスワードが聞かれるので、先ほど調べたデフォルトのrootパスワードを入力してください。

Securing the MySQL server deployment.
 
Enter password for user root:

新しく設定したいrootユーザのパスワードを聞かれます。入力すると、入力間違いが無いか確認する為に同じパスワードの再入力を求められます。

間違いが無ければ新しいパスワードを有効にしてもよいか聞かれるのでYを入力してください。

The existing password for the user account root has expired. Please set a new password.
 
New password: 
 
Re-enter new password:
The 'validate_password' component is installed on the server.
The subsequent steps will run with the existing configuration
of the component.
Using existing password for root.

パスワードが一致すると入力したパスワードの暗号化が行われ、rootパスワードを変更しても良いか聞かれます。Yを入力して下さい。

Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y 

次はデフォルトで登録されているanonymous user(匿名ユーザー)を削除するかどうか聞かれます。セキュリティ上のリスクになりうるので、anonymousユーザーは削除してしまいましょう。Yを入力してください。

By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.
 
Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y
Success.

次はrootユーザーのリモートログインを禁止するかどうかを聞かれます。別からrootユーザとしてログインを許可すると不正アクセスされた場合に非常に危険なので、これは禁止します。リモートからroot権限で操作したい場合はまずSSH等を使ってホストコンピュータにログインし、ホスト内でrootユーザーとしてMySQLにログインするようにします。

Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.
 
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y
Success.

次に、testデータベースを削除するかどうか聞かれます。有っても無くても特に困らないデータベースなので、余計なセキュリティリスクを考慮から外すため、削除してしまいましょう。

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.
 
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y
 - Dropping test database...
Success.
 
 - Removing privileges on test database...
Success.

最後に、今設定した権限を直ちに確定するか聞かれます。Yを入力して確定させてください。

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.
 
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y
Success.
 
All done!

初期設定は以上です。

初期設定を確認する為、MySQLにrootユーザーでログインします。

mysql -u root -p

MySQLにログイン

ステータスコマンドで状態を見ます。

status

MySQLのステータス

MySQLからログアウトする場合は以下のコマンドです。

 \q

ApacheとMySQLを自動起動するようにする

現在の状態ですと、OSを再起動する度にApacheとMySQLのデーモンは停止してしまいます。

CentOSではsystemctlのenableを使って、OS起動時にデーモンを自動起動させる事が出来ます。

sudo systemctl enable httpd
sudo systemctl enable mysqld

デーモンの自動起動化

SELinuxの無効化

SELinuxは、Linuxに高度なセキュリティを導入するための仕組みです。

現在のCentOSはデフォルトで有効となっていますが、この機能は少々難解で初心者にはあまり適切ではありません。この機能があるおかげで助かる事は稀ですが、初学の段階ではこの機能があるせいで意図した動作にならない事が頻繁に発生します。

元々Unix、Linuxにはオーナーやパーミッションといった高度なセキュリティが導入されている為、通常はSELinuxの恩恵を受ける事は殆どありません。特に、閉鎖されたローカル環境のみ、自分しか利用しないのであれば必要無いので、現段階ではこの機能を無効にします。

設定ファイルの編集

以下のコマンドで、SELinuxの設定ファイルを開きます。

sudo vi /etc/selinux/config
/etc/selinux/config
#SELINUX=enforcing
SELINUX=disabled

SELinuxの無効化

サーバの再起動

sudo reboot

再起動後の再確認

getenforce

Disabledと表示されれば、SELinuxは無効になっています。

スナップショットの作成

必要であれば、ここで再びスナップショットを作成しておきましょう。

まとめ

以上で、CentOS自体の更新、および、PHP、Apache、MySQLの導入の説明を終わります。

これでPHPによるWEBアプリケーションの開発環境が整った事になりますが、開発を更に便利にする為に、次のドキュメント『ホストOSとゲストOSでフォルダを共有する』でSSH接続を使った安全なファイル転送の仕組みであるSFTPを導入して更に開発効率を上げてみようと思います。

記事リンク