2
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触ってみる

Last updated at Posted at 2025-02-24

ソフトウェアをコンテナ化するためのプラットフォームの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"]

ファイル構成

directory
project/
 └ compose.yaml

Dockerコンテナを複数連携させて管理するための設定ファイルであるcompose.yamlを作成します。

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を元にしてコンテナを起動します

terminal
# コンテナを起動
docker compose up

# コンテナをバックグラウンドで起動(-d は "detached" の略で、コンテナをバックグラウンドで起動するオプション) ※基本はこれを使う
docker compose up -d

# イージをビルドし直す時
docker compose up -d --build
 
# キャッシュなしで再ビルド
docker compose build --no-cache 

# コンテナを停止
docker compose down  

初回コンテナ起動時は使用するDockerイメージがローカルに存在しないのでダウンロードが始まります。

terminal
//起動しているコンテナの確認
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に接続

terminal
//ubuntuコンテナ内でbashシェルを実行する
//docker exec -it コンテナ名 bash 
docker exec -it ubuntu bash 

//bashの入力待ちになるのでコマンドを試してみる
//bashの終了はexit+Enterキー

Fedra

OSです。
イメージはfedora:42を使います。

デフォルトコマンド:CMD ["/bin/bash"]

ファイル構成

directory
project/
 └ compose.yaml
compose.yaml
services:
  app:
    image: fedora:42
    container_name: fedra
    stdin_open: true  # インタラクティブシェルを有効化(オプション)
    tty: true         # 仮想端末を使用(オプション)

コンテナ起動

terminal
docker compose up -d

使ってみる

Fedraコンテナ内でbashシェルを実行する

terminal
//docker exec -it コンテナ名 /bin/bash
docker exec -it fedra /bin/bash
 
//bashの入力待ちになるのでコマンドを試してみる
//bashの終了はexit+Enterキー

Apache

ウェブサーバーです。
イメージはhttpd:2.4.63を使います。

デフォルトコマンド:CMD ["httpd-foreground"]

ファイル構成

directory
project/
 ├ compose.yaml
  └ html/
     └ index.html
compose.yaml
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/ にマッピング
html/index.html
<!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>

コンテナ起動

terminal
//コンテナを起動
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;"]

ファイル構成

directory
project/
 ├ compose.yaml
  ├ html/
  │  └ index.html
  └  nginx
    └ default.conf
compose.yaml
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
nginx/default.conf
server {
    listen 80;
    server_name localhost;

    root /usr/share/nginx/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}
html/index.html
<!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>

コンテナ起動

terminal
docker-compose up -d

使ってみる

http://localhost:8080 でindex.htmlの内容が表示されます

mySQL

RDBMSです。
イメージはmysql:9.0.1を使います

デフォルトコマンド:CMD ["mysqld"]

ファイル構成

directory
project/
 ├ compose.yaml
  ├ .env
  ├ html/
  │  └ index.html
  └ nginx
    └ default.conf
compose.yaml
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:
.env
MYSQL_ROOT_PASSWORD=example  # MySQLのrootパスワード
MYSQL_DATABASE=mydatabase   # 初期データベース名

コンテナ起動

terminal
docker-compose up -d

使ってみる

mySQLにログイン

terminal
//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イメージもあります)

directory
project/
 ├ compose.yaml
  ├ html/
  │  └ index.php
  └ nginx/
    └ default.conf
compose.yaml
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フォルダをマウント
html/index.php
<?php
phpinfo();
?>
nginx/default.conf
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;
    }
}

コンテナ起動

terminal
docker-compose up -d

使ってみる

http://localhost:8080 を開くとindex.phpの内容が表示されます

mySQLとphpMyAdmin

phpMyAdminはMySQLデータベースを管理するためのウェブベースのツールです
イメージはphpmyadmin/phpmyadmin:5.2.2を使います

デフォルトコマンド:CMD ["apache2-foreground"]

ファイル構成

directory
project/
  ├ compose.yaml
  ├ .env
  └ mysql/
    └ my.cnf
