転職したらスマレジだった件

スマレジのエンジニアやまてのテックブログです。マジレス大歓迎です。

諸事情で Zend Framework を理解する 2022 - ①Docker での開発環境構築

Zend Framework のバージョンは 3 系です

こんにちは!

スマレジの テックファーム(SES 部門)のWebエンジニア やまて(@r_yamate) と申します。

はじめに

本記事から何回かに渡って、 Zend Framework を使って、CRUD処理機能のあるWebサービスを作成する開発手順 をアウトプットします。

目次

公式ドキュメントのチュートリアルに沿って、少しアレンジしながら進めたものです。

docs.zendframework.com

Zend Framework とは、Webアプリケーションに必要となる機能を揃えた PHPフレームワークのひとつです。

PHPフレームワークといえば、現在は Laravel が人気ですが、 Zend Framework は一昔前のフレームワークということになるかと思います。

また、現状では Zend Framework 自体はアーカイブになっていて更新されておらず、 Laminas というフレームワークにマルっと変わっているようです。

「今時なぜ Zend Framework の学習を始めて、記事を書こうとしているのか…?」

と思われるかもしれませんが、事情としては、 派遣先の業務で Zend Framework を用いて開発されたWebサービスの改修に携わることになった ので、 Zend Framework の既存のコードを読み解けるよう理解を進めるため に、公式ドキュメントのチュートリアルを実施してアウトプットの機会を作ろう、という主旨です。

※ 注:スマレジの自社プロダクトでは Zend Framework は使われていません

スマレジの使用技術はこちらに記載があります →

corp.smaregi.jp

本記事でアウトプットすること

本記事を通じて、以下についてハンズオンで学習した内容をアウトプットしていきます。

作成するアプリケーションのイメージ

本記事で作成する一覧画面です。

画面内の登録、編集、削除ボタンを機能するようにします。

この記事の対象者

Zend Frameworkチュートリアルを実施する方はなかなかいないかとは思いますが…笑)

記事で触れないこと

本記事は Zend Framework での開発方法をざっくりと把握することを一番の目的としています。そのため、一行一行のコードの理解や、深掘りできていない部分が多くあります。

そして残念ながら、記事の通り進めたら最初から最後までハンズオンで進められる、という素敵な記事ではありません。

本記事の使用しているOS・対応バージョン

本連載の目次

本記事では以下の順序で投稿します。

ryamate.hatenablog.com

ryamate.hatenablog.com

ryamate.hatenablog.com

ryamate.hatenablog.com

ryamate.hatenablog.com

ryamate.hatenablog.com


Docker での開発環境構築

それでは早速、Docker での開発環境の構築についてです。

1. Docker コンテナの概要

Docker コンテナは、下記の3つのコンテナを起動します。

Dockerコンテナ Dockerイメージ 説明
web nginx:1.18.0-alpine
app smaregi/php:7.4.19-fpm-alpine3.13 パッケージ依存管理ツール:Composer 1系 / フレームワークZend Framework 3系
db mysql/mysql-server:5.6

Zend Framework のアウトプットが目的であるため、ここでは、docker-compose.yml、Dockerfile、その他Docker関連のファイルを参考に載せるのみです。(Docker の便利さはすごいので学習も頑張っておりますが、解説できるほどではないのが正直なところです)

※2022/03/24修正:使用するDockerイメージを mysql:5.6mysql/mysql-server:5.6 に変更しました。(M1 Mac でも動くようにしたいため)

qiita.com

2. 主要なファイル

docker-compose.yml

