Edited at

王道Webサーバ構成を構築する


【概要】

この記事は王道Webサーバ構成であるLAMP環境をローカル開発環境であるVagrantを使って構築してみる記事となります。また、構築しないまでもWebプログラミングの学習をされている初学者の方は参考程度に読んでいただければと思います。


【対象者】


  • Webプログラミングを始めて数ヶ月から一年程度の初学者

  • WebサーバをLAMP環境で構築したい方


【事前知識】

Webサーバはクライアントから情報処理の依頼を受け付けたりクライアントへ情報を提供することが主な役割となる。下の配置図のようにAPサーバがリクエストを受け付けプログラムを実行し、データの取得や加工をする。その後リクエスト元にレスポンスとしてデータを返却する。

具体的な名称を上げると下記のような技術が分類されます。


  • OS ... Linux Windowsサーバ

  • APサーバ ... ApacheHTTPServer NginX Tomcat

  • 実行プログラム ... PHP Java C++

  • データベース ... MySQL Oracle NoSQL



注意点

実際に運用されているWebサービスのサーバにおいて、上記図のようなアプリケーションとデータベースが同居するような構成となっていることはほぼないと思います。外部から接続があった場合、セキュリティや負荷分散を考慮してProxyやロードバランサを経由して受信しますし、DBもアプリケーションとは切り離した別のサーバでマスター/スレーブ構成などで運用されると思います。飽くまで開発環境や低可用性を許容した小規模システムを構築する場合などの参考にしてください。


【環境構築】

Vagrantを使ってWebサーバを立て、そこにApacheやMySQLをインストールしアプリケーションプログラムと連携できるよう設定します。最後にローカルPCのブラウザから画面表示とデータ検索ができれば構築完了となります。アプリケーションプログラムはこちらのサンプルコードを使用します。


VMの起動

まずはVagrantでLinuxのVMを起動します。今回ディストリビューションはCentOS7でBOXはこちらを使用します。起動したらログインして環境を作っていきます。

[vagrant@localhost ~]$ cat /etc/centos-release

CentOS Linux release 7.5.1804 (Core)

後にyum経由でPKGをいくつかインストールするのでepelとiusのrpmをインストールしておきます。

[vagrant@localhost ~]$ sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm https://centos7.iuscommunity.org/ius-release.rpm

.
.
.

// インストールされたことを確認
[vagrant@localhost ~]$ rpm -aq | grep -E "(epel-release|ius-release)"
ius-release-1.0-15.ius.centos7.noarch
epel-release-7-11.noarch

VMの起動が完了したらログインして必要となるPKGをインストールしていきますが、まずはその前にサンプルコードをダウンロードして解凍します。

// 50MB強あるのでdownloadに5分ほどかかる

[vagrant@localhost ~]$ wget https://github.com/hys-rabbit/FindWiki/archive/master.zip
.
.
.

// zipもunzipも入ってないと思うのでインストールする
[vagrant@localhost ~]$ sudo yum install -y zip unzip
.
.
.

// ダウンロードしたzipを解凍する
[vagrant@localhost ~]$ unzip master.zip
.
.
.

上記まで終わるとFindWiki-masterというディレクトリができていると思います。

ちなみにgitでcloneする場合は下記ととなります。

// git2.0系であるgit2u-2が候補にあることを確認してインストール(git1.0系でも問題ない)

[vagrant@localhost ~]$ yum --showduplicates search git | grep -E "^git2u-2"
git2u-2.16.2-1.ius.centos7.x86_64 : Fast Version Control System
git2u-2.16.4-1.ius.centos7.x86_64 : Fast Version Control System
git2u-2.16.5-1.ius.centos7.x86_64 : Fast Version Control System

[vagrant@localhost ~]$ sudo yum install git2u-2.16.5-1.ius.centos7.x86_64 -y
.
.
.

[vagrant@localhost ~]$ git --version
git version 2.16.5

// サンプルコードのリポジトリをフォークしてクローンする
// 50MB強あるのでクローンに5分ほどかかる
[vagrant@localhost ~]$ git clone https://github.com/<yourname>/FindWiki.git
.
.
.

上記まで終わるとFindWikiというディレクトリができていると思います。


MySQLの準備

