「コンテナ - LAMP」の版間の差分

提供: MochiuWiki : SUSE, EC, PCB

49行目: 49行目:
<br>
<br>
  lamp-project/
  lamp-project/
  ├── docker-compose.yml        # Compose設定ファイル
  ├── docker-compose.yml        # Compose設定ファイル (または、podman-compose.yml)
  ├── apache/
  ├── apache/
  │  ├── Dockerfile            # Apache用のDockerfile (カスタマイズする場合)
  │  ├── Dockerfile            # Apache用のDockerfile (カスタマイズする場合)

2025年12月23日 (火) 16:12時点における版

概要

LAMP環境とは、Linux、Apache、MySQL または MariaDB、PHPを組み合わせたWebアプリケーション開発・運用のための基盤環境である。

Docker ComposeまたはPodman Composeを使用することで、これらのコンポーネントを個別のコンテナとして構築し、相互に連携させることができる。
コンテナ化によって、環境の再現性が高まり、開発環境と本番環境の差異を最小限に抑えることが可能となる。

LAMP環境の各コンポーネントは以下の役割を担う。

  • Linux
    コンテナのベースとなるオペレーティングシステム (Alpine、Debian、Ubuntuなど)
  • Apache
    HTTPサーバとして動作し、静的ファイルの配信やPHPスクリプトの実行を担当する
  • MySQL / MariaDB
    リレーショナルデータベースとしてアプリケーションのデータを永続化する
  • PHP
    サーバサイドのスクリプト言語として動的なWebページを生成する


Docker ComposeまたはPodman Composeを使用することにより、LAMP環境を効率的に構築・管理できる。
コンテナ化によって、開発環境の再現性が高まり、チーム内での環境統一も容易になる。

  • Apache2、MySQL、PHPが独立したコンテナとして動作する。
  • 設定ファイルやデータは、ホスト側で管理され永続化される。
  • 環境変数を使用することで、設定の柔軟性が高い。
  • phpMyAdminにより、データベースの視覚的な管理が可能である。
  • SSL対応により、HTTPS通信をサポートできる。


開発環境として使用する場合は、Xdebugやホットリロード機能を追加することで、さらに開発効率を向上させることができる。
ただし、本番環境では、セキュリティ設定を強化し、適切なバックアップを実施することが重要である。


環境の前提条件

LAMP環境を構築する前に、以下に示すソフトウェアがインストールされている必要がある。

Docker環境の場合

  • Docker Engine (バージョン20.10以降を推奨)
  • Docker Compose (バージョン2.0以降を推奨)


Podman環境の場合

  • Podman (バージョン4.0以降を推奨)
  • Podman Compose (バージョン1.0以降を推奨)


インストール状況の確認は以下のコマンドで行う。

podman --version
podman-compose --version



ディレクトリ構成

LAMP環境を構築するために、ディレクトリ構成を作成する。
以下に示す構成は、各コンポーネントの設定ファイルやデータを整理して管理するためのものである。

lamp-project/
├── docker-compose.yml         # Compose設定ファイル (または、podman-compose.yml)
├── apache/
│   ├── Dockerfile             # Apache用のDockerfile (カスタマイズする場合)
│   └── httpd.conf             # Apache設定ファイル (カスタマイズする場合)
├── php/
│   ├── Dockerfile             # PHP用のDockerfile (拡張モジュールを追加する場合)
│   └── php.ini                # PHP設定ファイル
├── mysql/
│   ├── conf.d/
│   │   └── my.cnf             # MySQL設定ファイル
│   └── init/
│       └── 01-init.sql        # 初期化SQLスクリプト
└── www/
    └── html/
        └── index.php          # Webコンテンツのルートディレクトリ



基本的なCompose設定

LAMP環境を構築するためのCompose設定ファイルを作成する。
この設定では、Apache、MySQL、PHPの3つのサービスを定義して、それぞれを連携させる。

docker-compose.yml または compose.yml という名前でファイルを作成する。