compose.yaml
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 # ボリュームをホストマシンのファイルシステムに格納(省略可能)
.env
PMA_HOST: mysql  # MySQLのサービス名(コンテナ名ではなく)
MYSQL_ROOT_PASSWORD: example  # MySQLのrootパスワード
mysql/my.cnf
[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = 'Asia/Tokyo'

コンテナ起動

terminal
docker-compose up -d

使ってみる

phpMyAdmin

GUIでデータベースを操作できます
http://localhost:8081 でphpMyAdminにアクセス

項目
ユーザー名 root
パスワード example

mySQL

※Windows環境で、phpMyAdminから入れた日本語が???になってしまう場合の対応
my.cnfを右クリック→プロパティで「読み取り専用」にチェックしてください

ログイン
terminal
docker exec -it mysql mysql -u root -p
//パスワードを聞かれるので上で設定したものを入力してEnterキー
//mySQLの入力待ちになる

//データベースの一覧表示でphpMyAdminでの操作が反映されていることを確認する
SHOW DATABASES;

(mysqlで日本語を入力すると消えるのは、後半で対応します。)

bashにログイン
terminal
docker exec -it mysql bash

PHPとnginxとmySQLとphpMyAdmin

ファイル構成

directory
project/
  ├ compose.yaml
  ├ .env
  ├ html/
  │  └ index.php
  ├  mysql
  │  └  my.cnf
  └  nginx/
    └ default.conf
compose.yaml
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
.env
MYSQL_ROOT_PASSWORD=example  # MySQLのrootパスワード
MYSQL_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
PMA_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
MYSQL_DATABASE=mydatabase # MySQLの初期データベース名
nginx\default.conf
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\my.cnf
[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = 'Asia/Tokyo'
html/index.php
<?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();
?>

コンテナ起動

terminal
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

ファイル構成

directory
project/
  ├ compose.yaml
  ├ .env
  ├ html/
  │  └ index.php
  ├  mysql/
  │  ├ Dockerfile
  │  ├ init.sql
  │  └ my.cnf
  └  nginx/
    └ default.conf
compose.yaml
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
.env
MYSQL_ROOT_PASSWORD=example  # MySQLのrootパスワード
MYSQL_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
PMA_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
html/index.php
<?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();
?>
mysql/Dockerfile
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/my.cnf
[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = 'Asia/Tokyo'
mysql/init.sql
-- 初期データベースの作成
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;
nginx/default.conf
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;
  }
}

コンテナを起動

terminal
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の設定

ファイル構成

directory
project/
  ├ compose.yaml
  ├ .env
  ├ html/
  │  └ index.php
  ├  mysql
  │  ├ Dockerfile
  │  ├ init.sql
  │  └ my.cnf
  ├  php/
  │  ├ Dockerfile
  │  └ php.ini
  └  nginx/
    └ default.conf
compose.yaml
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
php/Dockerfile
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/php.ini
[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"
.env
MYSQL_ROOT_PASSWORD=example  # MySQLのrootパスワード
MYSQL_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
PMA_HOST=mysql # MySQLのホスト名(サービス名に合わせる)
html/index.php
<?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();
?>
mysql/Dockerfile
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/my.cnf
[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = 'Asia/Tokyo'
mysql/init.sql
 -- 初期データベースの作成
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;
nginx/default.conf
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;
  }
}

コンテナを起動

terminal
docker-compose up -d

php/Dockerfileで指定したパッケージがインストールされているかの確認

terminal
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 設定、ログ、一時ファイルなど

.dockerignore
# バージョン管理のディレクトリ(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 など

.dockerignore
# .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をマルチステージビルドに対応した記述に変更することで、不要なものを取り除き、イメージの軽量化、セキュリティ向上、ビルド速度の向上、柔軟性の確保ができます

問題があるときの調査方法

コンテナの詳細の確認

terminal
docker container inspect コンテナ名

イメージの詳細の確認

terminal
docker image inspect イメージ名:タグ

ボリュームの詳細の確認

terminal
docker volume inspect ボリューム名

ネットワークの詳細の確認

terminal
docker network inspect ネットワーク名

コンテナ情報の表示

terminal
//停止中のコンテナも含めて、すべてのコンテナの情報を表示
docker compose ps -a:

//特定のサービスのコンテナの状態を表示
docker compose ps サービス名: 

コンテナの中を調べる

terminal
docker exec -it コンテナ名 bash

cat ファイル名

ログの確認

terminal
//単一のコンテナのログを表示
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が追加されます)

2
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
2
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?