【Kubernetes】Laravel環境の構築ー前編ー

Kubernetes

Laravel実行環境をKubernetesで実装します。
アプリケーションを詰め込みたいのでイメージを作成してKubernetesでデプロイします。
出来るだけKubernetesで管理したいのでNginxとphp-fpmをコンテナ1つで作成して
MariaDBをKubernetesでデプロイします。
コンフィグやマニュフェストが長くなるので前編・後編に分けます。
 ①Dockerイメージ作成 ←ここ
 ②Kubernetesでデプロイ

後編は下記にあります。

環境

アプリケーション

名称バージョン
Dockerv24.0.4
docker-composev1.27.4

イメージOS

名称バージョン
nginx(alpine)v1.25.1
php-fpm(alpine)v8.2

Dockerイメージ作成

ファイル作成

nginxのDockerfileを作成します。
Dockerfile-nginx



FROM nginx:1.25.1-alpine

RUN mkdir /var/run/php-fpm

COPY ./nginx-http.conf /etc/nginx/conf.d/default.conf

RUN apk update \
  && apk add vim

php-fpmのDockerfileを作成します。
Dockerfile-php

FROM php:8.2-fpm-alpine

#php-fpm実行ユーザを作成
RUN addgroup -S www \
  && adduser -S www -G www \
  && echo "www ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers \
  && echo 'www:www' | chpasswd

#コンフィグをコピー
COPY ./www.conf /usr/local/etc/php-fpm.d/zzz-www.conf
COPY ./php.ini /usr/local/etc/php/php.ini

#アプリケーションインストール
RUN apk update --no-cache \
  && apk upgrade --no-cache \
  && apk add --no-cache --virtual \
    libtool \
    libxml2-dev \
    bash \
    curl \
    curl-dev \
    freetype-dev \
    g++ \
    gcc \
    git \
    icu-dev \
    icu-libs \
    libc-dev \
    libjpeg-turbo-dev \
    libpng-dev \
    libzip-dev \
    make \
    mysql-client \
    nodejs \
    openssl \
    oniguruma-dev \
    yarn \
    zlib-dev \
  && docker-php-ext-install \
    bcmath \
    calendar \
    curl \
    exif \
    gd \
    intl \
    mbstring \
    pdo \
    pdo_mysql \
    pcntl \
    xml \
    zip

# タイムゾーンや言語設定
ENV TZ=Asia/Tokyo
ENV LANG=ja_JP.UTF-8
RUN apk add tzdata \
  && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# composerインストール
ENV COMPOSER_HOME /composer
ENV PATH ./vendor/bin:/composer/vendor/bin:$PATH
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN curl -s https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin/ --filename=composer \
  && chmod +x /usr/local/bin/composer \
  && composer global require "laravel/installer"

# 作業ディレクトリ変更
WORKDIR /var/www

#プロジェクト作成
RUN composer create-project laravel/laravel portal

#作業ディレクトリ変更
WORKDIR /var/www/portal

RUN chmod 777 ./storage
RUN chmod -R 777 bootstrap/cache

RUN apk add  --no-cache nodejs npm
RUN npm install

nginxのコンフィグを作成します。
nginx-conf.conf
※fastcgi_passにlocalhostを設定しており、docker-composeでは接続できないので注意

server {
    listen 80;
    server_name localhost;

    error_log  /var/log/nginx/error.log warn;

    root /var/www/portal/public;
    index index.php;

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

    gzip  on;

    charset utf-8;

    location / {
        index index.php index.html index.htm;
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~* .(jpg|jpeg|png|gif|ico|css|js)$ {
        expires max;
        add_header Cache-Control public;
        access_log off;
    }

    # php-fpmとの連携
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass localhost:9000;  #fastcgiに渡すパス
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        gzip_types text/css text/javascript
                   application/x-javascript application/javascript
                   application/json;
        gzip_min_length 1k;
        gzip_disable "msie6"; #IE6では圧縮できないので無効化設定
    }
}

php-fpmの設定ファイルを作成します。
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 = "Asia/Tokyo"

[mysqlnd]
mysqlnd.collect_memory_statistics = on

[Assertion]
zend.assertions = 1

[mbstring]
mbstring.language = Japanese
default_charset=EUC-JP

php-fpmのコンフィグファイルを作成します。
www.conf

[www]
user = www
group = www
listen = 9000
listen.owner = www
listen.group = www
listen.mode = 0666
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

docker-composeファイルを作成します。
docker-compose.yaml

version: '3.8'

services:
  nginx-dep:
    container_name: nginx-dep
    build:
      context: .
      dockerfile: Dockerfile-nginx
    image: [ユーザ名]/nginx-dep
    ports:
    - 8080:80
    networks:
    - laravel-network
    depends_on: #laravel-depを先に起動する
    - laravel-dep

  laravel-dep:
    container_name: laravel-dep
    build:
      context: .
      dockerfile: Dockerfile-php
    image: [ユーザ名]/laravel-dep
    networks:
    - laravel-network

networks:
  laravel-network:
    driver: bridge

Dockerビルド

docker-compose buildでイメージを作成します。

docker-compose build

dockerにログインし、DockerHubにプッシュします。

docker login
docker push [ユーザ名]/nginx-dep
docker push [ユーザ名]/laravel-dep

最後に

Kubernetesで実装するのに3か月程かかりました。(仕事やアニメ、ゲームなどを挟んでいたので実働はもっと少ないですが。)
docker-composeでの実装はすぐにできたのですが、Kubernetesのデプロイ用コンフィグ作成に時間がかかりました。
正直、軽いテスト環境を整えるだけだったらdocker-composeで実装したほうが楽です。
いちいちKubernetes環境で確認するのは大変だと思いますので、docker-composeで動作確認して
うまくいってからデプロイするのが良いと思います。
DB含めて確認する場合はdocker-composeで動かす場合はsqliteが簡単なのかな?
私はpdo-sqliteやsqliteを入れるのが面倒だったのでmariadbのコンテナを作って動作確認をしました。