🕌

MAMPとWebサーバーの仕組みを徹底解説 - Apache、PHP、Railsの違いまで"

に公開

はじめに

最近、原点に帰って、いろいろな、なぜ?と思うことを調べまくっています。
この記事では、MAMPの仕組みからWebサーバーの基本、そしてなぜRailsアプリが共用レンタルサーバーで動かないのかまで、体系的に解説します。

「MAMPを使ったことはあるけど、中で何が起きているか分からない」という方に最適な内容です。

MAMPとは?

MAMPは以下の頭文字を取った略称です。

  • MacOS
  • Apache
  • MySQL
  • PHP

Webアプリケーションの開発環境を簡単に構築できるソフトウェアパッケージです。

各コンポーネントの役割

Apache(アパッチ)

役割: Webサーバーソフトウェア

  • HTTPリクエストを受け取る
  • HTMLファイルやPHPファイルをブラウザに返す
  • デフォルトでポート80(HTTP)や8888などで待ち受ける

MySQL

役割: データベース管理システム(RDBMS)

  • ユーザー情報や商品データなどを保存・管理
  • PHPから接続してデータの読み書きを行う

PHP

役割: サーバーサイドのスクリプト言語

  • 動的にHTMLを生成
  • データベースと連携
  • Apacheと連携して動作

なぜhtdocsに置くとlocalhostで動くのか?

Apacheの設定でドキュメントルートが指定されている

ドキュメントルート = /Applications/MAMP/htdocs

Apacheの設定ファイル(httpd.conf)に「このディレクトリ以下のファイルを公開する」という指定があります。

localhostとは

  • localhostは自分のPC自身を指すホスト名(IPアドレス: 127.0.0.1)
  • ブラウザでhttp://localhost:8888にアクセスすると、自分のPC内で動いているApacheに接続される

リクエストの流れ

ブラウザ
  ↓ http://localhost:8888/index.php
自分のPC内のApache(ポート8888で待機中)
  ↓
/Applications/MAMP/htdocs/index.php を探す
  ↓
PHPファイルならPHPエンジンで実行
  ↓
結果のHTMLをブラウザに返す

なぜhtdocsに置く必要があるのか

  • セキュリティ上の理由: Apacheは指定されたディレクトリ(ドキュメントルート)以下のファイルしか公開しない
  • htdocs以外に置いても、Apacheはそのファイルにアクセスできない
  • システムファイルや個人情報が誤って公開されるのを防ぐため

ApacheとPHPの関係

別々のソフトウェア

ApacheとPHPは完全に別のソフトウェアです。

  • Apache: Webサーバーソフトウェア(C言語で書かれている)
  • PHP: スクリプト言語とその実行エンジン

ApacheがPHPを呼び出す仕組み

Apacheの設定ファイルで「.phpという拡張子のファイルが来たらPHPエンジンに処理を渡す」ように設定されています。

httpd.confの設定例

LoadModule php_module /path/to/libphp.so
AddType application/x-httpd-php .php

この設定により:

  1. .phpファイルへのリクエストが来る
  2. ApacheがPHPモジュール(libphp)を呼び出す
  3. PHPエンジンがスクリプトを実行
  4. 実行結果をApacheに返す
  5. Apacheがブラウザに送信

連携方法

1. モジュール版(MAMPのデフォルト)

  • PHPがApacheのプロセス内で動作
  • 高速だが、Apacheとの結合が強い

2. CGI/FastCGI版

  • PHPが別プロセスとして動作
  • Apacheから独立している

PHPの組み込みサーバー

PHP 5.4以降には組み込みのWebサーバーが入っています。

使い方

php -S localhost:8000

これだけで簡易Webサーバーが起動します。

Apacheとの違い

項目 Apache + PHP PHP組み込みサーバー
用途 本番環境・開発環境 開発専用
性能 高い 低い(シングルスレッド)
機能 リライト、認証など豊富 最小限
セキュリティ 本番対応 開発のみ(本番NG)

使い分け

ちょっとしたPHPの動作確認
→ php -S localhost:8000 (手軽!)

WordPressなど本格的な開発
→ MAMP (本番環境に近い)

MAMPの起動ボタンは何をしているのか?

ApacheとMySQLのプロセスを起動している

起動ボタンを押すと、内部的には以下のようなコマンドが実行されています。

# Apacheの起動
/Applications/MAMP/Library/bin/apachectl start

# MySQLの起動
/Applications/MAMP/Library/bin/mysqld_safe start

なぜ起動ボタンが必要なのか

1. 常時起動させたくないから

ApacheとMySQLは起動すると、

  • メモリを消費し続ける
  • CPUリソースを使う
  • ポート(80, 8888, 3306など)を占有する

開発しないときまで動いていると、Macのリソースを無駄に使ってしまいます。

2. セキュリティ上の理由

常にWebサーバーが起動していると、外部からアクセスされるリスクがあります。不要なサービスは止めておくのがセキュリティの基本です。

サーバーソフトウェアの特徴

