ソフトウェアをコンテナ化するためのプラットフォームのDockerを使ってみます。
用語 | 意味 |
---|---|
Dockerコンテナ | アプリケーションとその依存関係を一つのパッケージとして隔離した実行環境 |
Dockerイメージ | コンテナの設計図で、必要なソフトウェアやライブラリ、設定が含まれた静的なファイル群 |
準備
Windows環境でやっていきます。
Docker Desktopのインストール
https://www.docker.com/get-started/
「Download Docker Desktop」を押してダウンロード、インストールしてください
Ubuntu
OSです。
Dockerイメージが公開されているDocker Hubを開きます。
Ubuntuを検索
https://hub.docker.com/_/ubuntu
ubuntu:24.04のイメージを使ってみます。
これはubuntuのDockerイメージで24.04というtagがついているものを使うという意味です。
「:latest」というタグは最新版という意味で、pullする時期によって指すバージョンが変わってしまうので、自分でも後で使うかもしれない場合や、他人と共有したりする目的で使うのは避けましょう。
コンテナを起動すると、元にしたDockerイメージに設定されているデフォルトコマンドが実行されるので、確認しておきます。
デフォルトコマンド:CMD ["/bin/bash"]
ファイル構成
project/
└ compose.yaml
Dockerコンテナを複数連携させて管理するための設定ファイルであるcompose.yamlを作成します。
services: # コンテナとして実行するサービスを定義するセクションの開始を意味する
ubuntu: # サービス名の指定(任意の文字列) Docker内部のネットワーク名や依存関係の指定に使用
image: ubuntu:24.04 #タグ名まで含めたDockerイメージの指定
container_name: ubuntu #コンテナ名の指定(任意の文字列) docker psで表示される名前
stdin_open: true # 標準入力を開いたままにする
tty: true # 仮想端末を有効にする
デフォルトコマンドでbashが指定されていても、stdin_openとttyの設定をしないとbashで操作できないため記載が必要です。
container_nameを省略するとコンテナ名は「Docker Compose が実行されるディレクトリの名前_サービス名_番号」になります
コンテナを起動
作成したcompose.yamlを元にしてコンテナを起動します
# コンテナを起動
docker compose up
# コンテナをバックグラウンドで起動(-d は "detached" の略で、コンテナをバックグラウンドで起動するオプション) ※基本はこれを使う
docker compose up -d
# イージをビルドし直す時
docker compose up -d --build
# キャッシュなしで再ビルド
docker compose build --no-cache
# コンテナを停止
docker compose down
初回コンテナ起動時は使用するDockerイメージがローカルに存在しないのでダウンロードが始まります。
//起動しているコンテナの確認
docker ps
CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS | NAMES |
---|---|---|---|---|---|---|
e632506d7889 | ubuntu:24.04 | "/bin/bash" | 17 seconds ago | Up 16 seconds | ubuntu |
Docker DesiktopのContainersタブでも確認できます
使ってみる
bashに接続
//ubuntuコンテナ内でbashシェルを実行する
//docker exec -it コンテナ名 bash
docker exec -it ubuntu bash
//bashの入力待ちになるのでコマンドを試してみる
//bashの終了はexit+Enterキー
Fedra
OSです。
イメージはfedora:42を使います。
デフォルトコマンド:CMD ["/bin/bash"]
ファイル構成
project/
└ compose.yaml
services:
app:
image: fedora:42
container_name: fedra
stdin_open: true # インタラクティブシェルを有効化(オプション)
tty: true # 仮想端末を使用(オプション)
コンテナ起動
docker compose up -d
使ってみる
Fedraコンテナ内でbashシェルを実行する
//docker exec -it コンテナ名 /bin/bash
docker exec -it fedra /bin/bash
//bashの入力待ちになるのでコマンドを試してみる
//bashの終了はexit+Enterキー
Apache
ウェブサーバーです。
イメージはhttpd:2.4.63を使います。
デフォルトコマンド:CMD ["httpd-foreground"]
ファイル構成
project/
├ compose.yaml
└ html/
└ index.html
services:
apache:
image: httpd:2.4.63
container_name: apache
ports:
- "8080:80" #ホストのポート 8080をコンテナのポート80にマッピング
volumes:
- ./html:/usr/local/apache2/htdocs/ #プロジェクト/htmlディレクトリをコンテナの/usr/local/apache2/htdocs/ にマッピング
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
HTML
</body>
</html>
コンテナ起動
//コンテナを起動
docker-compose up -d
使ってみる
http://localhost:8080 でhtml/index.htmlの内容が表示されます
nginx
Webサーバーです。
イメージはnginx:1.26.3を使います。
https://hub.docker.com/layers/library/nginx/1.26.3/images/sha256-b1f9004dc208f2c78aa60798f37f37efaf03c0b1df61020e25f36c3894b83651
デフォルトコマンド:CMD ["nginx" "-g" "daemon off;"]
ファイル構成
project/
├ compose.yaml
├ html/
│ └ index.html
└ nginx
└ default.conf
services:
nginx:
image: nginx:1.26.3
container_name: nginx
ports:
- "8080:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./html:/usr/share/nginx/html
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
HTML
</body>
</html>
コンテナ起動
docker-compose up -d
使ってみる
http://localhost:8080 でindex.htmlの内容が表示されます
mySQL
RDBMSです。
イメージはmysql:9.0.1を使います
デフォルトコマンド:CMD ["mysqld"]
ファイル構成
project/
├ compose.yaml
├ .env
├ html/
│ └ index.html
└ nginx
└ default.conf
services:
mysql:
image: mysql:9.0.1
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
ports:
- "3306:3306" # ホストとコンテナ間のポートマッピング
volumes:
- mysql_data:/var/lib/mysql # データの永続化
volumes:
mysql_data:
MYSQL_ROOT_PASSWORD=example # MySQLのrootパスワード
MYSQL_DATABASE=mydatabase # 初期データベース名
コンテナ起動
docker-compose up -d
使ってみる
mySQLにログイン
//docker exec -it mySQLのコンテナ名 mysql -u root -p
docker exec -it mysql mysql -u root -p
//下記が表示されるのでcompose.yamlで指定したrootユーザーのパスワードexampleを入力してEnter
Enter password:
//mySQLの入力待ちになる
//データベースの一覧表示
SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydatabase |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.02 sec)
SHOW VARIABLES LIKE '%version%';
+-----------------------------+------------------------------+
| Variable_name | Value |
+-----------------------------+------------------------------+
| admin_tls_version | TLSv1.2,TLSv1.3 |
| explain_json_format_version | 1 |
| immediate_server_version | 999999 |
| innodb_version | 9.0.1 |
| original_server_version | 999999 |
| protocol_version | 10 |
| replica_type_conversions | |
| slave_type_conversions | |
| tls_version | TLSv1.2,TLSv1.3 |
| version | 9.0.1 |
| version_comment | MySQL Community Server - GPL |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
| version_compile_zlib | 1.2.13 |
+-----------------------------+------------------------------+
14 rows in set (0.01 sec)
//mySQLから出るにはexit+Enterキー
PHP
サーバーサイドのスクリプト言語です。
イメージはphp:8.4-fpmを使います。
デフォルトコマンド:CMD ["php-fpm"]
ファイル構成
PHPだけでWebサーバーがないとWebページが表示できないのでnginxも一緒に起動します。
(apacheが同梱されているPHPのDockerイメージもあります)
project/
├ compose.yaml
├ html/
│ └ index.php
└ nginx/
└ default.conf
services:
nginx:
image: nginx:1.26.3
container_name: nginx
ports:
- "8080:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf # default.confをコンテナにマウント
depends_on:
- php
php:
image: php:8.4-fpm
container_name: php-fpm
volumes:
- ./html:/var/www/html # phpコンテナの/var/www/htmlにホストマシンのcompose.yamlと同じ階層にあるhtmlフォルダをマウント
<?php
phpinfo();
?>
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
コンテナ起動
docker-compose up -d
使ってみる
http://localhost:8080 を開くとindex.phpの内容が表示されます
mySQLとphpMyAdmin
phpMyAdminはMySQLデータベースを管理するためのウェブベースのツールです
イメージはphpmyadmin/phpmyadmin:5.2.2を使います
デフォルトコマンド:CMD ["apache2-foreground"]
ファイル構成
project/
├ compose.yaml
├ .env
└ mysql/
└ my.cnf
services:
phpmyadmin:
image: phpmyadmin/phpmyadmin:5.2.2 # phpmyadmin/phpmyadmin:5.2.2であることに注意
container_name: phpmyadmin
ports:
- "8081:80" # ホストのポート8081をコンテナの80ポートにマッピング
environment:
PMA_HOST: ${PMA_HOST}
PMA_PORT: 3306
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
restart: always # 常に再起動
mysql:
image: mysql:9.0.1
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
volumes:
- mysql-data:/var/lib/mysql # データ永続化のためボリュームを使用
- ./mysql/my.cnf:/etc/mysql/my.cnf # my.cnf をコンテナにマウント
ports:
- "3306:3306" # MySQLのポートをホストに公開
restart: always # 常に再起動
volumes:
mysql-data: # mysql-dataという名前のデータボリュームを作成
driver: local # ボリュームをホストマシンのファイルシステムに格納(省略可能)
PMA_HOST: mysql # MySQLのサービス名(コンテナ名ではなく)
MYSQL_ROOT_PASSWORD: example # MySQLのrootパスワード
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = 'Asia/Tokyo'
コンテナ起動
docker-compose up -d
使ってみる
phpMyAdmin
GUIでデータベースを操作できます
http://localhost:8081 でphpMyAdminにアクセス
項目 | 値 |
---|---|
ユーザー名 | root |
パスワード | example |
mySQL
※Windows環境で、phpMyAdminから入れた日本語が???になってしまう場合の対応
my.cnfを右クリック→プロパティで「読み取り専用」にチェックしてください
ログイン
docker exec -it mysql mysql -u root -p
//パスワードを聞かれるので上で設定したものを入力してEnterキー
//mySQLの入力待ちになる
//データベースの一覧表示でphpMyAdminでの操作が反映されていることを確認する
SHOW DATABASES;
(mysqlで日本語を入力すると消えるのは、後半で対応します。)
bashにログイン
docker exec -it mysql bash
PHPとnginxとmySQLとphpMyAdmin
ファイル構成
project/
├ compose.yaml
├ .env
├ html/
│ └ index.php
├ mysql
│ └ my.cnf
└ nginx/
└ default.conf
services:
nginx:
image: nginx:1.26.3
container_name: nginx
ports:
- "8080:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
php:
image: php:8.4-fpm
container_name: php-fpm
command:
- bash
- -c
- |
apt-get update && apt-get install -y libmariadb-dev && docker-php-ext-install mysqli && php-fpm
volumes:
- ./html:/var/www/html
environment:
MYSQL_HOST: mysql # MySQLのホスト名としてサービス名(mysql)を設定
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_PORT: 3306
MYSQL_DATABASE: ${MYSQL_DATABASE}
depends_on:
- mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin:5.2.2
container_name: phpmyadmin
ports:
- "8081:80" # ホストのポート8081をコンテナの80ポートにマッピング
environment:
PMA_HOST: ${PMA_HOST}
PMA_PORT: 3306
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} # MySQLのrootパスワード
restart: always # 常に再起動
mysql:
image: mysql:9.0.1
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} # MySQLのrootパスワード
MYSQL_DATABASE: ${MYSQL_DATABASE}
volumes:
- mysql-data:/var/lib/mysql # データ永続化のためボリュームを使用
- ./mysql/my.cnf:/etc/mysql/my.cnf # my.cnfをコンテナにマウント
ports:
- "3306:3306" # MySQLのポートをホストに公開
restart: always # 常に再起動
volumes:
mysql-data:
driver: local
MYSQL_ROOT_PASSWORD=example # MySQLのrootパスワード
MYSQL_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
PMA_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
MYSQL_DATABASE=mydatabase # MySQLの初期データベース名
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = 'Asia/Tokyo'
<?php
$servername = getenv('MYSQL_HOST'); // MySQLのホスト名(phpコンテナ内のサービス名)
$username = 'root';
$password = getenv('MYSQL_ROOT_PASSWORD'); // rootパスワード
$dbname = getenv('MYSQL_DATABASE'); // テスト用のデータベース名
$port = getenv('MYSQL_PORT'); // ポート番号(環境変数から取得)
// MySQLに接続
$conn = new mysqli($servername, $username, $password, $dbname, $port); // データベースを指定して接続
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// データベースに接続成功
echo "データベース'$dbname'への接続に成功しました。";
// 接続を閉じる
$conn->close();
?>
コンテナ起動
docker-compose up -d
使ってみる
http://localhost:8080 で index.phpを表示
http://localhost:8081 を開くとphpMyAdminにアクセス
Dockerfileの使用
これまでcompose.yamlで頑張ってきましたが、それぞれのコンテナの元になるイメージ自体の変更をするためにDockerfileを使っていきます。
MySQL(Dockerfile使用版)
変更箇所 | 内容 |
---|---|
compose.yamlの変更 | mysqlがimagesだったのをbuildオプションに変更してmysql/Dockerfileを参照するように変更 |
mysql/Dockerfileの追加 | 日本語ロケールの指定 初期化SQLスクリプトの追加 |
mysql/init.sqlの追加 | データベースとユーザーを作成するSQL |
ファイル構成
project/
├ compose.yaml
├ .env
├ html/
│ └ index.php
├ mysql/
│ ├ Dockerfile
│ ├ init.sql
│ └ my.cnf
└ nginx/
└ default.conf
services:
nginx:
image: nginx:1.26.3
container_name: nginx
ports:
- "8080:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
php:
image: php:8.4-fpm
container_name: php-fpm
command:
- bash
- -c
- |
apt-get update && apt-get install -y libmariadb-dev && docker-php-ext-install mysqli && php-fpm
volumes:
- ./html:/var/www/html
environment:
MYSQL_HOST: mysql # MySQLのホスト名としてサービス名(mysql)を設定
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_PORT: 3306
depends_on:
- mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin:5.2.2
container_name: phpmyadmin
ports:
- "8081:80" # ホストのポート8081をコンテナの80ポートにマッピング
environment:
PMA_HOST: ${PMA_HOST}
PMA_PORT: 3306
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
restart: always # 常に再起動
mysql:
build:
context: ./mysql # mysql フォルダにある Dockerfile を使う
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
volumes:
- mysql-data:/var/lib/mysql # データ永続化のためボリュームを使用
- ./mysql/my.cnf:/etc/mysql/my.cnf # my.cnf をコンテナにマウント
ports:
- "3306:3306" # MySQLのポートをホストに公開
restart: always # 常に再起動
volumes:
mysql-data:
driver: local
MYSQL_ROOT_PASSWORD=example # MySQLのrootパスワード
MYSQL_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
PMA_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
<?php
$servername = getenv('MYSQL_HOST'); // MySQLのホスト名(phpコンテナ内のサービス名)
$username = 'root';
$password = getenv('MYSQL_ROOT_PASSWORD'); // rootパスワード
$dbname = getenv('MYSQL_DATABASE'); // テスト用のデータベース名
$port = getenv('MYSQL_PORT'); // ポート番号(環境変数から取得)
// MySQLに接続
$conn = new mysqli($servername, $username, $password, $dbname, $port); // データベースを指定して接続
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// データベースに接続成功
echo "データベース'$dbname'への接続に成功しました。";
// 接続を閉じる
$conn->close();
?>
FROM mysql:9.0.1
# microdnf を使って bash と locales をインストール
RUN microdnf install -y bash glibc-langpack-ja
# ロケールの設定
ENV LANG ja_JP.UTF-8
# 初期化用SQLをコピー
COPY ./init.sql /docker-entrypoint-initdb.d/
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = 'Asia/Tokyo'
-- 初期データベースの作成
CREATE DATABASE IF NOT EXISTS mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- ユーザーの作成と権限の付与
CREATE USER IF NOT EXISTS 'myuser'@'%' IDENTIFIED BY 'mypassword';
GRANT ALL PRIVILEGES ON mydatabase.* TO 'myuser'@'%';
-- 権限の反映
FLUSH PRIVILEGES;
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
コンテナを起動
docker-compose up -d
使ってみる
http://localhost:8080 でindex.phpを表示
http://localhost:8081 でphpMyAdminにアクセス
PHP(Dockerfile使用版)
変更箇所 | 内容 |
---|---|
compose.yamlの変更 | phpがimagesだったのをbuild オプションに変更してphp/Dockerfileを参照するように変更 拡張機能の追加をphp/Dockerfileに移動 |
php/Dockerfileの追加 | 拡張機能の追加 php.iniをコンテナ内の適切な場所にコピー |
php/php.iniの追加 | PHPの設定 |
ファイル構成
project/
├ compose.yaml
├ .env
├ html/
│ └ index.php
├ mysql
│ ├ Dockerfile
│ ├ init.sql
│ └ my.cnf
├ php/
│ ├ Dockerfile
│ └ php.ini
└ nginx/
└ default.conf
services:
nginx:
image: nginx:1.26.3
container_name: nginx
ports:
- "8080:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
php:
build:
context: ./php # 新しく作成したphpフォルダ内のDockerfileを使用
container_name: php-fpm
volumes:
- ./html:/var/www/html
environment:
MYSQL_HOST: mysql # MySQLのホスト名としてサービス名(mysql)を設定
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_PORT: 3306
depends_on:
- mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin:5.2.2
container_name: phpmyadmin
ports:
- "8081:80" # ホストのポート8081をコンテナの80ポートにマッピング
environment:
PMA_HOST: ${PMA_HOST}
PMA_PORT: 3306
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
restart: always # 常に再起動
mysql:
build:
context: ./mysql # mysql フォルダにある Dockerfile を使う
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
volumes:
- mysql-data:/var/lib/mysql # データ永続化のためボリュームを使用
- ./mysql/my.cnf:/etc/mysql/my.cnf # my.cnf をコンテナにマウント
ports:
- "3306:3306" # MySQLのポートをホストに公開
restart: always # 常に再起動
volumes:
mysql-data:
driver: local
FROM php:8.4-fpm
# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y \
# MySQL/MariaDBとの接続をサポートするライブラリ(mysqli用)
libmariadb-dev \
# PNG画像の操作をサポート
libpng-dev \
# JPEG画像の操作をサポート
libjpeg-dev \
# FreeTypeライブラリ(フォントレンダリングのためのライブラリ)
libfreetype6-dev \
# 圧縮ライブラリ(画像やファイル圧縮に使用)
zlib1g-dev \
# XML処理用のライブラリ
libxml2-dev \
# 国際化機能(多言語対応、地域設定など)
libicu-dev \
# mbstringで必要なライブラリ
libonig-dev \
# ZIPファイル操作に必要なライブラリ
libzip-dev \
# Gitのインストール(ソースコード管理などに使用)
git \
# PHP拡張モジュールのインストール
&& docker-php-ext-install \
# 画像処理ライブラリ(画像の生成・加工が可能)
gd \
# マルチバイト文字列操作をサポート(日本語や中国語など)
mbstring \
# 高精度な数値計算(大きな整数や小数を扱う)
bcmath \
# ZIPファイルの圧縮・解凍
zip \
# SOAP Webサービスクライアントを提供(XMLベースのWebサービスとの通信)
soap \
# 国際化対応(多言語やロケールに関連する処理)
intl \
# mysqli拡張をインストール(MySQL/MariaDBとの接続)
mysqli \
# PECLで追加の拡張をインストール
&& pecl install xdebug \
# インストールした拡張を有効化
&& docker-php-ext-enable xdebug
[PHP]
; 基本的な設定
max_execution_time = 30
memory_limit = 256M
; エラーレポートの設定
display_errors = On
error_reporting = E_ALL
; xdebugの設定
[xdebug]
zend_extension=xdebug.so
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.log_level=0
xdebug.log=/tmp/xdebug.log
; PHPの文字エンコーディング設定
default_charset = "UTF-8"
MYSQL_ROOT_PASSWORD=example # MySQLのrootパスワード
MYSQL_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
PMA_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
<?php
$servername = getenv('MYSQL_HOST'); // MySQLのホスト名(phpコンテナ内のサービス名)
$username = 'root';
$password = getenv('MYSQL_ROOT_PASSWORD'); // rootパスワード
$dbname = 'mydatabase'; // init.sqlで作成するデータベース名
$port = getenv('MYSQL_PORT'); // ポート番号(環境変数から取得)
// MySQLに接続
$conn = new mysqli($servername, $username, $password, $dbname, $port); // データベースを指定して接続
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// データベースに接続成功
echo "データベース'$dbname'への接続に成功しました。";
// 接続を閉じる
$conn->close();
?>
FROM mysql:9.0.1
# microdnf を使って bash と locales をインストール
RUN microdnf install -y bash glibc-langpack-ja
# ロケールの設定
ENV LANG ja_JP.UTF-8
# 初期化用SQLをコピー
COPY ./init.sql /docker-entrypoint-initdb.d/
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = 'Asia/Tokyo'
-- 初期データベースの作成
CREATE DATABASE IF NOT EXISTS mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- ユーザーの作成と権限の付与
CREATE USER IF NOT EXISTS 'myuser'@'%' IDENTIFIED BY 'mypassword';
GRANT ALL PRIVILEGES ON mydatabase.* TO 'myuser'@'%';
-- 権限の反映
FLUSH PRIVILEGES;
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
コンテナを起動
docker-compose up -d
php/Dockerfileで指定したパッケージがインストールされているかの確認
docker-compose exec php php -m
使ってみる
http://localhost:8080 でindex.phpの内容を表示
http://localhost:8081 でphpMyAdminにアクセス
Dockerfileで指定できる主な命令
命令 | 内容 |
---|---|
FROM | ベースとなるイメージを指定Dockerfileの最初に記述 |
ADD | ローカルにあるファイルやディレクトリ、URL、tarアーカイブファイルなどをコンテナ内にコピー(COPY の方が推奨) |
COPY | ローカルのファイルやディレクトリをコンテナ内にコピー |
RUN | コンテナ内でコマンドを実行 |
CMD | コンテナが起動した際に実行されるデフォルトのコマンドを指定 |
ENTRYPOINT | コンテナが起動する際に実行されるコマンドを指定 (CMDとの違い)コンテナを実行する際に指定するコマンドを変更不可 |
ONBUILD | 親イメージがビルドされる際に実行する命令を指定 |
EXPOSE | コンテナがリッスンするネットワークポートを指定 |
VOLUME | コンテナにマウントするボリュームを指定 |
ENV | 環境変数を設定 |
WORKDIR | 作業ディレクトリを設定 |
SHELL | RUN コマンドの実行時に使うシェルを変更 |
LABEL | イメージにメタデータを付与 |
USER | コンテナ内で実行するユーザーを指定 |
ARG | ビルド時に渡される変数を定義 |
STOPSIGNAL | コンテナの停止に使用するシグナルを指定 |
HEALTHCHECK | コンテナのヘルスチェックを設定 |
イメージに不要なものを含めない
.dockerignore
Dockerイメージをビルドする時に、どのファイルやディレクトリを無視するかを指定できます
Dockerfile用.dockerignore
主にビルドに関連しないファイルを無視します
例:依存関係、IDE 設定、ログ、一時ファイルなど
# バージョン管理のディレクトリ(Git)
.git/
# IDEの設定ファイル(VSCode、IntelliJ等)
.vscode/
.idea/
# Node.js の依存関係(再インストール可能)
node_modules/
# PHP の依存関係(再インストール可能)
vendor/
# 一時ファイルやバックアップファイル
tmp/
temp/
*~
*.bak
# ログファイル(不要)
*.log
# コンパイル済みのバイナリや中間ファイル(例: Pythonのバイトコード)
*.pyc
*.pyo
compose.yaml用.dockerignore
開発用の設定ファイルや開発環境専用ファイルを無視します
例:.env ファイル、docker-compose.override.yaml など
# .env ファイル(環境設定や機密情報が含まれているため)
.env
# Node.js の依存関係(再インストール可能)
node_modules/
# PHP の依存関係(再インストール可能)
vendor/
# 開発環境用のオーバーライド設定
docker-compose.override.yaml
# IDEの設定ファイル(VSCode、IntelliJ等)
.vscode/
.idea/
# Git リポジトリ関連ファイル
.git/
# ログファイル(不要)
*.log
# 一時ファイルやバックアップファイル
tmp/
temp/
*~
# README やドキュメントファイル(ビルドには不要)
*.md
マルチステージビルド
今回は扱いませんが、Dockerfileをマルチステージビルドに対応した記述に変更することで、不要なものを取り除き、イメージの軽量化、セキュリティ向上、ビルド速度の向上、柔軟性の確保ができます
問題があるときの調査方法
コンテナの詳細の確認
docker container inspect コンテナ名
イメージの詳細の確認
docker image inspect イメージ名:タグ
ボリュームの詳細の確認
docker volume inspect ボリューム名
ネットワークの詳細の確認
docker network inspect ネットワーク名
コンテナ情報の表示
//停止中のコンテナも含めて、すべてのコンテナの情報を表示
docker compose ps -a:
//特定のサービスのコンテナの状態を表示
docker compose ps サービス名:
コンテナの中を調べる
docker exec -it コンテナ名 bash
cat ファイル名
ログの確認
//単一のコンテナのログを表示
docker logs コンテナ名
//compose.yamlで定義されたコンテナのログを表示
docker-compose logs コンテナ名
Gordonに聞く
(Docker Desktopバージョン4.38以降が必要)
DockerのAIエージェントであるGordonに助けてもらうことができます
デフォルトでは無効になっているため、設定メニューから有効化する必要があります
(設定画面のFeatures in developmentでEnable Docker AIにチェックを入れてApply & restart
Containers、Imagesなどの上にAsk Gordonが追加されます)