0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DockerでApache+MySQL+PHPの環境を構築する

0
Posted at

はじめに

DockerでLAMP環境を構築する場合の備忘録です。
ToDoリストを表示するアプリです。

環境変数を使用する場合

ディレクトリ構成

$ ls -Ra
.:
.  ..  .env  Dockerfile  compose.yaml  db  src

./db:
.  ..  init

./db/init:
.  ..  init.sql

./src:
.  ..  todo_list.php

ファイル

.env 環境変数の値を記述する
MYSQL_ROOT_PASSWORD=rootpass
MYSQL_DATABASE=example_database
MYSQL_USER=example_user
MYSQL_PASSWORD=password
MYSQL_TABLE=todo_list
Dockerfile apacheを含むPHPを使用
FROM php:8.5.2-apache
RUN apt update && apt install -y libonig-dev && docker-php-ext-install pdo_mysql
compose.yaml
services:
  db:
    image: mysql:9.5.0
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      TZ: Asia/Tokyo
      LANG: ja_JP.UTF-8
      LC_ALL: ja_JP.UTF-8
    command:
      --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
    volumes:
      - db-data:/var/lib/mysql
      - ./db/init:/docker-entrypoint-initdb.d
  php:
    build: .
    depends_on:
      - db
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_TABLE: ${MYSQL_TABLE}
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
volumes:
  db-data:

MySQLの日本語対応のため

      TZ: Asia/Tokyo
      LANG: ja_JP.UTF-8
      LC_ALL: ja_JP.UTF-8
    command:
      --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci

データベースの初期設定のため

      - ./db/init:/docker-entrypoint-initdb.d
init.sql データベースの初期化用のコマンド
CREATE DATABASE IF NOT EXISTS example_database;

use example_database;

CREATE TABLE IF NOT EXISTS todo_list(
        item_id INT AUTO_INCREMENT,
        content VARCHAR(255),
        PRIMARY KEY(item_id)
);

INSERT INTO todo_list (content) VALUES ("消しゴムを買う");
INSERT INTO todo_list (content) VALUES ("銀行で家賃を振り込む");
INSERT INTO todo_list (content) VALUES ("洗濯機の修理を依頼する");
todo_list.php
<?php
$user = getenv('MYSQL_USER');
$password = getenv('MYSQL_PASSWORD');
$database = getenv('MYSQL_DATABASE');
$table = getenv('MYSQL_TABLE');
$dsn = "mysql:host=db;dbname={$database};charset=utf8";
?>
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>ToDoリスト</title>
  </head>
  <body>
    <div>
      <?php
      try {
        $pdo = new PDO($dsn, $user, $password);
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $sql = "SELECT * FROM $table";
        $stm = $pdo->prepare($sql);
        $stm->execute();
        $result = $stm->fetchAll(PDO::FETCH_ASSOC);
        echo "<table border='1'>";
        echo "<thead><tr>";
        echo "<th>", "ID", "</th>";
        echo "<th>", "ToDo", "</th>";
        echo "</tr></thead>";
        echo "<tbody>";
        foreach ($result as $row){
          echo "<tr>";
          echo "<td>", $row['item_id'], "</td>";
          echo "<td>", $row['content'], "</td>";
          echo "</tr>";
        }
        echo "</tbody>";
        echo "</table>";
      } catch (Exception $e) {
        echo '<span class="error">エラーがありました。</span><br>';
        echo $e->getMessage();
        exit();
      }
      ?>
    </div>
  </body>
</html>

パスワードにsecretsを使用する場合

ディレクトリ構成

$ ls -Ra
.:
.  ..  .env  Dockerfile  compose.yaml  db  mysql_password.txt  mysql_root_password.txt  src

./db:
.  ..  init

./db/init:
.  ..  init.sql

./src:
.  ..  dbsample.php  todo_list.php

ファイル

.env 環境変数の値を記述する
MYSQL_DATABASE=example_database
MYSQL_USER=example_user
MYSQL_TABLE=todo_list
Dockerfile apacheを含むPHPを使用
FROM php:8.5.2-apache
RUN apt update && apt install -y libonig-dev && docker-php-ext-install pdo_mysql
compose.yaml
services:
  db:
    image: mysql:9.5.0
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root_password
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD_FILE: /run/secrets/mysql_password
      TZ: Asia/Tokyo
      LANG: ja_JP.UTF-8
      LC_ALL: ja_JP.UTF-8
    command:
      --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
    secrets:
      - mysql_password
      - mysql_root_password
    volumes:
      - db-data:/var/lib/mysql
      - ./db/init:/docker-entrypoint-initdb.d
  php:
    build: .
    depends_on:
      - db
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD_FILE: /run/secrets/mysql_password
      MYSQL_TABLE: ${MYSQL_TABLE}
    secrets:
      - mysql_password
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
volumes:
  db-data:

secrets:
  mysql_password:
    file: ./mysql_password.txt
  mysql_root_password:
    file: ./mysql_root_password.txt
init.sql データベースの初期化用のコマンド
CREATE DATABASE IF NOT EXISTS example_database;

use example_database;

CREATE TABLE IF NOT EXISTS todo_list(
        item_id INT AUTO_INCREMENT,
        content VARCHAR(255),
        PRIMARY KEY(item_id)
);

INSERT INTO todo_list (content) VALUES ("消しゴムを買う");
INSERT INTO todo_list (content) VALUES ("銀行で家賃を振り込む");
INSERT INTO todo_list (content) VALUES ("洗濯機の修理を依頼する");
todo_list.php
<?php
$password_file = getenv('MYSQL_PASSWORD_FILE');
$user = getenv('MYSQL_USER');
$password = rtrim(file_get_contents($password_file));
$database = getenv('MYSQL_DATABASE');
$table = getenv('MYSQL_TABLE');
$dsn = "mysql:host=db;dbname={$database};charset=utf8";
?>
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>ToDoリスト</title>
  </head>
  <body>
    <div>
      <?php
      try {
        $pdo = new PDO($dsn, $user, $password);
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $sql = "SELECT * FROM $table";
        $stm = $pdo->prepare($sql);
        $stm->execute();
        $result = $stm->fetchAll(PDO::FETCH_ASSOC);
        echo "<table border='1'>";
        echo "<thead><tr>";
        echo "<th>", "ID", "</th>";
        echo "<th>", "ToDo", "</th>";
        echo "</tr></thead>";
        echo "<tbody>";
        foreach ($result as $row){
          echo "<tr>";
          echo "<td>", $row['item_id'], "</td>";
          echo "<td>", $row['content'], "</td>";
          echo "</tr>";
        }
        echo "</tbody>";
        echo "</table>";
      } catch (Exception $e) {
        echo '<span class="error">エラーがありました。</span><br>';
        echo $e->getMessage();
        exit();
      }
      ?>
    </div>
  </body>
</html>

環境変数 MYSQL_PASSWORD_FILEにパスワードファイルのパスを設定しているので、そのファイルからパスワードを読み出す。

$password_file = getenv('MYSQL_PASSWORD_FILE');
$password = rtrim(file_get_contents($password_file));
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?