以下の例では、ヘルスチェックの設定も含まれている。
ヘルスチェックにより、MySQLコンテナが完全に起動するまで待機してから、Webサーバがデータベースへの接続を試みることができる。

 version: '3.8'
 
 services:
   # Webサーバ (Apache + PHP)
   web:
     build:
       context: ./php
       dockerfile: Dockerfile
     container_name: lamp-web
     ports:
       - "0.0.0.0:8080:80"
     volumes:
       - ./www/html:/var/www/html
       - ./apache/logs:/var/log/apache2
     environment:
       - APACHE_RUN_USER=www-data
       - APACHE_RUN_GROUP=www-data
     depends_on:
       - db
     networks:
       - lamp-network
     restart: unless-stopped
 
   # データベースサーバ (MySQL)
   db:
     image: mysql:8.0
     container_name: lamp-db
     environment:
       MYSQL_ROOT_PASSWORD: rootpassword
       MYSQL_DATABASE: myapp
       MYSQL_USER: dbuser
       MYSQL_PASSWORD: dbpassword
     volumes:
       - mysql-data:/var/lib/mysql
       - ./mysql/init:/docker-entrypoint-initdb.d
       - ./mysql/conf.d:/etc/mysql/conf.d
     ports:
       - "0.0.0.0:3306:3306"
     networks:
       - lamp-network
     restart: unless-stopped
     healthcheck:
       test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
       interval: 10s
       timeout: 5s
       retries: 5
 
   # データベース管理ツール (phpMyAdmin)
   phpmyadmin:
     image: phpmyadmin:latest
     container_name: lamp-phpmyadmin
     environment:
       PMA_HOST: db
       PMA_PORT: 3306
       PMA_USER: root
       PMA_PASSWORD: rootpassword
     ports:
       - "0.0.0.0:8081:80"
     depends_on:
       - db
     networks:
       - lamp-network
     restart: unless-stopped
 
 # 永続化ボリュームの定義
 volumes:
   mysql-data:
     driver: local
 
 # ネットワークの定義
 networks:
   lamp-network:
     driver: bridge


この設定ファイルでは、php:8.2-apacheという公式イメージを使用している。
このイメージにはApacheとPHPが統合されており、追加の設定なしでPHPスクリプトを実行できる。

データベースとしてはMySQL 8.0を使用し、環境変数でデータベース名やユーザ情報を設定している。

depends_onディレクティブにより、webサービスが起動する前にdbサービスが起動することが保証される。
また、両サービスはlamp-networkという専用のネットワークで接続され、サービス名 (上記の例では、db) でお互いに通信できる。


コンテナの起動と動作確認

Compose設定ファイルを作成したら、以下のコマンドでコンテナを起動する。

Docker Composeの場合

docker-compose up -d


または、Docker Compose V2の場合は以下のコマンドでも起動できる。

docker compose up -d


起動したコンテナの状態を確認するには、以下のコマンドを実行する。

Docker Composeの場合

docker-compose ps


Podman Composeの場合

podman-compose up -d


起動したコンテナの状態を確認するには、以下のコマンドを実行する。

Podman Composeの場合

podman-compose ps


正常に起動している場合は、webとdbの2つのコンテナがUpステータスで表示される。

初回起動時の注意点

MySQLコンテナは初回起動時にデータベースの初期化を行うため、完全に起動するまで数十秒かかる場合がある。
ログを確認して、MySQLが完全に起動したことを確認する。

docker-compose logs -f db
# または
podman-compose logs -f db


ready for connections というメッセージが表示されている場合、MySQLの起動が完了している。


PHPの動作確認

phpinfo()による確認

www/html/index.phpファイルを作成し、以下に示す内容を記述する。

 <?php
 phpinfo();
 ?>


Webブラウザで http://localhost:8080 にアクセスすると、PHPの詳細情報が表示される。
この画面では、PHPのバージョンや有効な拡張モジュール、Apache環境変数等を確認することができる。

データベース接続の確認

次に、PHPからMySQLへの接続を確認する。
www/html/db-test.phpファイルを作成し、以下に示す内容を記述する。

 <?php
 $servername = "db";  // Composeファイルで定義したサービス名
 $username = "dbuser";
 $password = "dbpassword";
 $database = "myapp";
 
 try {
    // PDOを使用した接続
    // DSN(Data Source Name)を構築してデータベースに接続
    $conn = new PDO(
       "mysql:host=$servername;dbname=$database;charset=utf8mb4",
       $username,
       $password
    );
 
   // エラーモードを例外に設定 (データベース操作でエラーが発生した時に例外をスローする)
   $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 
   // 接続成功メッセージ
   echo "接続情報: MySQL via PDO<br>";
 
   // サーバーバージョンの表示 (MySQLiのhost_infoに相当する情報)
   echo "サーバーバージョン: " . $conn->getAttribute(PDO::ATTR_SERVER_VERSION) . "<br>";
 }
 catch (PDOException $e) {
    // 接続エラーが発生した場合の処理
    die("接続失敗: " . $e->getMessage());
 }
 
 // PDOの場合、接続は自動的にスクリプト終了時にクローズされる
 // 明示的にクローズする場合は以下のように記述する
 $conn = null;
 ?>