version: "3.6"
services:
  web:
    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile
    depends_on:
      - app
    ports:
      - ${WEB_PORT:-80}:80
    volumes:
      - ./doc_root/public:/var/www/sample-app/public

  app:
    build:
      context: .
      dockerfile: ./docker/php/Dockerfile
    environment:
      MYSQL_DATABASE: ${DB_NAME:-self_order}
      MYSQL_USER: ${DB_USER:-db_user}
      MYSQL_PASSWORD: ${DB_PASS:-secret}
    depends_on:
      - db
    links:
      - db:mysql
    volumes:
      - ./docker/php/php.ini:/usr/local/etc/php/php.ini
      - ./doc_root:/var/www/sample-app

  db:
    build:
      context: .
      dockerfile: ./docker/mysql/Dockerfile
    environment:
      MYSQL_DATABASE: ${DB_NAME:-self_order}
      MYSQL_USER: ${DB_USER:-db_user}
      MYSQL_PASSWORD: ${DB_PASS:-secret}
      MYSQL_ROOT_PASSWORD: ${DB_PASS:-secret}
    ports:
      - ${DB_PORT:-3306}:3306
    volumes:
      - db-data:/var/lib/mysql
volumes:
  db-data:
    driver: local

web コンテナ

docker/nginx/Dockerfile

FROM nginx:1.18.0-alpine

# timezone environment
ENV TZ=Asia/Tokyo

RUN apk --update --no-cache add git zip unzip

COPY ./docker/nginx/nginx.conf /etc/nginx/conf.d/default.conf

WORKDIR /var/www/sample-app/public

docker/nginx/nginx.conf

server {
    listen 80;
    server_name localhost
    index index.php index.html;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/sample-app/public;

    location / {
        root /var/www/sample-app/public;
        index index.php index.html;
        try_files $uri $uri/ /index.php?$args;
        autoindex on;
        autoindex_localtime on;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

※ nginx.conf に関連してエラーになった時のエラー解決記事

qiita.com

app コンテナ

docker/php/Dockerfile

FROM smaregi/php:7.4.19-fpm-alpine3.13 AS php-base

# timezone environment
ENV TZ=Asia/Tokyo \
    # composer environment
    COMPOSER_ALLOW_SUPERUSER=1

RUN set -xe \
    && apk add --no-cache git=2.30.2-r0 \
    && docker-php-ext-enable xdebug

# composer のインストール
# (バージョンを1系に指定する理由は、2系であると依存関係のエラーが出るため)
COPY --from=composer:1 /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/sample-app

※ Composer のバージョンを1系に指定する理由は、2系であるとパッケージの依存関係により、Zend Frameworkのインストールがうまく行かず、1系であれば問題ないためです。

※ git のバージョンでエラーが出てDockerコンテナが起動しない場合

qiita.com

docker/php/php.ini

[xdebug]
xdebug.remote_enable = On
xdebug.remote_autostart = On
xdebug.remote_host = host.docker.internal
xdebug.max_nesting_level = 512
xdebug.remote_port = 9000

db コンテナ

docker/mysql/Dockerfile

FROM mysql/mysql-server:5.6

# timezone environment
ENV TZ=Asia/Tokyo

COPY ./docker/mysql/my.cnf /etc/mysql/conf.d/my.cnf
COPY ./docker/mysql/initdb.d /docker-entrypoint-initdb.d

CMD [ "mysqld", "--character-set-server=utf8", "--collation-server=utf8_unicode_ci" ]

docker/mysql/my.cnf

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

[client]
default-character-set=utf8mb4

docker/mysql/initdb.d/01_products.sql

SET CHARACTER_SET_CLIENT = utf8;
SET CHARACTER_SET_CONNECTION = utf8;

CREATE TABLE products (
    id                    INTEGER AUTO_INCREMENT PRIMARY KEY,
    item_name             VARCHAR(256) NOT NULL,
    price                 INTEGER NOT NULL,
    image                 VARCHAR(256),
    delete_flag           BOOLEAN NOT NULL DEFAULT FALSE,
    created_at            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

INSERT INTO
    products (item_name, price, image)
VALUES
    ('日替わりランチA', 600, null),
    ('日替わりランチB', 800, null),
    ('日替わりランチC', 1000, null);

※ Dockerコンテナ起動した時にデータベースにテーブルが作成されるようにしています。

qiita.com

3. 本記事完了時点のソースコード

本記事完了時点のソースコードGitHub上に公開しています。

github.com

以下は変更差分です。

github.com

おわりに

今回の記事は以上です!

次回、 ② Zend Framework のインストール を投稿します。