【追記】2024年12月11日
- OSベースイメージである
debian:buster
がダウンロードできない (サポート切れ) のためdebian:bullseye
に変更しました。 参考 - Dockerfileの階層を変更しました。 (
/Dockerfile
→/docker/Dockerfile
)
TL;DR;
テンプレート化されていますので、複製して利用可能です。
導入
個人的に携わっている案件でphp5系の開発環境が必要になりました。
ご周知のことと思いますが、php5系は既にサポート終了しており、調べても情報が少なく、、、
私のDocker経験が浅いの相まって、非常に手間取ったので記事として残しておこうと思います。
構築した環境
- PHP5.6
- Apache2.4
- MySQL8.0
- PostFix
- MailHog
フォルダ構成
php56-apache24-postfix/
├── conf/
| ├─ entrypoint.sh
│ └─ main.cf
│
├── docker/
│ ├─ Dockerfile
│ ├─ db.initdb.d # 接頭2文字の数字の順番に沿って実行される
| | ├─ 00_create_database.sql
| | └─ 01_create_test_table.sql
| └─ php
│ └─ php.ini # phpの設定ファイル
│
├── src/ # Apacheのドキュメントルート
│
├── .gitignore
├── docker-compose.yml
└── README.md
Dockerfile
# https://wiki.debian.org/LTS を参照したところdebian:busterがサポート切れ
# bullseyeは2026年9月31日までサポート
FROM debian:bullseye
RUN apt-get update
RUN apt-get update && apt-get install -y apt-transport-https lsb-release ca-certificates wget
RUN wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
RUN echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list
RUN apt-get update && apt-get install -y \
apache2 \
php5.6 \
php5.6-mysql \
php5.6-mbstring \
libapache2-mod-php5.6 \
&& rm -rf /var/lib/apt/lists/*
RUN a2enmod php5.6
RUN a2enmod rewrite
RUN echo 'ServerName localhost' >> /etc/apache2/apache2.conf
RUN echo '<Directory /var/www/>\n\tAllowOverride All\n</Directory>' >> /etc/apache2/apache2.conf
EXPOSE 80
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
RUN apt update && apt upgrade -y
RUN DEBIAN_FRONTEND=noninteractive apt install postfix -y
RUN apt install sasl2-bin -y
RUN DEBIAN_FRONTEND=noninteractive apt install cyrus-imapd -y
COPY conf/entrypoint.sh /entrypoint.sh
COPY conf/main.cf /etc/postfix/main.cf
RUN chmod 700 /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]
debian系のベースイメージに、PHP
、Apache
、(sendmail関数が入っていなかったので)Postfix
をインストールしています。
メール送信のためにmain.cf
をコンテナ内に取り込みます。
その後、メールリレーの設定のためにentrypoint.sh
を実行します。
docker-compose.yml
version: '3'
services:
app:
container_name: php56-apache24
build:
context: .
dockerfile: docker/Dockerfile
volumes:
- ./docker/php/php.ini:/etc/php/5.6/apache2/conf.d/php.ini
- ./src:/var/www/html
ports:
- 8000:80
depends_on:
- db
environment:
- ENVIRONMENT=local
- MAIL_SERVICE=[mail]:1025
networks:
- my-network1
db:
container_name: php56-apache24-mysql8
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
restart: always
ports:
- '13306:3306'
volumes:
- ./docker/db.data:/var/lib/mysql
- ./docker/db.initdb.d:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: testuser
MYSQL_PASSWORD: testpass
MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password
networks:
- my-network1
phpmyadmin:
container_name: phpmyadmin
image: phpmyadmin/phpmyadmin
ports:
- 8080:80
environment:
PMA_HOST: db
PMA_PORT: 3306
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: testuser
MYSQL_PASSWORD: testpass
networks:
- my-network1
mail:
image: mailhog/mailhog
ports:
- '8025:8025'
- '1025:1025'
networks:
- my-network1
networks:
my-network1:
以下のコンテナを作成します
- app : PHPやApacheが動作するメインコンテナ
- db : データベース用のコンテナ
- phpmyadmin : phpMyAdmin用のコンテナ
- mail : MailHog用のコンテナ
main.cf
compatibility_level = 2
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix/sbin
data_directory = /var/lib/postfix
mail_owner = postfix
myhostname = mail.srv.world
mydomain = srv.world
myorigin = $mydomain
inet_interfaces = localhost
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
local_recipient_maps = unix:passwd.byname $alias_maps
unknown_local_recipient_reject_code = 550
mynetworks_style = subnet
mynetworks = localhost
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
home_mailbox = Maildir/
smtpd_banner = $myhostname ESMTP
debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/postfix
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
inet_protocols = ipv4
disable_vrfy_command = yes
smtpd_helo_required = yes
message_size_limit = 10240000
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions = permit_mynetworks, permit_auth_destination, permit_sasl_authenticated, reject
smtpd_tls_security_level = may
smtp_tls_security_level = may
警告
一番下の空行は必要です。
一般的なPostfixの設定に加え、一番下の2行
smtpd_tls_security_level = may
smtp_tls_security_level = may
この2行でメールリレーのセキュリティレベルを設定しています。
entrypoint.sh
#!/bin/bash
set -e
# リレーホストの設定
echo "relayhost = $MAIL_SERVICE" >> /etc/postfix/main.cf
# Postfixを起動
/usr/sbin/postfix -c /etc/postfix start
exec "$@"
ビルド ・ 起動
docker compose build
docker compose up -d
phpMyAdmin
http://localhost:8080
MailHog
http://localhost:8025
DBへの接続
環境構築とは直接関係ないので折りたたんでおきます
php56-apache24-postfix/src/database.php
<?php
$host = "db";
$port = 3306;
$dbname = "local_db";
$user = $pass = "root";
try {
// DB接続
$dsn = "mysql:host=$host;port=$port;dbname={$dbname};charset=utf8";
$pdo = new PDO($dsn, $user, $pass);
$stmt = $pdo->prepare("SELECT * FROM test_table");
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($results as $result) {
echo "<div>id: " . $result["id"] . ", name: " . $result["name"] . "</div>";
}
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
$pdo = null;
メール送信
同じく環境構築とは直接関係ないので折りたたんでおきます
php56-apache24-postfix/src/mail.php
<?php
mb_language("Japanese");
mb_internal_encoding("UTF-8");
$mail_to = "tomail@example.com";
$subject = "メールタイトル" . "\n";
$return_mail = "test@example.com";
$headers = ['From' => 'メール<info@example.com>'];
$headers = $headers
. "MIME-Version: 1.0\r\n"
. "Content-Transfer-Encoding: 8bit\r\n"
. "Content-Type: text/html; charset=UTF-8\r\n";
$message = <<<EOF
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Hello</h1>
<h2>こんにちは</h2>
<h3>コンニチハ</h3>
<h4>コンニチハ</h4>
</body>
</html>
EOF;
if (mb_send_mail($mail_to, $subject, $message, $headers, "-f" . $return_mail)) {
echo "succeeded";
} else {
echo "succeeded";
};
echo "<br>";
?>
<a href="http://localhost:8025">MailHog</a>
苦労したところ
- ベースにしたイメージに
sendmail
モジュールが入っておらず、PHPのmb_send_mail
関数が使えませんでした。 -
sendmail
をなんとか導入するためにPostfix
をインストールし、設定ファイルを書き換える(main.cfをコピーする)ことにしました。 - MailHogが日本語対応していないので、メールのヘッダーを工夫する必要がありました。
参考