LoginSignup
2
3

PHP Docker

Last updated at Posted at 2023-05-21

追記

PHP, nginx, mysql, phpmyadminをDockerで構築する記事を新たに公開しました。
そちらではhealthcheckを用いて各コンテナの実行順序をコントロールしています。
合わせて確認していただけると幸いです。


はじめに

備忘録です。
PHPでのDocker構築には選択肢がいろいろありそうだったので一通り全て試してみました。

PHPをWebサーバーで実行する方法の違い

WebサーバーでPHPを実行する方法は2つある

  • モジュールモード PHPをWebサーバーに組み込み同一プロセスで実行
    (dockerimage: php-apatch)

  • CGIモード PHPをWebサーバーの外(別プロセス)で実行する
    (PHPとWebサーバーでコンテナを分ける)

Docker Imageの違い

Docker ImageにはCLIとFPMとphp-module版の3つがある

  • Apache: PHPとApacheが含まれておりモジュールモードで実行できる
  • CLI: ターミナルなどからPHPスクリプトを直接実行する
  • FPM: WebサーバーがPHPエンジンを介してスクリプトを実行する(CGI)
    (FPMはWebサーバーとPHPエンジンの間で橋渡しをしている)

PHP-CLI

PHPをCLIで利用する最小構成
Dockerfile

FROM php:8.1.19-cli-buster
WORKDIR /usr/src/myapp
COPY . /usr/src/myapp

docker-compose.yml

version: "3.8"
services:
  php:
    build: .
    tty: true
    volumes:
      - ./:/usr/src/myapp
    environment:
      - TZ=Asia/Tokyo

PHP-apache

PHPとApacheをPHPモジュールモードで利用する

構成

html
	css
	- index.php
php
	- .env
	- Dockerfile
	- php.ini

db

docker-compose.yml

Dockerfile

FROM php:8.1.19-apache-bullseye
WORKDIR /usr/src/myapp
COPY ./html /var/www/html

docker-compose.yml

version: "3.8"
services:
  php:
    build:
      context: .
      dockerfile: ./php/Dockerfile
    env_file: ./php/.env
    tty: true
    depends_on:
      - db
    volumes:
      - ./php/php.ini:/usr/local/etc/php/php.ini
      - ./html:/var/www/html
      - /usr/src/myapp/db # DB配下をマウントしない設定
    ports:
      - "8080:80" # apacheは80を使用
    environment:
      - TZ=Asia/Tokyo

	db:
    image: mysql:8.0.31
    platform: linux/amd64
    env_file: ./db/.env
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    volumes:
      - ./db/data:/var/lib/mysql
      - ./db/conf.d:/etc/mysql/conf.d
    ports:
      - 3306:3306
    # networks:
    #   - backend
    environment:
      TZ: Asia/Tokyo

	phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpMyAdmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=db
    depends_on:
      - db
    ports:
      - 8000:80
    # volumes:
    #   - ./phpmyadmin/sessions:/sessions

PHP-apache (composer)

Composerを利用する

構成

src
	css
	- index.php
php
	- .env
	- Dockerfile
	- php.ini

vendor

composer.json
.gitignore
.dockerignore
docker-compose.yml

Dockerfile

FROM php:8.1.19-apache-bullseye

WORKDIR /usr/src/myapp

COPY ./ /usr/src/myapp

# hash of composer. this value will change so check the official site
# https://getcomposer.org/download/
ARG COMPOSER_HASH=55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae

# Change Apache Document Root
ENV APACHE_DOCUMENT_ROOT='/usr/src/myapp/src/'

# Change Document ROOT
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

# Install Composer
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
    && php -r "if (hash_file('sha384', 'composer-setup.php') === '$COMPOSER_HASH') \
     { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
    && php composer-setup.php \
    && php -r "unlink('composer-setup.php');" \
    && mv composer.phar /usr/local/bin/composer

# Composer install
RUN composer install

docker-compose.yml
DBとPHPMyadminはPHP-Apacheと一緒

version: "3.8"
services:
  app:
    build:
      context: .
      dockerfile: ./php/Dockerfile
    tty: true
    depends_on:
      - db
    volumes:
      - ./php/php.ini:/usr/local/etc/php/php.ini
      - ./:/usr/src/myapp
    ports:
      - "8080:80"
    environment:
      - TZ=Asia/Tokyo

PHP nginx

最近だとnginxを使うことが一番多いらしい
Composerを導入する例を用いて実装する

構成

src
	css
	- index.php
php
	- .env
	- Dockerfile
	- php.ini
	- default.conf

vendor

db
	- .env
	data
	conf.d
		- my.cnf

composer.json
.gitignore
.dockerignore
docker-compose.yml

.dockerignore

vendor

Dockerfile

FROM php:8.1.19-fpm-bullseye

WORKDIR /usr/src/myapp

COPY ./ /usr/src/myapp

# hash of composer. this value will change so check the official site
# https://getcomposer.org/download/
ARG COMPOSER_HASH=55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae

# Install Composer
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
    && php -r "if (hash_file('sha384', 'composer-setup.php') === '$COMPOSER_HASH') \
     { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
    && php composer-setup.php \
    && php -r "unlink('composer-setup.php');" \
    && mv composer.phar /usr/local/bin/composer

# Composer install
RUN composer install

docker-compose.yml

version: "3.8"
services:
  php:
    build:
      context: .
      dockerfile: ./php/Dockerfile
    env_file: ./php/.env
    tty: true
    depends_on:
      - db
    volumes:
      - ./php/php.ini:/usr/local/etc/php/php.ini
      - ./:/usr/src/myapp
      - /usr/src/myapp/db # DB配下をマウントしない設定
    environment:
      - TZ=Asia/Tokyo
  nginx:
    image: nginx:latest
    ports:
      - 8080:80
    volumes:
      - ./src:/usr/src/myapp/src
      - ./php/default.conf:/etc/nginx/conf.d/default.conf
  db:
    image: mysql:8.0.31
    platform: linux/amd64
    env_file: ./db/.env
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    volumes:
      - ./db/data:/var/lib/mysql
      - ./db/conf.d/my.cnf:/etc/mysql/conf.d/my.cnf
    ports:
      - 3306:3306
    environment:
      TZ: Asia/Tokyo

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpMyAdmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=db
    depends_on:
      - db
    ports:
      - 8000:80
    # volumes:
    #   - ./phpmyadmin/sessions:/sessions

/etc/nginx/conf.d/default.conf

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    # DocumentRoot
    root   /usr/src/myapp/src;
    # "/"の時に返却するファイルを指定
    index  index.html index.htm index.php;

    location  / {
        # 左から順に評価
        # 存在しなければ最後の指定に従ってindex.phpを返す
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        # php-fpmのservice名:9000
        fastcgi_pass  php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        include       fastcgi_params;
    }
}

おわりに

一番時間がかかったのはnginxの仕様や設定でした。
Webサーバーの設定自分でやったことなかったので...
コピペで動いたとは思いますが、内容をきちっと理解するために時間がかかりました。

現在お世話になっている会社でPHPを利用しているので勉強のためDocker環境を自作してみました。
Webサーバーが何なのかフワッとした印象でしたが、今回の勉強を通して理解が深まりました。

参考

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