今回使用するサンプルコードではデータベースとしてMySQLを使うのでWebサーバにMySQL5.7をインストールします。手順としては公式サイトを参考にrpmをインストールした後yumでmysql-community-serverをインストールします。

// rpmをインストールする

[vagrant@localhost ~]$ sudo rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-2.noarch.rpm
.
.
.

// インストールされたことを確認する
[vagrant@localhost ~]$ rpm -aq | grep mysql
mysql80-community-release-el7-2.noarch

// yumリポジトリで有効となっているmysql-community-serverを確認するとMySQL8.0が有効となっている
// 今回は5.7を使用するので8.0を無効化し5.7を有効化する。
[vagrant@localhost ~]$ yum repolist all | grep -E "mysql.[00-99]-community"
mysql55-community/x86_64 MySQL 5.5 Community Server 無効
mysql55-community-source MySQL 5.5 Community Server - Sou 無効
mysql56-community/x86_64 MySQL 5.6 Community Server 無効
mysql56-community-source MySQL 5.6 Community Server - Sou 無効
mysql57-community/x86_64 MySQL 5.7 Community Server 無効
mysql57-community-source MySQL 5.7 Community Server - Sou 無効
mysql80-community/x86_64 MySQL 8.0 Community Server 有効: 82
mysql80-community-source MySQL 8.0 Community Server - Sou 無効
[vagrant@localhost ~]$ sudo yum-config-manager --disable mysql80-community
.
.
.
[vagrant@localhost ~]$ sudo yum-config-manager --enable mysql57-community
.
.
.
[vagrant@localhost ~]$ yum repolist all | grep -E "mysql.[00-99]-community"
mysql55-community/x86_64 MySQL 5.5 Community Server 無効
mysql55-community-source MySQL 5.5 Community Server - Sou 無効
mysql56-community/x86_64 MySQL 5.6 Community Server 無効
mysql56-community-source MySQL 5.6 Community Server - Sou 無効
mysql57-community/x86_64 MySQL 5.7 Community Server 有効: 327
mysql57-community-source MySQL 5.7 Community Server - Sou 無効
mysql80-community/x86_64 MySQL 8.0 Community Server 無効
mysql80-community-source MySQL 8.0 Community Server - Sou 無効

// mysql-community-serverをインストール
[vagrant@localhost ~]$ sudo yum install mysql-community-server -y
.
.
.
[vagrant@localhost ~]$ mysql --version
mysql Ver 14.14 Distrib 5.7.25, for Linux (x86_64) using EditLine wrapper

これでMySQL5.7をインストールすることができたので、これからはデータベースを構築していきます。

// MySQLが起動していないことを確認する

[vagrant@localhost ~]$ systemctl status mysqld.service
● mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:mysqld(8)
http://dev.mysql.com/doc/refman/en/using-systemd.html

// MySQLを起動する
[vagrant@localhost ~]$ systemctl start mysqld.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to manage system services or units.
Authenticating as: root
Password:
==== AUTHENTICATION COMPLETE ===
[vagrant@localhost ~]$ systemctl status mysqld.service
● mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: active (running) since 土 2019-03-16 12:48:19 UTC; 33s ago
Docs: man:mysqld(8)
http://dev.mysql.com/doc/refman/en/using-systemd.html
Process: 6479 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
Process: 6402 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
Main PID: 6482 (mysqld)
CGroup: /system.slice/mysqld.service
└─6482 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

// LISTENプロセスの確認に便利なlsofをインストールする
[vagrant@localhost ~]$ sudo yum install lsof -y
.
.
.

// MySQLのデフォルトポート3306とそのPIDを見てMySQLが起動していることを確認する
[vagrant@localhost ~]$ sudo lsof -i:3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 6482 mysql 22u IPv6 39113 0t0 TCP *:mysql (LISTEN)
[vagrant@localhost ~]$ ps uf 6482
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
mysql 6482 0.0 16.8 1119708 171608 ? Sl 12:48 0:00 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

// MySQLの初期パスワードを確認する
[vagrant@localhost ~]$ sudo grep 'temporary password' /var/log/mysqld.log
2019-03-16T12:48:17.038108Z 1 [Note] A temporary password is generated for root@localhost: <初期パスワード>

