GitHub CodespacesでDockerを使ってハマったメモです。
典型的な PHP(Apache) と MySQL のコンテナを作ります。
CodespacesではすでにDockerがインストールされています。
PHPのコンテナの手順
docker pull php:8.1-apache
Apache抱き合わせのPHP 8.1
イメージを取得
docker images
落としたイメージの確認
docker container run -it --name php-server -d --publish 80:80 php:8.1-apache
イメージを起動
--name
でコンテナの名前を付けます。
つけるかつけないかは任意ですが、今回はphp-server
と名付けます。
-d
はデーモンの意味
--publish
でポート指定
-it
はもうお決まりでつけておく [](https://qiita.com/k_uchida_____/items/8ca31226bd6d10850791
これをCodespacesで実行すると、80番ポートで開くようのURLでアクセスできるようになります。
クリックするとブラウザで開ける。
ただ403 Forbidden エラーページが表示される。
index.phpあるいはindex.htmlが無いので作ります。
docker container exec -it php-server bash
コンテナ「php-server(さっきつけた名前)」に入り込みます。
コンテナ内でターミナルを実行しているような感じです。
php-server:/var/www/html# echo "PHP FILE" > index.php
php-server:/var/www/html#
の部分は実際に表示されるのではなく
わかりやすいように独断で付け足したものです。
とりあえず/var/www/htmlにindex.phpを作成。
さっきのURLを更新し、「PHP FILE」と表示されていたら成功。
どうしてもviを使いたい人はインストールします。
php-server:/var/www/html# apt update
php-server:/var/www/html# apt install vim
viではなくvimな点に注意。
php-server:/var/www/html# exit
コンテナのターミナルを終了して抜け出します。
docker container rm --force php-server
コンテナ「php-server(さっき名付けた)」を削除します。
--forceで強制的に削除(ストップしてから削除の手順をすっ飛ばす)します。
index.phpを作成するもう一つの方法。
docker container cp ./index.php php-server:/var/www/html/
ホスト側でindex.php
を作成した後、コンテナのパスにコピーします。
この例では./index.phpをコンテナ(php-server)
の/var/www/html/
にコピーしてます。
*当然ですがコンテナを削除した段階ではエラーになります。
イメージの注意点
PHPのコンテナをインストールするとNginxがデフォ
docker pull php
PHPのバージョンとApacheを指定する場合
docker pull php:8.1-apache
Apacheを再起動するとコンテナが停止する
いつもの感じでApacheを再起動しようとするとコンテナごと停止してしまう。
php-server:/var/www/html# service apache2 restart
コンテナを停止せずApacheを再起動
php-server:/var/www/html# /etc/init.d/apache2 reload
PHPの拡張機能をインストールする場合の注意
php-server:/var/www/html# apt install pdo_mysql
ではなく
php-server:/var/www/html# docker-php-ext-install pdo_mysql
でインストールする
MySQLの手順
docker pull mysql
イメージ名をmysqlでやるとOSがOracle Linux
というRedHat系のLinuxになってしまう。
試してないのですがdebian用もあるのでDocker Hubを調べてください。
docker run -it --name msql -e MYSQL_ROOT_PASSWORD=oracle -d --publish 3306:3306 mysql
--name
でコンテナの名前をmsql
としました(何でもいい)
-e
は環境変数で、MYSQL_ROOT_PASWORD
でMySQLのルートのパスワードを設定します。
コンテナにログインしたとき、MySQLから求められるrootのパスワードになります。
docker container exec -it msql bash
msql(さっき作成したMySQLのコンテナの名前)に入り込みます。
bash-4.4# mysql -u root -p
bash-4.4#
はMySQLコンテナ内を表してます。
後はMySQLを実行してみましょう。
パスワードはMYSQL_ROOT_PASSWORD
で入力したものです。
exitでコンテナを抜けます。
docker container rm --force msql
msqlを削除します。
OSを調べる
コンテナに入って、そのコンテナのOSが何なのかを知るには
cat /etc/os-release
イメージ名がmysqlをそのままインストールするとOracle Linux Server 8.6
となってました。
PHP + MySQL の連携
MySQLとPHPのコンテナをそれぞれ起動
docker container run -it --name php-server -d --publish 80:80 php:8.1-apache
docker run -it --name msql -e MYSQL_ROOT_PASSWORD=oracle -d --publish 3306:3306 mysql
MySQLで使用する初期化用のファイルを用意する。
init.sql
CREATE DATABASE mydb;
USE mydb;
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
description VARCHAR(100) NOT NULL
);
INSERT INTO users VALUE(NULL, 'TAKO', '8 legs');
INSERT INTO users VALUE(NULL, 'IKA', '10 legs');
MySQLコンテナのルートにこのファイルを送り込む。
docker container cp ./mysql/init.sql msql:/
MySQLコンテナに入る
docker container exec -it msql bash
MySQLコンテナ内にてinit.sqlをMySQLに実行させる
mysql -u root -p < /init.sql
一応反映されているか確認してみましょう。
mysql> select * from users;
+----+------+-------------+
| id | name | description |
+----+------+-------------+
| 1 | TAKO | 8 legs |
| 2 | IKA | 10 legs |
+----+------+-------------+
2 rows in set (0.00 sec)
MySQLに設定されているローカルIPを取得。
cat /etc/hosts
私の環境では
172.17.0.3 104c8ec5d68e
と表示。
このIPのほうをメモっておく。
用が済んだらMySQLコンテナを抜ける。
ホスト側でindex.phpを作成
<?php
$host = "172.17.0.3";
$dns = "mysql:dbname=mydb;host={$host};port=3306";
try
{
$pdo = new PDO($dns, 'root', 'oracle');
$stm = $pdo->prepare('SELECT * FROM users');
$stm->execute();
if($items = $stm->fetchAll(PDO::FETCH_OBJ))
{
foreach($items as $item)
{
$id = $item->id;
$name = $item->name;
$description = $item->description;
echo "[$id] $name ... $description <br />";
}
}
else
{
echo "Exit";
}
}
catch(Exception $ex)
{
echo "$ex";
}
MySQLコンテナのIPを設定する。
このIPを間違えると接続するときに、
pdoexception: sqlstate[hy000] [2002] connection refused
と怒られることになる。
次にindex.phpをPHPコンテナの/var/www/htmlに配置する
docker container cp ./www/index.php php-server:/var/www/html
PHPコンテナに入る
docker container exec -it bash
pdo_mysqlをインストールする。
docker-php-ext-install pdo_mysql
Apacheを再起動する
/etc/init.d/apache2 reload
もう一度ブラウザでアクセスします。
最後に。
結構苦労しました。
めっちゃ面倒。
index.phpをコンテナにコピーしたり、init.sqlをコピーAND実行したりと
コンテナを起動するたびに1から同じことを繰り返さないといけないので大変です。
なぜなら起動したとき、それらのファイルはクリアされるからです。
そこでこれらの処理をファイルにまとめておきます。それがDockerfile
です。
次回に続く「かも」