http://localhost:8080/db-test.php にアクセスして、接続成功メッセージが表示される場合はPHPおよびMySQL間の連携が正常に動作している。


PHP拡張モジュールの追加

基本的なphp:8.2-apacheイメージには、最小限の拡張モジュールしか含まれていない。
多くのWebアプリケーションでは、追加の拡張モジュールが必要となる。

Dockerfileの作成

php/Dockerfileを作成して、必要な拡張モジュールをインストールする設定を記述する。

以下の例では、画像処理 (gd)、データベース接続 (mysqli、pdo_mysql)、文字列処理 (mbstring)、ファイル圧縮 (zip) 等の一般的な拡張モジュールをインストールしている。

 FROM php:8.2-apache
 
 # システムパッケージの更新と必要なライブラリのインストール
 RUN apt-get update && apt-get install -y \
     libpng-dev \
     libjpeg-dev \
     libfreetype6-dev \
     libzip-dev \
     libonig-dev \
     libxml2-dev \
     && rm -rf /var/lib/apt/lists/*
 
 # PHP拡張モジュールのインストール
 RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
     && docker-php-ext-install -j$(nproc) \
     gd \
     mysqli \
     pdo \
     pdo_mysql \
     mbstring \
     zip \
     exif \
     pcntl \
     bcmath \
     opcache
 
 # Apacheのmod_rewriteを有効化
 RUN a2enmod rewrite
 
 # 作業ディレクトリの設定
 WORKDIR /var/www/html


Compose設定の更新

docker-compose.ymlを以下に示すように修正する。

   web:
     build:
       context: ./php
       dockerfile: Dockerfile
     container_name: lamp-web
     ports:
       - "0.0.0.0:8080:80"
     volumes:
       - ./www/html:/var/www/html
     depends_on:
       - db
     networks:
       - lamp-network
     restart: unless-stopped


imageディレクティブの代わりにbuildディレクティブを使用することにより、Dockerfileからイメージをビルドすることができる。

ビルドして起動する。

docker-compose up -d --build
# または
podman-compose up -d --build



PHP設定のカスタマイズ

PHPの動作をカスタマイズするため、php.iniファイルを作成および設定する。

カスタムphp.iniの作成

php/php.iniファイルを作成して、必要な設定を記述する。

以下の例では、実行時間の上限、メモリ制限、アップロードファイルサイズ等を調整している。

開発環境ではエラーを画面に表示させることにより、問題の早期発見が可能になる。
本番環境では、セキュリティの観点からエラーをログファイルに記録する設定に切り替えることが推奨される。

 ; 基本設定
 max_execution_time = 300
 max_input_time = 300
 memory_limit = 256M
 
 ; アップロード設定
 upload_max_filesize = 64M
 post_max_size = 64M
 
 ; エラー表示設定 (開発環境用)
 display_errors = On
 display_startup_errors = On
 error_reporting = E_ALL
 
 ; 本番環境用設定 (本番環境ではこちらを使用)
 ; display_errors = Off
 ; display_startup_errors = Off
 ; error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
 ; log_errors = On
 ; error_log = /var/log/php/error.log
 
 ; タイムゾーン設定
 date.timezone = Asia/Tokyo
 
 ; セッション設定
 session.save_handler = files
 session.save_path = "/tmp"
 session.gc_maxlifetime = 1440
 
 ; OPcache設定 (パフォーマンス向上)
 opcache.enable = 1
 opcache.memory_consumption = 128
 opcache.interned_strings_buffer = 8
 opcache.max_accelerated_files = 4000
 opcache.revalidate_freq = 60


Dockerfileの更新

作成したphp.iniをコンテナにコピーするため、php/Dockerfileに以下の行を追加する。

 # カスタムphp.iniのコピー
 COPY php.ini /usr/local/etc/php/conf.d/custom.ini


この設定により、カスタムphp.iniが読み込まれ、デフォルト設定が上書きされる。


Apache設定

Apacheの設定をカスタマイズすることにより、仮想ホストの設定やmod_rewriteの有効化などを行える。

.htaccessの有効化

多くのPHPアプリケーション (WordPress等) は.htaccessファイルを使用してURLの書き換えを行う。
これを有効にするため、AllowOverrideディレクティブを設定する必要がある。

apache/000-default.confファイルを作成し、以下の内容を記述する。

 <VirtualHost *:80>
     ServerAdmin webmaster@localhost
     DocumentRoot /var/www/html
 
     <Directory /var/www/html>
         Options Indexes FollowSymLinks
         AllowOverride All
         Require all granted
     </Directory>
 
     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined
 </VirtualHost>


この設定では、AllowOverride Allを指定することにより、.htaccessファイルによるディレクトリ単位の設定変更を許可している。

Dockerfileへの追加

php/Dockerfileに、この設定ファイルをコピーする行を追加する。

 # Apache設定のコピー
 COPY ../apache/000-default.conf /etc/apache2/sites-available/000-default.conf



MySQL初期化スクリプト

コンテナ起動時に自動的にデータベーステーブルを作成、あるいは、初期データを投入する場合、初期化スクリプトを使用する。

初期化SQLの作成

mysql/init/01-init.sqlファイルを作成して、テーブル定義やサンプルデータを記述する。

 -- データベースの使用
 USE myapp;
 
 -- ユーザテーブルの作成
 CREATE TABLE IF NOT EXISTS users (
     id INT AUTO_INCREMENT PRIMARY KEY,
     username VARCHAR(50) NOT NULL UNIQUE,
     email VARCHAR(100) NOT NULL UNIQUE,
     password_hash VARCHAR(255) NOT NULL,
     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 
 -- 記事テーブルの作成
 CREATE TABLE IF NOT EXISTS posts (
     id INT AUTO_INCREMENT PRIMARY KEY,
     user_id INT NOT NULL,
     title VARCHAR(200) NOT NULL,
     content TEXT,
     published BOOLEAN DEFAULT FALSE,
     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
     updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 
 -- サンプルデータの挿入
 INSERT INTO users (username, email, password_hash) VALUES
 ('admin', 'admin@example.com', '$2y$10$abcdefghijklmnopqrstuvwxyz1234567890'),
 ('testuser', 'test@example.com', '$2y$10$1234567890abcdefghijklmnopqrstuvwxyz');
 
 INSERT INTO posts (user_id, title, content, published) VALUES
 (1, '最初の投稿', 'これはテスト投稿です。', TRUE),
 (1, '2番目の投稿', 'もう一つのテスト投稿です。', TRUE),
 (2, 'ユーザ投稿', 'テストユーザからの投稿です。', FALSE);


このSQLファイルは、MySQLコンテナの初回起動時に自動的に実行される。
/docker-entrypoint-initdb.dディレクトリに配置されたSQLファイルは、ファイル名の昇順で実行されるため、複数のファイルを使用する場合は 01-、02- のように番号を付加して実行順序を制御できる。


MySQL設定のカスタマイズ

MySQLの動作をカスタマイズするため、設定ファイルを作成する。

カスタムmy.cnfの作成

mysql/conf.d/my.cnfファイルを作成して、以下に示す内容を記述する。

以下の例では、文字コードをutf8mb4、日本時間 (UTC+9) を設定している。
また、パフォーマンスチューニングのためのバッファサイズやスロークエリログの設定も含まれている。

 [mysqld]
 # 文字コード設定
 character-set-server = utf8mb4
 collation-server = utf8mb4_unicode_ci
 
 # タイムゾーン設定
 default-time-zone = '+09:00'
 
 # 接続設定
 max_connections = 200
 max_connect_errors = 100
 
 # パフォーマンス設定
 innodb_buffer_pool_size = 256M
 innodb_log_file_size = 64M
 innodb_flush_log_at_trx_commit = 2
 
 # ログ設定
 slow_query_log = 1
 slow_query_log_file = /var/log/mysql/slow-query.log
 long_query_time = 2
 
 # バイナリログ設定 (レプリケーション用)
 # server-id = 1
 # log_bin = /var/log/mysql/mysql-bin.log
 # expire_logs_days = 7
 
 [client]
 default-character-set = utf8mb4


Compose設定への追加

Composeファイルのdbサービスに、設定ファイルをマウントする設定を追加する。

   db:
     image: mysql:8.0
     container_name: lamp-db
     environment:
       MYSQL_ROOT_PASSWORD: rootpassword
       MYSQL_DATABASE: myapp
       MYSQL_USER: dbuser
       MYSQL_PASSWORD: dbpassword
     volumes:
       - mysql-data:/var/lib/mysql
       - ./mysql/init:/docker-entrypoint-initdb.d
       - ./mysql/conf.d:/etc/mysql/conf.d
     networks:
       - lamp-network
     restart: unless-stopped



phpMyAdminの追加

データベースを視覚的に管理するため、phpMyAdminを追加することができる。
phpMyAdminは、Webブラウザ上でデータベースの操作が可能なツールである。

Compose設定への追加

Composeファイルに、phpMyAdminサービスを追加する。

以下の例では、http://localhost:8081 でphpMyAdminにアクセスできるようになる。
ログイン画面では、Composeファイルで指定したデータベースユーザ (dbuser) または rootユーザ でログインできる。

   phpmyadmin:
     image: phpmyadmin:latest
     container_name: lamp-phpmyadmin
     environment:
       PMA_HOST: db
       PMA_PORT: 3306
       PMA_USER: root
       PMA_PASSWORD: rootpassword
     ports:
       - "0.0.0.0:8081:80"
     depends_on:
       - db
     networks:
       - lamp-network
     restart: unless-stopped



アクセス方法とテスト

コンテナを起動した後、以下のURLでそれぞれのサービスにアクセスできる。

Webサーバ

http://localhost:8080 にアクセスすると、./www/html/index.phpの内容が表示される。

phpMyAdmin

http://localhost:8081 にアクセスすると、phpMyAdminのログイン画面が表示される。以下のいずれかの認証情報でログインできる。

管理者ユーザの場合

  • ユーザ名: root
  • パスワード: rootpassword


一般ユーザの場合

  • ユーザ名: dbuser
  • パスワード: dbpassword


データベース接続テスト

PHPからMySQLへの接続をテストするため、./www/html/db-connect.phpファイルを作成する。

 <?php
 // データベース接続設定
 $host = 'db';  // Composeで定義したサービス名
 $dbname = 'myapp';
 $username = 'dbuser';
 $password = 'dbpassword';
 
 try {
     // PDOを使用した接続
     $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password);
     $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
     
     echo "<h2>データベース接続成功!</h2>";
     
     // ユーザテーブルの内容を取得
     $stmt = $pdo->query("SELECT * FROM users");
     $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
     
     echo "<h3>登録ユーザ一覧</h3>";
     echo "<table border='1' cellpadding='5'>";
     echo "<tr><th>ID</th><th>ユーザ名</th><th>メールアドレス</th><th>登録日時</th></tr>";
     
     foreach ($users as $user) {
         echo "<tr>";
         echo "<td>" . htmlspecialchars($user['id']) . "</td>";
         echo "<td>" . htmlspecialchars($user['username']) . "</td>";
         echo "<td>" . htmlspecialchars($user['email']) . "</td>";
         echo "<td>" . htmlspecialchars($user['created_at']) . "</td>";
         echo "</tr>";
     }
     
     echo "</table>";
     
 } catch (PDOException $e) {
     echo "<h2>データベース接続エラー</h2>";
     echo "<p>エラー内容: " . htmlspecialchars($e->getMessage()) . "</p>";
 }
 ?>


http://localhost:8080/db-connect.php にアクセスして、ユーザ一覧が表示されれば、LAMP環境が正しく動作している。


MariaDBを使用する場合

MySQLの代わりにMariaDBを使用することもできる。
MariaDBはMySQLのフォーク版であり、互換性がある。

Compose設定の変更

Composeファイルのdbサービスを、以下に示すように変更する。
主な変更点は、イメージ名をmariadb:x.xに変更し、環境変数名を MARIADB_ で始まるものに変更している点である。
ボリューム名も mysql-data から mariadb-data に変更することが推奨される。

   db:
     image: mariadb:10.11
     container_name: lamp-mariadb
     environment:
       MARIADB_ROOT_PASSWORD: rootpassword
       MARIADB_DATABASE: myapp
       MARIADB_USER: dbuser
       MARIADB_PASSWORD: dbpassword
     volumes:
       - mariadb-data:/var/lib/mysql
       - ./mysql/init:/docker-entrypoint-initdb.d
       - ./mysql/conf.d:/etc/mysql/conf.d
     ports:
       - "0.0.0.0:3306:3306"
     networks:
       - lamp-network
     restart: unless-stopped
     healthcheck:
       test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
       interval: 10s
       timeout: 5s
       retries: 5



環境変数ファイルの使用

パスワード等の機密情報をCompose設定ファイルに直接記述するのではなく、.envファイルに分離することができる。
これにより、設定ファイルをバージョン管理システムで管理する際に、機密情報を除外できる。

.envファイルの作成

プロジェクトルートに.envファイルを作成して、環境変数を定義する。

 # データベース設定
 MYSQL_ROOT_PASSWORD=rootpassword
 MYSQL_DATABASE=myapp
 MYSQL_USER=dbuser
 MYSQL_PASSWORD=dbpassword
 
 # Webサーバ設定
 WEB_PORT=8080
 
 # phpMyAdmin設定
 PMA_PORT=8081


Compose設定の更新

Composeファイルを編集して、環境変数を参照するように変更する。
これにより、開発環境と本番環境で異なる設定値を使用する場合でも、Composeファイルを変更する必要がなくなる。

.envファイルを.gitignoreに追加して、バージョン管理から除外する。

   db:
     image: mysql:8.0
     container_name: lamp-db
     environment:
       MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
       MYSQL_DATABASE: ${MYSQL_DATABASE}
       MYSQL_USER: ${MYSQL_USER}
       MYSQL_PASSWORD: ${MYSQL_PASSWORD}
     # ... 以下省略
 
   web:
     build:
       context: ./php
       dockerfile: Dockerfile
     container_name: lamp-web
     ports:
       - "0.0.0.0:${WEB_PORT}:80"
     # ... 以下省略



データの永続化とバックアップ

コンテナを削除してもデータを保持するため、適切な永続化戦略が必要である。

ボリュームの確認

作成されたボリュームを確認する。

# Docker Composeの場合
docker volume ls

# Podman Composeの場合
podman volume ls


<プロジェクト名>_mysql-data という名前のボリュームが作成されていることを確認する。

データベースのバックアップ

MySQLデータベースの内容をバックアップする。

パスワード入力を求められるので、ルートパスワードを入力する。
バックアップファイルbackup.sqlが作成される。

# Docker Composeの場合
docker-compose exec db mysqldump -u root -p myapp > backup.sql

# Podman Composeの場合
podman-compose exec db mysqldump -u root -p myapp > backup.sql


バックアップの復元

バックアップから復元するには、以下のコマンドを実行する。

docker-compose exec -T db mysql -u root -p myapp < backup.sql
# または
podman-compose exec -T db mysql -u root -p myapp < backup.sql


完全バックアップスクリプト

定期的なバックアップを自動化するため、シェルスクリプトを作成する。

以下の例では、backup.shという名前で以下に示す内容を保存している。

 #!/usr/bin/env sh
 
 # バックアップディレクトリの作成
 BACKUP_DIR="./backups"
 mkdir -p $BACKUP_DIR
 
 # タイムスタンプの生成
 TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
 
 # データベースのバックアップ
 echo "データベースをバックアップしています..."
 docker-compose exec -T db mysqldump -u root -prootpassword --all-databases > "$BACKUP_DIR/mysql_$TIMESTAMP.sql"
 
 # Webコンテンツのバックアップ
 echo "Webコンテンツをバックアップしています..."
 tar -czf "$BACKUP_DIR/www_$TIMESTAMP.tar.gz" ./www
 
 # 古いバックアップの削除 (30日以上前のファイル)
 find $BACKUP_DIR -type f -mtime +30 -delete
 
 echo "バックアップが完了しました: $TIMESTAMP"


スクリプトに実行権限を付与する。

chmod u+x backup.sh


定期的にバックアップを実行するには、cronに登録する。

crontab -e


# 毎日午前3時にバックアップを実行する例
0 3 * * * cd /path/to/lamp-project && ./backup.sh



SSLの設定

HTTPS通信を有効にするため、SSL証明書を設定する。

自己署名証明書の作成

開発環境では、自己署名証明書を使用できる。
例えば、以下に示すコマンドで自己署名証明書を生成することができる。

mkdir -p ./ssl

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
            -keyout ./ssl/server.key \
            -out ./ssl/server.crt \
            -subj "/C=JP/ST=Tokyo/L=Tokyo/O=Development/CN=localhost"


Apacheのssl.confの作成

apache/ssl.confファイルを作成して、HTTPS設定を記述する。

 <IfModule mod_ssl.c>
     <VirtualHost *:443>
         ServerAdmin webmaster@localhost
         DocumentRoot /var/www/html
 
         SSLEngine on
         SSLCertificateFile /etc/ssl/certs/server.crt
         SSLCertificateKeyFile /etc/ssl/private/server.key
 
         <Directory /var/www/html>
             Options Indexes FollowSymLinks
             AllowOverride All
             Require all granted
         </Directory>
 
         ErrorLog ${APACHE_LOG_DIR}/ssl-error.log
         CustomLog ${APACHE_LOG_DIR}/ssl-access.log combined
     </VirtualHost>
 </IfModule>


Dockerfileの更新

php/Dockerfileに、SSL設定と証明書をコピーする行を追加する。

 # SSLモジュールの有効化
 RUN a2enmod ssl
 RUN a2ensite default-ssl
 
 # SSL証明書のコピー
 COPY ../ssl/server.crt /etc/ssl/certs/server.crt
 COPY ../ssl/server.key /etc/ssl/private/server.key
 
 # SSL設定のコピー
 COPY ../apache/ssl.conf /etc/apache2/sites-available/default-ssl.conf


Compose設定の更新

docker-compose.ymlのwebサービスに、443ポートを追加する。

   web:
     build:
       context: ./php
       dockerfile: Dockerfile
     container_name: lamp-web
     ports:
       - "0.0.0.0:8080:80"
       - "0.0.0.0:8443:443"
     # ... 以下省略


再ビルドして起動する。

docker-compose up -d --build


https://localhost:8443 にアクセスすると、HTTPSでWebサーバにアクセスできる。
Webブラウザは自己署名証明書の警告を表示するが、開発環境では問題ない。

本番環境では、Let's Encrypt等の認証局から正式な証明書を取得することが推奨される。


Composerのインストール

PHPの依存関係管理ツールであるComposerをコンテナにインストールする方法を説明する。

Dockerfileへの追加

php/Dockerfileファイルに、Composerをインストールする設定を追加する。

 # Composerのインストール
 RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
 
 # Composerのバージョン確認
 RUN composer --version


再ビルド後、コンテナ内でComposerを使用できる。

docker-compose exec web composer --version


プロジェクトでのComposer使用例

Laravel等のフレームワークをインストールする。

docker-compose exec web composer create-project laravel/laravel /var/www/html/laravel


または、既存のcomposer.jsonファイルがある場合は、依存パッケージをインストールする。

docker-compose exec web composer install



Node.jsとnpmの追加

フロントエンドのビルドツールを使用する場合、Node.jsとnpmが必要になることがある。

Dockerfileへの追加

php/Dockerfileファイルに、Node.jsをインストールする設定を追加する。

 # Node.jsとnpmのインストール
 RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
     && apt-get install -y nodejs \
     && npm install -g npm@latest
 
 # バージョン確認
 RUN node --version && npm --version


これにより、コンテナ内でnpmコマンドを使用できるようになる。

docker-compose exec web npm install
docker-compose exec web npm run build



開発時の設定

開発効率を向上させるための設定がある。

Xdebugの設定

PHPのデバッグツールXdebugをインストールすることで、ステップ実行やブレークポイント設定が可能になる。

php/Dockerfileに以下に示す設定を追加する。

 # Xdebugのインストール
 RUN pecl install xdebug \
     && docker-php-ext-enable xdebug
 
 # Xdebug設定
 RUN echo "xdebug.mode=develop,debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
     && echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
     && echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini


ホットリロードの設定

ファイル変更を自動的に検知してWebブラウザをリロードするため、ブラウザ拡張機能 (Live Server) や npmパッケージ (browser-sync) が使用できる。

ログの確認を簡単にする

Composeファイルにログ設定を追加することにより、ログの確認が容易になる。

   web:
     # ... 既存の設定
     logging:
       driver: "json-file"
       options:
         max-size: "10m"
         max-file: "3"



トラブルシューティング

コンテナが起動しない

ログを確認して、エラーメッセージを特定する。

docker-compose logs web
docker-compose logs db
# または
podman-compose logs web
podman-compose logs db


設定ファイルの構文エラーがある場合は、以下に示すコマンドで検証する。

docker-compose config
# または
podman-compose config


データベースに接続できない

データベースコンテナが完全に起動するまで待つ必要がある。

まず、ヘルスチェックを確認する。
statusカラムにhealthyと表示されている場合は、接続可能である。

docker-compose ps
# または
podman-compose ps


次に、接続情報が正しいかどうかを確認する。
ホスト名は、Composeファイルで定義したサービス名 (db) を使用する必要がある。
この時、localhost や 127.0.0.1 では接続できない。

ポート番号の競合

既に他のサービスがポートを使用している場合、異なるポート番号に変更する。

ports:
  - "0.0.0.0:8081:80"  # 8080の代わりに8081を使用


パーミッションエラー

ボリュームマウントしたディレクトリのパーミッションを確認する。

sudo chown -R 1000:1000 ./www/html
chmod -R 755 ./www/html


PHP拡張モジュールが見つからない

必要な拡張モジュールがインストールされているか確認する。

docker-compose exec web php -m
# または
podman-compose exec web php -m 


インストールされていない場合は、Dockerfileに追加して再ビルドする。

MySQLの文字化け

文字コード設定を確認する。
phpMyAdmin または コマンドラインで以下に示すクエリを実行する。

SHOW VARIABLES LIKE 'character%';


全てutf8mb4と表示されていることを確認する。
もし異なる場合は、my.cnfの設定を見直す。

コンテナ内のファイルが見えない

ボリュームマウントの設定を確認する。
相対パスが正しいか、ホスト側のディレクトリが存在するかどうかを確認する。

ls -la ./www/html


メモリ不足エラー

Docker Desktop / Podman Desktopの設定で、割り当てメモリを増やす。
また、php.iniの memory_limit を調整する。


パフォーマンス最適化

OPcacheの有効化

php.iniで既に設定したOPcacheにより、PHPスクリプトのコンパイル結果がキャッシュされて実行速度が向上する。

MySQLのクエリキャッシュ

MySQL 8.0以降ではクエリキャッシュが廃止されたため、アプリケーション側でキャッシュ (Redis、Memcached等) を使用することが推奨される。

静的ファイルの圧縮

Apacheの mod_deflate を使用して、テキストファイルを圧縮して転送する。

apache/000-default.confファイルに以下に示す設定を追加する。

 <IfModule mod_deflate.c>
     AddOutputFilterByType DEFLATE text/html text/plain text/xml
     AddOutputFilterByType DEFLATE text/css text/javascript
     AddOutputFilterByType DEFLATE application/javascript application/json
 </IfModule>


php/Dockerfileファイルで mod_deflate を有効化する。

RUN a2enmod deflate



セキュリティ対策

本番環境での設定変更

本番環境では、以下に示す設定変更が推奨される。

  • php.iniでエラー表示を無効化する。
     display_errors = Off
     log_errors = On
     error_log = /var/log/php/error.log
    

  • 環境変数からパスワードを分離する。
     # 本番環境では.envファイルを使用せず、環境変数を直接設定する
     export MYSQL_ROOT_PASSWORD=$(openssl rand -base64 32)
    


ファイアウォール設定

外部からのアクセスを許可する場合、ファイアウォールでポート開放を行う。

  • Linuxの場合
    • firewalld使用時
       sudo firewall-cmd --permanent --add-port=8080/tcp
       sudo firewall-cmd --permanent --add-port=8443/tcp
       sudo firewall-cmd --reload
      

    • ufw使用時
       sudo ufw allow 8080/tcp
       sudo ufw allow 8443/tcp
       sudo ufw reload
      

  • Windows 11の場合

    PowerShellを管理者権限で起動する。
    HTTPポートの受信ルールを追加する。
     New-NetFirewallRule -DisplayName "LAMP HTTP" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow
    

    HTTPSポートの受信ルールを追加する。
     New-NetFirewallRule -DisplayName "LAMP HTTPS" -Direction Inbound -Protocol TCP -LocalPort 8443 -Action Allow
    

    接続テストを別PCから実行する。
     Test-NetConnection -ComputerName <サーバのIPアドレス> -Port 8080
     Test-NetConnection -ComputerName <サーバのIPアドレス> -Port 8443
    

    ファイアウォールルールを削除する場合は、以下に示すコマンドを実行する。
     Remove-NetFirewallRule -DisplayName "LAMP HTTP" -ErrorAction SilentlyContinue
     Remove-NetFirewallRule -DisplayName "LAMP HTTPS" -ErrorAction SilentlyContinue
    



コンテナの管理コマンド

コンテナの起動

docker-compose up -d
# または
podman-compose up -d


コンテナの停止

docker-compose down
# または
podman-compose down


データボリュームも削除する場合は、-vオプションを追加する。

docker-compose down -v
# または
podman-compose down -v


コンテナの再起動

docker-compose restart
# または
podman-compose restart


# 特定のサービスのみ再起動する場合

docker-compose restart <サービス名>
# または
podman-compose restart <サービス名>


コンテナのログ確認

docker-compose logs -f <サービス名>
# または
podman-compose logs -f <サービス名>


コンテナ内でコマンド実行

docker-compose exec <サービス名> bash

# 例 : サービス名 (db) のMySQLコンテナの場合
docker-compose exec db mysql -u root -p


イメージの再ビルド

docker-compose build
docker-compose up -d --build
# または
podman-compose build
podman-compose up -d --build


リソース使用状況の確認

docker stats
# または
podman stats