// MySQLにログインする
[vagrant@localhost ~]$ mysql -u root -p
Enter password: // ↑で確認した初期パスワードを入力する
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.25

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

// パスワードを初期パスワードから変更する(rootパスワードなので忘れないようにする)
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '新パスワード';
Query OK, 0 rows affected (0.00 sec)

// データベースを作成する
mysql> create database wiki;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| wiki |
+--------------------+
5 rows in set (0.00 sec)

データベースを用意したら、サンプルコードにあるDDLを実行してデータを作る。

まずはDDLのzipを解凍しよう。

// サンプルコードディレクトリに移動しDDLを解凍する。

[vagrant@localhost FindWiki-master]$ gunzip sql/ddl.sql.gz
[vagrant@localhost FindWiki-master]$ ll sql/ddl.sql
-rw-rw-r--. 1 vagrant vagrant 231879465 3月 15 12:54 sql/ddl.sql

// 早速DDLを投入する
// データ量が多いので投入完了まで数分かかる
[vagrant@localhost FindWiki-master]$ mysql -u root -p wiki < sql/ddl.sql
Enter password: // 先ほど決めたパスワード

// 最後にMySQLにログインしてデータができていることを確認する
[vagrant@localhost FindWiki-master]$ mysql -u root -p
.
.
.
mysql> use wiki
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------+
| Tables_in_wiki |
+----------------+
| namespace |
| page |
+----------------+
2 rows in set (0.00 sec)

// 263万レコードある
mysql> select count(1) from page;
+----------+
| count(1) |
+----------+
| 2637675 |
+----------+
1 row in set (0.58 sec)

これでデータベースの準備は完了です。


Apacheの準備

APサーバとなるApache2.4をインストールして起動します。ApacheはPKG名としてはhttpdとなっています。

// 一番新しいのをインストールする

[vagrant@localhost ~]$ yum --showduplicates list | grep "httpd24u\."
httpd24u.x86_64 2.4.35-1.ius.centos7 ius
httpd24u.x86_64 2.4.37-1.ius.centos7 ius
httpd24u.x86_64 2.4.38-1.ius.centos7 ius
[vagrant@localhost ~]$ sudo yum install httpd24u.x86_64 -y
.
.
.

// Apacheが停止していることを確認
[vagrant@localhost ~]$ systemctl status httpd.service
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:httpd.service(8)

// DocumentRootにviなどで下記の確認用HTMLファイルを作成する
[vagrant@localhost ~]$ cat /etc/httpd/conf/httpd.conf | grep -v "#" | grep DocumentRoot
DocumentRoot "/var/www/html"
[vagrant@localhost ~]$ cat /var/www/html/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<h1>Welcome to my page.</h1>
</body>
</html>

// Apacheを起動する
[vagrant@localhost ~]$ systemctl start httpd.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to manage system services or units.
Authenticating as: root
Password:
==== AUTHENTICATION COMPLETE ===

// 6プロセス起動している(rootは親プロセス)
[vagrant@localhost ~]$ sudo lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 14626 root 4u IPv6 54971 0t0 TCP *:http (LISTEN)
httpd 14627 apache 4u IPv6 54971 0t0 TCP *:http (LISTEN)
httpd 14628 apache 4u IPv6 54971 0t0 TCP *:http (LISTEN)
httpd 14629 apache 4u IPv6 54971 0t0 TCP *:http (LISTEN)
httpd 14630 apache 4u IPv6 54971 0t0 TCP *:http (LISTEN)
httpd 14631 apache 4u IPv6 54971 0t0 TCP *:http (LISTEN)
httpd 14688 apache 4u IPv6 54971 0t0 TCP *:http (LISTEN)

ブラウザのアドレスバーにIPを入力し閲覧してみると、確認用のHTMLファイルを参照していることがわかる。簡単だがApacheのインストールはこれまで。

image.png


PHP関連PKGのインストール

HTMLは表示できたが、このままではPHPを読み込まないのでPHP用のPKGをインストールしていきます。

// ApacheがPHPの実行やDB接続するために下記三つのPKGをインストールする

