Docker+Nginx+Laravel9+php-8.1+php-fpmの環境作成

docker

記事について

windows11のWSL2(ubuntu-20.04)で、docker+laravel9+php-8.1の環境を作成するメモ。WSL特有の事はしていないので、ubuntu下であればいけると思う。

事前準備

laravel9からはphpの8.0が最低ラインになっているようなので、不足分をアップデートする。php-8と8.1の間でも速度差が20%程度あるようなので、どうせなら8.1にする。

パッケージインストール

wsl2上のubuntu 20.04で実行。最低限のものだけ上げておく。

$ sudo add-apt-repository ppa:ondrej/php
$ sudo apt update
$ sudo apt install php8.1
$ sudo apt-get install php8.1-dom

Laravel9のプロジェクト作成(インストール)

laravel9のインストール

composerをubuntuにも入れているので、composerでさくっと入れる。プロジェクト名称は「laravel9-app」とした。自分の環境だと入れた瞬間から9だった。

$ composer create-project laravel/laravel laravel9-app
$ cd laravel9-app
$ php artisan --version
Laravel Framework 9.40.1

Docker環境の作成

ディレクトリ作成

dockerに必要なディレクトリを作成していく。

[上で作成したlaravel9-appディレクトリにいる前提]
$ mkdir -p docker/app
$ mkdir -p docker/app/php-fpm.d
$ mkdir -p docker/nginx/conf

環境設定ファイルの作成 (.env)

何もせずにコンテナを作成すると意図せぬ名前になるので、作成されるコンテナ名を指定しておく。今回は「laravel9-app」の名前で作成されるようにする例。

$ vim docker/.env
COMPOSE_PROJECT_NAME=laravel9-app

php.iniを作成

まずはphp.iniの作成。

$ vim docker/app/php.ini
zend.exception_ignore_args = off
expose_php = on
max_execution_time = 30
max_input_vars = 1000
upload_max_filesize = 64M
post_max_size = 128M
memory_limit = 256M
error_reporting = E_ALL
display_errors = on
display_startup_errors = on
log_errors = on
error_log = /dev/stderr
default_charset = UTF-8

[Date]
date.timezone = ${TZ}

[mysqlnd]
mysqlnd.collect_memory_statistics = on

[Assertion]
zend.assertions = 1

[mbstring]
mbstring.language = Japanese

php-fpmの設定ファイル作成 (zz-www.conf)

次にphp-fpm.dのファイルを作成する。名前は「zz-」で始めることを強く推奨。

$ vim docker/app/php-fpm.d/zz-www.conf
[www]
user = www-data
group = www-data
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0666

アプリケーション側Dockerfileの作成

アプリケーション側(PHPが動く側)のDockerfileを作成する。phpのバージョンは「8.1.8」。

$ vim docker/app/Dockerfile
FROM php:8.1.8-fpm-buster
SHELL ["/bin/bash", "-oeux", "pipefail", "-c"]

# timezone environment
ENV TZ=Asia/Tokyo \
  # locale
  LANG=en_US.UTF-8 \
  LANGUAGE=en_US:en \
  LC_ALL=en_US.UTF-8 \
  # composer environment
  COMPOSER_ALLOW_SUPERUSER=1 \
  COMPOSER_HOME=/composer \
  COMPOSER_NO_INTERACTION=1

COPY --from=composer:2.1 /usr/bin/composer /usr/bin/composer

RUN apt-get update && \
  apt-get -y install git wget vim  zip curl unzip libicu-dev libonig-dev libzip-dev locales libpq-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev libjpeg-dev libcurl4-gnutls-dev gnupg2 procps default-jre grep fonts-takao fonts-ipafont fonts-ipaexfont && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* && \
  locale-gen en_US.UTF-8 && \
  localedef -f UTF-8 -i en_US en_US.UTF-8 && \
  mkdir /var/run/php-fpm && \
  mkdir /var/log/php && \
  docker-php-ext-install intl pdo_mysql zip bcmath mbstring && \
  docker-php-ext-configure gd --with-freetype --with-jpeg && \
  docker-php-ext-install -j$(nproc) gd && \
  docker-php-ext-install curl && \
  composer config -g process-timeout 3600 && \
  composer config -g repos.packagist composer https://repo.packagist.org