通常のアプリケーション(Chromeなど)

  • ダブルクリックで起動
  • ウィンドウを閉じたら終了

サーバーソフトウェア(Apache, MySQL)

  • 起動コマンドで開始
  • ウィンドウがなくてもバックグラウンドで動き続ける
  • 停止コマンドで終了

MAMPはこの「サーバーソフトウェアの起動/停止」をGUIのボタンで簡単にできるようにしたものです。

レンタルサーバーでは常時稼働

シン・レンタルサーバーなどのレンタルサーバーでは、ApacheやMySQLは24時間365日常に稼働しています。

MAMPとの違い

項目 MAMP(開発環境) レンタルサーバー
稼働時間 必要なときだけ 24時間365日
目的 開発・テスト 本番公開
アクセス 自分だけ(localhost) 世界中から
停止 自由に停止可能 基本的に停止しない
リソース 自分のPCのみ 複数ユーザーで共有

レンタルサーバーでの構成

インターネット
    ↓
シン・レンタルサーバー(常時稼働中)
    ├─ Apache (常時ポート80/443で待機)
    ├─ MySQL (常時ポート3306で待機)
    └─ PHP (Apacheから呼び出される)
         ↓
    /home/ユーザー名/public_html/
    (ここがhtdocsに相当)

なぜRailsアプリは共用レンタルサーバーで動かないのか?

結論: ApacheはRubyを理解できないから

PHPとRuby(Rails)では、Apacheとの連携方法が根本的に違います

PHPの場合(共用サーバーで動く)

ブラウザ → Apache → PHPモジュール → PHPスクリプト実行 → 結果を返す
  • ApacheにPHPモジュールが組み込まれている
  • .phpファイルが来たら自動的にPHPエンジンが処理
  • 共用サーバーは最初からPHP対応のApacheを用意している

Railsの場合(独自のアプリケーションサーバーが必要)

ブラウザ → (Apache/Nginx) → Pumaなどのアプリサーバー → Railsアプリ → 結果を返す

Railsに必要なもの:

  1. アプリケーションサーバー(Puma, Unicornなど)

    • Railsアプリを常時起動させておくプログラム
    • Apacheとは別のプロセスとして動く
  2. リバースプロキシ設定

    • ApacheやNginxが「中継役」になる
    • リクエストをRailsアプリに転送する

なぜこんなに違うのか?

PHPの動作モデル(ステートレス):

// index.php
<?php
echo "Hello World";
?>
  • 1リクエストごとにスクリプトを1から実行
  • 実行が終わったらメモリ解放
  • 状態を保持しない

Railsの動作モデル(ステートフル):

# Rails
class UsersController < ApplicationController
  def index
    @users = User.all
  end
end
  • アプリケーション全体をメモリに常駐させる
  • ルーティング、モデル、ビューなどのフレームワークが常に動いている
  • 状態を保持

共用サーバーで動かない理由

1. 独自プロセスを常駐させられない

共用サーバーの制約:
- Apacheは動いている ✓
- MySQLは動いている ✓
- Pumaを起動する権限がない ✗
- 独自のデーモンプロセスを起動できない ✗

2. root権限が必要

Railsアプリを動かすには、

  • アプリケーションサーバー(Puma)のインストール
  • 常駐プロセスの起動
  • ポート設定

これらには管理者権限が必要です。

3. リソースの問題

共用サーバー:
├─ 100人のユーザー
└─ みんなでCPU/メモリを共有

もしRailsアプリを許可すると:
├─ ユーザーA: Railsアプリ(メモリ500MB常駐)
├─ ユーザーB: Railsアプリ(メモリ500MB常駐)
└─ ユーザーC: Railsアプリ(メモリ500MB常駐)
→ サーバーがパンクする!

Railsをデプロイできる環境

1. VPS(Virtual Private Server)

  • さくらのVPS、ConoHa VPSなど
  • root権限あり
  • 自由にソフトウェアをインストール可能

2. PaaS(Platform as a Service)

  • Heroku、Render、Fly.ioなど
  • Railsデプロイを簡単にしてくれるサービス

3. クラウド(AWS, GCP, Azure)

  • EC2、Cloud Runなど
  • 柔軟だが設定は複雑

言語・フレームワーク別の対応

言語/FW 実行方式 共用サーバー 理由
PHP リクエストごと実行 ○ 動く Apache標準対応
Rails 常駐型アプリ ✗ 動かない 独自サーバー必要
Node.js 常駐型アプリ ✗ 動かない 同上
Python(Django) 常駐型アプリ ✗ 動かない 同上

libphp.soの正体

PHPエンジン本体が入っている

実は、PHPモジュール(libphp.so)にはPHPエンジンのコア機能がほぼ全部入っています

libphp.so (共有ライブラリ)
├─ PHPインタープリタ(パーサー)
├─ Zend Engine(実行エンジン)
├─ 基本的な関数群
└─ Apache連携用のインターフェース

2つの形態

# 1. スタンドアロン版(独立したPHP)
/usr/bin/php
→ コマンドラインで使うPHP本体