[vagrant@localhost ~]$ yum list | grep -E "(mod_php72u|php72u-pdo|php72u-mysqlnd)\."
mod_php72u.x86_64 7.2.16-1.ius.centos7 @ius
php72u-mysqlnd.x86_64 7.2.16-1.ius.centos7 @ius
php72u-pdo.x86_64 7.2.16-1.ius.centos7 @ius
[vagrant@localhost ~]$ sudo yum install -y mod_php72u.x86_64 php72u-pdo.x86_64 php72u-mysqlnd.x86_64
.
.
.
[vagrant@localhost ~]$ sudo yum list installed | grep php72u
mod_php72u.x86_64 7.2.16-1.ius.centos7 @ius
php72u-common.x86_64 7.2.16-1.ius.centos7 @ius
php72u-mysqlnd.x86_64 7.2.16-1.ius.centos7 @ius
php72u-pdo.x86_64 7.2.16-1.ius.centos7 @ius

// 下記のlibphpをApacheの設定に追加する必要があるので覚えておく
[vagrant@localhost ~]$ rpm -ql mod_php72u.x86_64
/etc/httpd/conf.d/php.conf
/etc/httpd/conf.modules.d/15-php.conf
/usr/lib64/httpd/modules/libphp7-zts.so
/usr/lib64/httpd/modules/libphp7.so // ← これ
/usr/share/httpd/icons/php.gif
/var/lib/php/mod_php
/var/lib/php/mod_php/opcache
/var/lib/php/mod_php/session
/var/lib/php/mod_php/wsdlcache


httpd.confの設定

// FindWiki直下のappディレクトリをusr下に移動して所有者をrootにする

[vagrant@localhost ~]$ sudo cp -pr FindWiki-master/app/ /usr/lib/app/
[vagrant@localhost ~]$ sudo chown root:root -R /usr/lib/app/

// 設定ファイルをコピーしバックアップとしておく
[vagrant@localhost ~]$ cd /etc/httpd/conf/
[vagrant@localhost conf]$
[vagrant@localhost conf]$ sudo cp -p httpd.conf httpd.conf.org

// viで編集し設定を追加していく
[vagrant@localhost conf]$ sudo vi httpd.conf
↓↓↓ ここからは編集する内容を記載 ↓↓↓

// mod_phpを読み込む
LoadModule php7_module /usr/lib64/httpd/modules/libphp7.so

// MySQLの設定値を記載
SetEnv DB_HOST 127.0.0.1
SetEnv DB_PORT 3306
SetEnv DB_USER <username> // 特にユーザを作っていなければroot
SetEnv DB_PASS <password> // rootユーザのパスワード

// アプリケーションディレクトリの設定する
DocumentRoot "/usr/lib/app" // /var/www/htmlだったところ

<Directory "/usr/lib/app"> // /var/www/htmlだったところ

<IfModule dir_module>
DirectoryIndex index.php // index.htmlだったところ
</IfModule>

↑↑↑ ここまでは編集する内容を記載 ↑↑↑

最終的に下記の変更ができていれば良いかと思います。

[vagrant@localhost conf]$ diff httpd.conf httpd.conf.org 

59,64d58
< # php7.2
< #
<
< LoadModule php7_module /usr/lib64/httpd/modules/libphp7.so
<
< #
121,128d114
< # Configuration value for MySQL.
< #
< SetEnv DB_HOST 127.0.0.1
< SetEnv DB_PORT 3306
< SetEnv DB_USER <username>
< SetEnv DB_PASS <password>
<
< #
133c119
< DocumentRoot "/usr/lib/app"
---
> DocumentRoot "/var/www/html"
145c131
< <Directory "/usr/lib/app">
---
> <Directory "/var/www/html">
178c164
< DirectoryIndex index.php
---
> DirectoryIndex index.html

最後にApacheを再起動してブラウザをリロードすると画面が表示されるはずです。

検索ができればDB接続もできていることとなり構築完了となります。

image.png


まとめ

下記図はブラウザからリクエストを投げてレスポンスが返ってくるまでの簡単なシーケンス図となる。



本記事は環境構築のみでプログラムの実装はなかったが、今後LAMP環境アプリのプログラムを実装することがあったら、先に記した配置図や上記のシーケンス図を思い出してほしい。自分がアプリケーションのどこで何をするプログラムを書くのかイメージすることで、本質的なプログラムの実装や課題の解決に繋げることができると思います。