COPY ./php-fpm.d/zz-www.conf /usr/local/etc/php-fpm.d/zz-www.conf
COPY ./php.ini /usr/local/etc/php/php.ini

WORKDIR /var/www

nginxの設定ファイルを作成

nginxの設定ファイルを作成する。ここではホスト名を「laravel9-app.localhost」としている。

$ vim docker/nginx/conf/default.conf
access_log /dev/stdout main;
error_log /dev/stderr warn;

server {
    listen 80;
    root /var/www/public;
    server_name laravel9-app.localhost;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;
    client_max_body_size 20m;
    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

nginxのDockerfileを作成

webサーバ側 (nginx側)のDockerfileを作成する。特に注意点はなし。

$ vim docker/nginx/Dockerfile
FROM node:latest as node
FROM nginx:alpine
SHELL ["/bin/ash", "-oeux", "pipefail", "-c"]

ENV TZ=JST

RUN apk update && \
  apk add --update --no-cache --virtual=.build-dependencies g++

# node command
COPY --from=node /usr/local/bin /usr/local/bin
# npm command
COPY --from=node /usr/local/lib /usr/local/lib
# yarn command
COPY --from=node /opt /opt
# nginx config file
COPY ./conf/default.conf /etc/nginx/conf.d/default.conf

WORKDIR /var/www

docker-compose.ymlの作成

最後にdocker-compose.ymlを作成する。

$ vim docker/docker-compose.yml
version: '3'

volumes:
  laravel9-app-php-fpm-socket:
services:
  nginx:
    container_name: laravel9-app-nginx
    build:
      context: ./nginx
    volumes:
      - laravel9-app-php-fpm-socket:/var/run/php-fpm
      - ../../laravel9-app:/var/www
    depends_on:
      - app
    networks:
      - laravel9-app-network
      - local-network
    environment:
      VIRTUAL_HOST: "laravel9-app.localhost"

  app:
    container_name: laravel9-app
    build:
      context: ./app
    volumes:
      - laravel9-app-php-fpm-socket:/var/run/php-fpm
      - ../../laravel9-app:/var/www
    networks:
      - laravel9-app-network
      - local-network

networks:
  laravel9-app-network:
    name: laravel9-app-network
  local-network:
    external: true
    name: local-network

ビルド・起動

ビルドして、起動してみる。

$ cd docker
$ docker-compose build
$ docker-compose up -d

コンテナ一覧で、今回のものが起動していることが確認できる。

$ docker ps
CONTAINER ID   IMAGE                      COMMAND                  CREATED              STATUS              PORTS
                       NAMES
7762f1c5c48e   docker_nginx               "/docker-entrypoint.…"   About a minute ago   Up About a minute   80/tcp
                       laravel9-app-nginx
4c851be97818   docker_app                 "docker-php-entrypoi…"   About a minute ago   Up About a minute   9000/tcp
                       laravel9-app

これで動くかと思ったのだが、storage関連にパーミッションが足りなくてlaravelが動かなかったので、パーミッションを変更する。まずはdockerコンテナ内へ入る。

$ docker exec -it 4c85 /bin/bash

storageディレクトリに入り、権限を「777」にする。

root@4c851be97818:/var/www# cd storage/
root@4c851be97818:/var/www/storage# chmod 777 -R *

「laravel9-app.localhost」で無事起動できました。

余談

laravel9を初めから入れるだけなら結構すんなりだった。laravel8からlaravel9へのアップグレードはまだやってないので、どこかでやってみようと思う。

コメント

タイトルとURLをコピーしました