# 2. モジュール版(Apacheに組み込まれる)
/path/to/libphp.so
→ Apacheのプロセス内で動くPHP

Apacheプロセス内部の構造

Apacheプロセス
│
├─ Apache本体のコード
│   ├─ HTTPリクエスト処理
│   ├─ ファイル送信
│   └─ モジュール管理
│
└─ 読み込まれたモジュール
    ├─ mod_rewrite (URL書き換え)
    ├─ mod_ssl (HTTPS対応)
    └─ libphp.so ← PHPエンジン全体がここに!
        ├─ PHPパーサー
        ├─ Zend Engine
        ├─ 変数管理
        ├─ 関数実装
        └─ Apache連携コード

なぜ全部入っているのか?

メモリ効率のため

別プロセス方式(CGI)の場合:

リクエスト1: PHPプロセス起動 → 実行 → 終了
リクエスト2: PHPプロセス起動 → 実行 → 終了
リクエスト3: PHPプロセス起動 → 実行 → 終了
→ 毎回起動コストがかかる(遅い!)

モジュール方式(libphp)の場合:

Apacheプロセス起動(PHPエンジン込み)
↓
リクエスト1: すでにメモリにある → 実行
リクエスト2: すでにメモリにある → 実行
リクエスト3: すでにメモリにある → 実行
→ 高速!

EC2でPHPを動かすには

Apacheだけでは不十分

EC2にApacheだけインストールしても、PHPファイルは実行できません。

Apacheだけの場合

sudo yum install httpd
sudo systemctl start httpd

この状態でindex.phpにアクセスすると、

ブラウザに表示される内容:
<?php
echo "Hello World";
?>

PHPコードがそのまま表示される(実行されない!)

正しいセットアップ手順

1. Apacheのインストール

sudo yum install httpd

2. PHPのインストール

sudo yum install php

このとき、自動的に:

  • PHP本体(/usr/bin/php)
  • PHPモジュール(libphp.so)
  • Apache設定ファイルの自動更新

が行われます。

3. Apache再起動

sudo systemctl restart httpd

これで初めてindex.phpが実行されます!

パッケージマネージャーの賢さ

sudo yum install php

このコマンドの裏側、

yum(パッケージマネージャー)
↓
「phpをインストールしたいのか...」
↓
「Apacheが入ってるか確認しよう」
↓
if (Apache installed) {
  libphp.soも一緒にインストール
  Apache設定ファイルも自動生成
}

インストールされるパッケージ:

Installing:
 php              x86_64  8.0.30-1
Installing dependencies:
 php-common       x86_64  8.0.30-1  ← PHPの共通ファイル
 php-cli          x86_64  8.0.30-1  ← /usr/bin/php(CLI版)
 mod_php          x86_64  8.0.30-1  ← libphp.so(Apache用)★

ファイルが配置される場所

グローバルインストール:
/usr/bin/php
├─ コマンドライン版PHP(どこからでも使える)

Apache連携用:
/usr/lib64/httpd/modules/libphp.so
├─ Apache用PHPモジュール

設定ファイル(自動生成):
/etc/httpd/conf.modules.d/10-php.conf
├─ LoadModule php_module modules/libphp.so
└─ <FilesMatch \.php$> ... </FilesMatch>

インストール後の確認

# PHPモジュールが追加された
ls /usr/lib64/httpd/modules/ | grep php
libphp.so

# 設定ファイルも自動生成された
cat /etc/httpd/conf.modules.d/10-php.conf
LoadModule php_module modules/libphp.so

<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

静的HTMLとの違い

EC2 + Apache のみ
├─ HTML → ○ 表示できる
├─ CSS/JS → ○ 表示できる
└─ PHP → ✗ 表示できない(コードが見える)

EC2 + Apache + PHP
├─ HTML → ○ 表示できる
├─ CSS/JS → ○ 表示できる
└─ PHP → ○ 実行できる!

まとめ

MAMPの仕組み

  • MAMP = MacOS + Apache + MySQL + PHP
  • 起動ボタンでApacheとMySQLのプロセスを起動
  • htdocsはApacheのドキュメントルート

ApacheとPHPの関係

  • 別々のソフトウェアだが、libphp.soで連携
  • libphp.soにはPHPエンジン本体が含まれる
  • Apacheのプロセス内でPHPが動作(モジュール版)

開発環境と本番環境

  • MAMP: 開発時に必要なときだけ起動
  • レンタルサーバー: 24時間365日稼働

PHPとRailsの違い

  • PHP: リクエストごとに実行(ステートレス) → 共用サーバーOK
  • Rails: 常駐型アプリ(ステートフル) → VPS/PaaS必要

EC2でのセットアップ

  • Apacheだけでは不十分
  • PHPを別途インストールする必要がある
  • パッケージマネージャーが自動で連携してくれる

結構、長い記事になってしまいましたが、
この記事が、Webサーバーの仕組み理解の助けになれば幸いです!
春から開発エンジニアになりますが、しっかりと言語化できるように頑張っていきます!!

Discussion