20210124のlaravelに関する記事は8件です。

共同開発講座を受講中にコツコツ書いた「詰まったメモ」をジャンル別に全て公開します【環境構築編】

はじめに

タイトルの通り、共同開発講座を受講中に起きたトラブルや詰まりポイントをまとめたメモ(約50記事)をジャンル別に全て公開します。
ジャンルは以下の通りなので、気になるものがあればぜひご覧ください。

【ジャンル一覧】

GitHub関連
Laravel関連
データベース(migration/seeding)関連
環境関連
総まとめ集

下記の点を、ご了承ください。
・ジャンルで統一しているため、内容に関しては統一性はありません。
・メモの難易度もバラバラです。
・初学者向けの内容となっております。
・自分用のメモを転用しておりますので、表現が稚拙な部分があるかと思います。
・あくまで僕のメモです!!

環境

・vagrant-docker-laravel
・docker-compose version 1.25.0
・PHP 7.2.34
・Laravel Framework 5.8.38
・mysql Ver 14.14 Distrib 5.7.32, for Linux (x86_64) using EditLine wrapper
・phpmyadminを使用

・【docker】down と stop の使い分け

docker-compose build 
を行って
・ファイルの修正を反映させたい時

docker-compose down  //コンテナの削除?シャットダウン

を行って

docker-compose up -d

で、新たにコンテナを立ち上げる

・そのままのコンテナで、再起動のみ行いたい場合は

docker-compose stop

でコンテナを止めてから

docker-compose start

で、既存のコンテナを開始させる

・Docker 起動時にapacheがすぐに落ちる

不具合詳細

Docker 起動時にapacheがすぐに落ちる不具合
その他ブラウザでLaravelにアクセスできない等

原因は、DockerとVagrantの適切なシャットダウンをしていなかったから(?)

【メンターさんの回答】
以前の操作で適切なシャットダウンが出来ていないと、ガベージファイルというゴミファイルが悪さをしているのかも知れません。

docker ps -a
で現在できているコンテナをみて、

docker rm コンテナID
でガベージファイルを全削除してから、

再度
docker-compose build
docker-compose up -d
等を試していただけますか?

参考リンク
https://qiita.com/tifa2chan/items/e9aa408244687a63a0ae

対処方法

①適切なシャットダウン
Docker 停止

docker-compose stop

Vagrant 停止

vagrant suspend

②ガベージファイルの削除方法
既存のコンテナを確認する

docker ps -a

不要と思われるコンテナを削除する

docker rm コンテナ名

シャットダウンからの復帰

suspendからの復帰

vagrant resume

dockerの開始

docker-compose start

・Docker立ち上げまでの流れ(インストール後)

※こちら私が使用していたディレクトリ名なのでわかりにくいかもです

ターミナルにて
・cdコマンドでプロジェクトディレクトリに移動
・cdコマンドでdocker-on-vagrantに移動
・vagrantにログイン

kei@Mac-Pro docker-on-vagrant % vagrant ssh
Last login: Sat Nov 14 16:32:03 2020 from 10.0.2.2

ls   cdコマンドでdocker-laravelまで移動

[vagrant@local-docker ~]$ ls
docks
[vagrant@local-docker ~]$ cd docks/
[vagrant@local-docker docks]$ ls
docker-laravel
[vagrant@local-docker docks]$ cd docker-laravel/
[vagrant@local-docker docker-laravel]$ ls
README.md  apache-php  docker-compose.yml  index.php  lara-d

docker-laravel上で「docker-compose start」(既存のコンテナをスタートさせる)

[vagrant@local-docker docker-laravel]$ docker-compose start
Starting db         ... done
Starting web        ... done
Starting phpmyadmin ... done

//3つ全て立ち上がったらOK!

lara-dに移動

[vagrant@local-docker docker-laravel]$ ls
README.md  apache-php  docker-compose.yml  index.php  lara-d
[vagrant@local-docker docker-laravel]$ cd lara-d

--ここから開発スタートできる--

・Laravelとmysqlが接続できないエラー(環境構築)

エラー詳細

→php artisan migration ができない

root@86b16371b02f html]# php artisan migrate

エラー文

   Illuminate\Database\QueryException  : SQLSTATE[HY000] [1045] Access denied for user 'root'@'172.23.0.3' (using password: NO) (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE')

原因

①Laravelの.envファイルのmysqlパスワード と docker-compose.yml内に記載されているmysqlパスワードが不一致であった。
ちなみに、docker-compose.yml内のパスワードに全て合わせなければならない!!

②そもそも、migrationをする前にテーブルが入るための箱(データベース)をphpmyadminに作っておかなければならなかった。これは.envファイルのDB_DATABASE=●●●で指定されている名前のdbを作っておくこと

③migrationファイル内の構文が間違っていた
今回はtimestamps()とtimestamp()で引数の取り方が変わるため、構文エラーとなっていた。

Mysqlとの接続方法

以前まとめた記事があります↓↓
https://qiita.com/kei_Q/items/f3422b34afbe094119cb

・vagrant docker 新しいコンテナを立ち上げる(新規プロジェクトを立ち上げる)方法

コンテナを新しく立ち上げたい!!!
という時の方法

laravelの環境を動かすことができるdockerファイルをクローン

この時に名前を変更しておくと良い

[vagrant@local-docker docks]$ git clone https://github.com/****/docker-laravel.git **lara-review** ←ここで名前変更

vagrantにログインした状態でdocksディレクトリの中にクローンする

[vagrant@local-docker docks]$ git clone https://github.com/****/docker-laravel.git lara-review
Cloning into 'lara-review'...
remote: Enumerating objects: 23, done.
remote: Counting objects: 100% (23/23), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 23 (delta 5), reused 22 (delta 4), pack-reused 0
Unpacking objects: 100% (23/23), done.

これでファイルをクローンしてきてlara-reviewと言う名前でvagrantの中においた。

イメージの作成

docker-compose  build

を行ってイメージを作成した

いざコンテナの作成

docker-compose  up -d

でコンテナを新しく作成しようとしたらエラーが出た
それが以下のエラー

[vagrant@local-docker lara-review]$ docker-compose up -d
Creating network "lara-review_default" with the default driver
Creating mysql5.7 ... error
ERROR: for mysql5.7  Cannot create container for service db: Conflict. The container name "/mysql5.7" is already in use by container "76d4ee80c5a2d3f73636dcd29e6ac736470617f02ee7e36148599f15d8fea51a". You have to remove (or rename) that container to be able to reuse that name.

訳)
コンテナを作成しようとしたけど、コンテナを作る時に使用するファイルに記載してある名前はすでに他のコンテナで使われているから作れませんよ?
って怒られてる。。

つまり、今取り組んでるプロジェクトであるlara-dというlaravelプロジェクトのために作ったコンテナで、名前使っちゃってるから、同じ名前で二つは作成できないよと言う意味。

解決策

解決策としては以下の3つが考えられる?

①既存のコンテナの削除
②既存のコンテナの名前変更
③ymlファイルの名前を変更してbuildした後にコンテナ作成

現行のプロジェクトであるlara-dを消すのは不可能だから答えは③になるので
lara-reviewでクローンしてきたものの中にあるdocker-compose.ymlファイルに書いてある3つの名前を全て変更する
①Apache
②phpmyadmin
③web bash
の3つのこと。

docker-compose.ymlファイル

[vagrant@local-docker lara-review]$ cat docker-compose.yml 
version: "3"
services:
  web:
    build:
      context: ./apache-php
    ports: 
      - 80:80
    privileged: true
    links:
      - db
    volumes:
      - "./:/var/www/html"
      - "./apache-php/apache.conf:/etc/httpd/conf/httpd.conf"
    container_name: "apache-php"   //←この名前を変更
  db:
    image: mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=root
    container_name: "mysql5.7"  //←この名前を変更
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    links:
      - db
    ports:
      - 8080:80
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=db
      - PMA_USER=root
      - PMA_PASSWORD=root
    container_name: "phpmyamin-la"   //←この名前を変更
[vagrant@local-docker lara-review]$ 

ymlファイルの編集

sudo vi docker-compose.yml

で編集

3つの名前を適当に変更した後、

docker-compose build
docker-compose up -d

を行うとコンテナが作成できた!!(この時既存のコンテナはストップしておかないといけない)

--------ここまでがコンテナの立ち上げ-----------

---------以下、Laravelの導入-----------

コンテナを立ち上げ、web  bash に入る

[vagrant@local-docker lara-review]$ docker-compose exec web bash

laravel本体をインストールする

[root@4b2a1b935301 html]# composer create-project --prefer-dist laravel/laravel laravel-review "5.8.*"

ちなみに最後の5.8の後の「*」は「5.8系のなかで最新のものをインストールしてね」という意味

laravelインストール画面

Creating a "laravel/laravel" project at "./laravel-review"
Installing laravel/laravel (v5.8.35)
  - Downloading laravel/laravel (v5.8.35)
  - Installing laravel/laravel (v5.8.35): Extracting archive
Created project in /var/www/html/laravel-review
> @php -r "file_exists('.env') || copy('.env.example', '.env');"
Loading composer repositories with package information
Updating dependencies
Lock file operations: 86 installs, 0 updates, 0 removals
  - Locking beyondcode/laravel-dump-server (1.3.0)
  - Locking dnoegel/php-xdg-base-dir (v0.1.1)
  - Locking doctrine/inflector (1.4.3)
  - Locking doctrine/instantiator (1.4.0)
  - Locking doctrine/lexer (1.2.1)
・・・・・
・・・・
・・続く

ymlファイルを編集する

[vagrant@local-docker lara-review]$ cat docker-compose.yml 
version: "3"
services:
  web:
    build:
      context: ./apache-php
    ports: 
      - 80:80
    privileged: true
    links:
      - db
    volumes:
      - "./laravel-review:/var/www/html"  //変更箇所
      - "./apache-php/apache.conf:/etc/httpd/conf/httpd.conf" //変更箇所
    container_name: "apache-php-2"
  db:
    image: mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=root
    container_name: "mysql5.7-2"
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    links:
      - db
    ports:
      - 8080:80
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=db
      - PMA_USER=root
      - PMA_PASSWORD=root
    container_name: "phpmyamin-la-2"

apache  conf をbuildする

[vagrant@local-docker apache-php]$ docker-compose build

ちなみに

コンテナを起動させておけるのは多分一つだけなので、、
lara-reviewのコンテナを立ち上げる際はdocker-laravelのコンテナは停止しておく必要がある。

停止とスタートのコマンドは以下の通り

docker-compose stop     コンテナを停止 
(docker-compose downはシャットダウンなので注意)
docker-compose start     コンテナを再開させる

docker-laravel(既存プロジェクト) もしくは lara-review(新規プロジェクト) の停止もしくは開始したい方のディレクトリに移動してから上記コマンドを叩いて、使わないプロジェクトを停止させ、これから使用する方を立ち上げる。

こんな感じに↓↓↓

[vagrant@local-docker lara-review]$ docker-compose stop
Stopping phpmyamin-la-2 ... done
Stopping apache-php-2   ... done
Stopping mysql5.7-2     ... done
[vagrant@local-docker lara-review]$ 
[vagrant@local-docker lara-review]$ 
[vagrant@local-docker lara-review]$ cd ..
[vagrant@local-docker docks]$ cd docker-laravel/
[vagrant@local-docker docker-laravel]$ docker-compose start
Starting db         ... done
Starting web        ... done
Starting phpmyadmin ... done

・vagrantの停止と再起動の流れ(パソコンの再起動したい時に超有用です)

パソコンを再起動するときはvagrantをシャットダウンさせるか、スリープモードにしておくべきだそう。

vagrantを一時停止する(スリープさせる)

vagrant suspend
kei@Mac-Pro docker-on-vagrant % vagrant suspend
==> vagrant: A new version of Vagrant is available: 2.2.14 (installed version: 2.2.13)!
==> vagrant: To upgrade visit: https://www.vagrantup.com/downloads.html
==> default: Saving VM state and suspending execution...

vagrantが止まったかどうかの確認(状態確認)

vagrant status

ちなみにdefaultの状態は

Power off
Running
Saved

の三つがある。

vagrant status実行

kei@Mac-Pro docker-on-vagrant % vagrant status
Current machine states:

default                   saved (virtualbox)     //savedならOK!

To resume this VM, simply run `vagrant up`.
oourakeisuke@Mac-Pro docker-on-vagrant % 

――ここでパソコンを再起動する――

――パソコンの再起動が完了したら――

状態確認

vagrant status
Last login: Sun Nov 22 15:25:57 on console
kei@Mac-Pro docker-on-vagrant % vagrant status
Current machine states:

default                   saved (virtualbox)     //savedのままならOK!

To resume this VM, simply run `vagrant up`.

vagrantを再起動する(suspendからの復帰)

vagrant resume
kei@Mac-Pro docker-on-vagrant % vagrant resume
==> default: Resuming suspended VM...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2200
    default: SSH username: vagrant
    default: SSH auth method: private key
==> default: Machine booted and ready!
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: flag to force provisioning. Provisioners marked to run always will still run.

vagrantにログインする

kei@Mac-Pro docker-on-vagrant % vagrant ssh
Last login: Thu Nov 19 11:14:13 2020 from 10.0.2.2
[vagrant@local-docker ~]$ 

ログイン成功!!(再起動成功!!)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【最新版】はじめてのLaravel!Laradockを用いたLaravel開発環境構築

  • 最終編集日(2021年1月)

環境構築だけ読みたい方は、Laravelの環境構築まで読み飛ばしてください。

概要

本記事は、PHPのフレームワークであるLaravelの環境構築を開設した記事です。

構築する Laravel 及び PHP のバージョンは以下になります。

  • Laravel 8.x
  • PHP 7.4

初めてLaravelを使う方、一度環境構築で挫折した方でもつまずかないことを心掛けて執筆しました。

何かわからないことことがありましたら、コメントでお知らせください!

環境

Docker for Desktopのインストールが必要になります

  • Mac
  • Windows
    • Windows 10 homeの方は、Windowsをバージョン2004,ビルド19041以上にアップデートした上でWSL 2のインストールが必要になります
    • Docker Toolboxでも環境構築をすることはできますが、一部コマンドが異なる場合があります
  • 本記事ではMySQLを使います。PostgreSQLでの環境構築も可能ですが、Laradockの起動で一部コマンドが異なります。

Laradock で使用できる PHP バージョン早見表

Laradockで使用できるPHP、Laravelのバージョンは以下の通りです。
※2021年1月現在公式サポートされているPHPのバージョンのみ記載しています。

PHPバージョン Laradock対応
7.3
7.4
8.0 ×

前提条件

  • gitをインストールしていること
  • Docker for Desktopをインストールしていること

Terminalで以下のコマンドを実行して正しく出力されるかを確認してください。

$ git --version
git version 2.9.0
$ docker --version
Docker version 19.03.1, build 74b1e89e8a 
$ docker-compose --version
docker-compose version 1.24.1, build 4667896b

※Dockerのバージョンは17.12以降である必要があります。
(参考) Getting Started

Laravelの環境構築

それでは実際にLaravelの環境構築を行っていきましょう。

プロジェクトディレクトリの作成

mkdirコマンドでLaradockをインストールするディレクトリを作成します。ここでは、laravel-workspaceとしています。

mkdir laravel-workspace

cdコマンドで作成したディレクトリに移動します。

cd laravel-workspace

Laradockのインストール

Laradockをインストールしていきます。

以下のコマンドを実行します。

$ git clone https://github.com/Laradock/laradock.git

インストールが終わると以下のように表示されます。

$ git clone https://github.com/Laradock/laradock.git
Cloning into 'laradock'...
remote: Enumerating objects: 11524, done.
remote: Total 11524 (delta 0), reused 0 (Rdelta 0), pack-reused 11524eceiving objects: 100% (11524/11524), 11.36 MiB | 3Receiving objects: 100% (11524/11524), 11.42 MiB | 346.00
 KiB/s, done.
Resolving deltas: 100% (6203/6203), done.
Checking connectivity... done.

laradockディレクトリが作成されていることがわかります。

$ ls
laradock/

Laradockのインストールは以上です

.env ファイルの編集

.envファイルを編集することで、プロジェクトの環境変数を定義していきます。使用するデータベースやPHPのバージョンなどもここで指定します。

cdコマンドを使って先ほど作成されたlaradockディレクトリに移動しましょう。

$ cd laradock

laradockディレクトリの中には、env-exampleという.envのサンプルがあります。これをコピーして使用します。以下のコマンドでコピーしてください。

cp env-example .env

.envを編集していきます。お好きなエディタで.envファイルを開いてください。

1.プロジェクトの相対パスの指定

プロジェクトを作成するにあたり、パスを指定します。
ここでは、laravel-projectというプロジェクトをlaradock同じ階層に作成します。

laravel-workspace
├── laradock
└── laravel-project

8行目を以下のように編集してください。

.env
- APP_CODE_PATH_HOST=../
+ APP_CODE_PATH_HOST=../laravel-project

2.データベースのディレクトリ変更

デフォルトでは、データベースなどがホームディレクトリに保存されるようになっています。
プロジェクトディレクトリ配下に作成されるように設定を変更しましょう。

17行目を以下のように編集してください。

.env
- DATA_PATH_HOST=~/.laradock/data
+ DATA_PATH_HOST=.laradock/data

3. コンテナ名の変更

ここでは、Dockerを起動するときのコンテナ名を指定していきます。「コンテナ?」という方はコピペしていただいて構いません。
※Dockerに関しては「いまさらだけどDockerに入門したので分かりやすくまとめてみた」の記事が非常にわかりやすいです。

36行目を以下のように編集してください。

.env
- COMPOSE_PROJECT_NAME=laradock_
+ COMPOSE_PROJECT_NAME=laravel-project

4. PHPのバージョン設定

PHPのバージョンを設定します。

42行目を使用したいPHPのバージョンに変更します。
ここでは、PHP 7.4を指定します。

.env
- PHP_VERSION=7.3
+ PHP_VERSION=7.4

2021年1月現在のLaradockがサポートしているPHPのバージョンに関してはこちらをご覧ください。

Laradockの起動

それではLaradockを起動していきます。

laradockディレクトリで以下のコマンドを実行してコンテナを起動します。

postgresを使用している場合は、mysqlの部分をpostgresに置き換えてください。

$ docker-compose up -d php-fpm nginx mysql workspace

以下のように表示されればOKです。

$ docker-compose up -d nginx mysql workspace
.
.
.
Creating laravel-project_docker-in-docker_1 ... done
Creating laravel-project_mysql_1            ... done
Creating laravel-project_workspace_1        ... done
Creating laravel-project_php-fpm_1          ... done
Creating laravel-project_nginx_1            ... done

Laravelアプリケーションの作成

それではLaravelのアプリケーションを作成していきます。以下のコマンドを実行してください。

$ docker-compose exec workspace bash

以下のような表示になれば正常にbashが起動できています。

$ docker-compose exec workspace bash
root@6095e16a845d:/var/www#

コマンドの最後には、Laravelのバージョンを指定しています。2021年現在、最新版はLaravel8.xです。ここでは8.*を指定していますが、コマンドの最後の数字を変えることで、別のバージョンのLaravelでアプリケーションを作成をすることができます。

# composer create-project --prefer-dist laravel/laravel="8.*" .

※アプリケーションの作成には少し時間がかかります。

Application key set successfully.と表示されればアプリケーションの作成は完了です。

以下のようにプロジェクトの相対パスの指定で指定した名前と同じフォルダが作成されています。

laravel-workspace
├── laradock
└── laravel-project

アプリケーションの確認

http://localhost にアクセスしてLaravelプロジェクトが作成されているか確認してみましょう。
image

上記のように表示されていれば正常にアプリケーションが作成されています。

コンテナの停止

コンテナを停止するときは以下のコマンドで停止することができます。

$ docker-compose stop

参考

※本記事はTechpitの教材を一部修正したものです。

最後まで読んでいただきありがとうございました。今後も、PHP・Laravelに関する記事を投稿していきますので、もしよろしければ、Techpitをフォローしてお待ちください!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker上のLaravelにJetstreamをインストールする。

https://qiita.com/ucan-lab/items/56c9dc3cf2e6762672f4
https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4
上記の記事を参考に構築したLaravel8に、Jetstreamをインストールします。

ComposerでJetstreamをインストールする

まず、Laravelをインストールしたコンテナに入ります。

$ docker-compose exec [コンテナ名] [コマンド名]

次にcomposerコマンドを実行します。

$ composer require laravel/jetstream

jetstream:installを実行

フロントエンドスタックとして、LivewireかInertiaを指定します。
Livewireはテンプレート言語にLaravelのBladeを利用します。
一方、InertiaはVue.jsを利用します。
どちらの場合も、--teamsをつけることでチームサポートを有効にできます。

$ php artisan jetstream:install livewire
$ php artisan jetstream:install livewire --teams
$ php artisan jetstream:install inertia
$ php artisan jetstream:install inertia --teams

npmの依存パッケージをインストール・構築

npmがインストールされているコンテナで実行します。

$ npm install && npm run dev

データベースをマイグレートする

こちらは再びLaravelのコンテナで実行します。

$ php artisan migrate

確認

Laravelのホーム画面を確認すると、右上にログイン画面、ユーザー登録画面へのリンクが表示されており、それぞれの画面へ遷移できます。

スクリーンショット 2021-01-24 17.17.48.png
スクリーンショット 2021-01-24 17.21.37.png
スクリーンショット 2021-01-24 17.21.53.png

composer require aravel/jetstream でメモリエラーが出た場合

php.iniファイルのmemory_limitを一時的に無制限にすることで対応可能です。
インストール後、memory_limitの値を元に戻しておいてください。

php.ini
memory_limit = 256M

php.ini
memory_limit = -1
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker + Laravel + Vue の環境構築 - Docker編

はじめに

  • DockerWindows10 Homeにも対応したということでDockerでの環境構築を始めてみました。
  • DockerVueは初めて触ります。Laravelのみ少し経験あり。
  • Xserverにデプロイするつもりで構築。
    • ドキュメントルートはプロジェクト直下の public_html
    • 本来はWebサーバーはApacheだけど、慣れたいのでnginx使ってます。

環境

  • Windows 10 Home(20H2)

Dockerのインストールについて

  • インストール
  • 発生したトラブル
    • Win10にすんなりインストールして使えるとはいかず、バージョンアップをしました。
    • Windowsアップデートがまだの場合、下記公式からダウンロード可能です。
  • 生成されたバージョン
    • Docker: 20.10.2
    • Docker Compose: 1.27.4

image.png

Docker

  • Docker単体でも使えるがDocker Composeを使うのが便利なようです。
  • docker-composeはymlファイルに複数のコンテナの定義を記述し、立ち上げができます。
  • WEBサーバーやDB等の1つのファイルで管理でき、コンテナ間の連携もできる大変便利なツールです。
  • 今回使うDocker Desktopのインストール内容にDocker Composeも含まれています。

Docker Composeの準備

  • 下記のymlを実行し、以下の環境が作られました。
    • php : 7.4.14
    • nginx : 1.19.6
    • MySql : 5.7.32
    • PhpMyAdmin : 5.0.4
    • npm : 6.12.1
    • node : 12.13.1
docker-compose.yml
version: '3'

services:
  php:
    build: ./docker/php
    volumes:
      - ./src:/var/www

  nginx:
    image: nginx
    ports:
      - 80:80
    volumes:
      - ./src:/var/www
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
    tty: true

    command: [nginx-debug, '-g', 'daemon off;']

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: sample_project
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./docker/db/data:/var/lib/mysql
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./docker/db/sql:/docker-entrypoint-initdb.d
    ports:
      - 3306:3306

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=db
      - PMA_USER=docker
      - PMA_PASSWORD=docker
    links:
      - db
    ports:
      - 4000:80
    volumes:
      - ./docker/phpmyadmin/sessions:/sessions

  node:
    image: node:12.13-alpine
    tty: true
    volumes:
      - ./src:/var/www
    working_dir: /var/www

php -> Dockefileの準備

Dockerfileに各コンテナの詳細情報を定義します。
これはphp用のDockerfileで、今回個別に用意するのはこれだけです。

FROM php:7.4-fpm
COPY php.ini /usr/local/etc/php/

# 1. 必要なツールをインストール
RUN apt-get update \
  && apt-get install -y zlib1g-dev mariadb-client vim libzip-dev \
  && docker-php-ext-install zip pdo_mysql \
  && git vim curl cron unzip

# 2. Composerインストール
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composerd

ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin

WORKDIR /var/www

# 3. laravelインストール
RUN composer global require "laravel/installer"

php -> php.iniの準備

php.ini
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

nginx -> default.conf

server {
  listen 80;
    index index.php index.html;
    root /var/www/public_html;

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

  location ~ \.php$ {

    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass php:9000;
    fastcgi_index index.php;
    include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}

ここまでのディレクトリ構成

適当な場所にプロジェクトフォルダを作り、下記のように配置してください。
[]で囲ってる箇所はディレクトリです。

[myLaravel]
  ├── [docker]
  │    ├── [nginx]
  │    │   └── default.conf
  │    └── [php]
  │        ├── Dockerfile
  │        └── php.ini
  └── [src]

Docker Composeの実行

  • コマンドプロンプト、またはGit Bash等を使ってプロジェクトフォルダへ移動してください。
  • 下記コマンドを実行するとDocker Composeの内容からコンテナが作成され、下記のように動作を確認できます。
~/myLaravel$ docker-compose up -d

Starting mylaravel_db_1         ... done
Starting mylaravel_node_1       ... done
Starting mylaravel_php_1        ... done
Starting mylaravel_phpmyadmin_1 ... done
Starting mylaravel_nginx_1      ... done

Docker Desktopを確認すると下記のように指定したプロジェクトと、コンテナが作成されていることが確認できます。
image.png

これで環境が整いました。

Docker Desktopからの操作

各コンテナにカーソルを合わせると、いくつかアイコンが表示されます。

image.png

左から

  • ブラウザを開く
    • WebサーバーやPhpMyAdmin等ブラウザ上で確認できるものにだけ、アイコンが表示されます。
  • コンソール画面を開く
    • コンソール上での操作を行います。
    • 他の記事だとコマンドdocker-compose exec php bashを使ってるものが多いです。
    • なぜか僕はこのコマンドでエラーになるので、デスクトップアプリ経由で使ってます。
      • docker-compose.ymlの各コンテナの設定にtty:trueがあればできるはずなんですが解決できなかったので、設定から外しています。
    • PHPコマンドやnpmを使う時はそれぞれのコンソール上からしか実行できないので、やりたいことに合わせたコンソールを開く必要があります。ちょっとめんどくさい。
  • コンテナの停止
  • コンテナの再起動
  • コンテナの削除

最終的にできた構成

db, phpmyadminディレクトリが作られました。中身は特に気にしなくていいので省略してます。

[myLaravel]
  ├── [docker]
  │    ├── [db]
  │    │   └── ...
  │    ├── [nginx]
  │    │   └── default.conf
  │    ├── [php]
  │    │   ├── Dockerfile
  │    │   └── php.ini
  │    └── [phpmyadmin]
  │        └── [sessions]
  └── [src]

次回

次回はLaravelとVueの環境構築を進めます。

参考にさせていただいた記事

https://qiita.com/phper_sugiyama/items/654f7a9171ae5ccf3e83
https://qiita.com/rockinruuula1227/items/83f3f1406f339083ef3f

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】テーブル名が長い時に、Laravel7から導入された外部キー制約をつけるマイグレーションエイリアスを使う方法

久しぶりのQiitaへの投稿です。

未経験からエンジニアに転職をして、2年目に突入したバックエンドエンジニアです。
DBに外部キー制約を追加をしようと思い、Laravel7から使えるエイリアスでmigrationファイルを作成していました。
ただ、テーブル名が長い時にハマってしまい、できる人には当たり前すぎる内容かもしれませんが、振り返りの意味も込めて投稿します。

開発環境

  • 言語:PHP7.4.8
  • フレームワーク:Laravel7.28.3
  • DB:MySQL8.0.22

テーブル名が短い時

目標のテーブル構造

公式ガイドでもよく使われるような下記のようなテーブルを作り、postsテーブルのuser_idに外部キー制約をかけることを目指します。

image.png

Laravel7より前の時の記法

Laravel7より前のバージョンで外部キー制約をつけるためには、下記のようにmigrationファイルを作成をしていました。
一度user_idのカラムを作成してから別の行で外部キー制約をつけています。

        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
        });

image.png

そんなに難しくもないですが、少しだけ面倒です。

Laravel7以降で使えるエイリアスを使用

そこでLaravel7以降では下記のようなエイリアスができ、foreignIdconstrained()を使えば一行でも外部キー制約をかけることができるようになりました。
短くて楽ですね。

        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained();
            $table->timestamps();
        });

image.png

テーブル名が長い時

目標のテーブル構造

問題のパターンです。下記のようなテーブルを想定して試してみます。
名前は適当に僕が好きなスポーツからとってきましたが、とりあえず2つのテーブル名が長く文字数の合計が一定数を超えると同じ現象になります。

image.png

Laravel7以降で使えるエイリアスを使用

せっかく新しい記法があるということなので、foreignIdを使った新しいエイリアスを使ってやってみます。

        Schema::create('national_basketball_association_players', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->foreignId('national_basketball_association_team_id')->constrained();
            $table->timestamps();
        });

キー名が長すぎるようで下記のようなエラーが出てしまいました。

  SQLSTATE[42000]: Syntax error or access violation: 1059 Identifier name 'national_basketball_association_players_national_basketball_association_team_id_foreign' is too long (SQL: alter table `national_basketball_association_players` add constraint `national_basketball_association_players_national_basketball_association_team_id_foreign` foreign key (`national_basketball_association_team_id`) references `national_basketball_association_teams` (`id`))

通常であれば、Laravelのスキームビルダの制約命名規則に従い、自動的に外部キー制約の名前は変換されるため、外部キー制約名は下記のようになります。

(接続元テーブル名)_(外部キー名)_foreign

しかし、今回この命名規則に当てはめようとすると、national_basketball_association_players_national_basketball_association_team_id_foreignという名前になりますが、これは文字数が長すぎるということでエラーになってしまいました。

Laravel7以降で使えるエイリアスを使用(nameでキー名変更)

同じようなことが他の制約を作る時でも起こっていたのを思い出します。
nameメソッドを使えば直せたような気がするのでnameメソッドを使って試してみました。
外部キー制約名は省略した、basketball_players_team_id_foreignを設定します。

        Schema::create('national_basketball_association_players', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->foreignId('national_basketball_association_team_id')->constrained()->name('basketball_players_team_id_foreign');
            $table->timestamps();
        });

先程と違い、今度はエラーも起こらず、migrationファイルが無事に通りました。
念のためにdatabaseを確認してみます。

image.png

外部キー制約がついていません。。。
多分routeを作成する時に使うnameメソッドと勘違いしていたのですが、ここで結構ハマってしまいました。

migration関連でnameメソッドは用意されていなさそうでした。

エイリアスメソッドのコードを確認

改めて今回のエイリアスのforeignIdメソッドを確認してみます。

    public function foreignId($column)
    {
        $this->columns[] = $column = new ForeignIdColumnDefinition($this, [
            'type' => 'bigInteger',
            'name' => $column,
            'autoIncrement' => false,
            'unsigned' => true,
        ]);

        return $column;
    }

引数がカラム名のみで1つしか受け付けていないので、キー名を短くして渡そうとしても無理そうです。

また、foreignIdの後に使っているconstrainedも確認してみます。

    public function constrained($table = null, $column = 'id')
    {
        return $this->references($column)->on($table ?? Str::plural(Str::beforeLast($this->name, '_'.$column)));
    }

こちらも外部キー制約名を渡す引数がなく、無理そうです。

結果:Laravel7以降で使えるエイリアスを使用(indexでキー名変更)

下記のようにindexメソッドを使って、外部キー名を指定するとうまくいきました。

        Schema::create('national_basketball_association_players', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->foreignId('national_basketball_association_team_id')->constrained()->index('basketball_players_team_id_foreign');
            $table->timestamps();
        });

公式ガイドを見てみるとindexメソッドは「基本的なインデックス追加」とだけ書いてありましたが、外部キー制約の名前を作成をする際にも使えるようです。
uniqueキー作るときは、第2引数にインデックスキー名指定できるのに対して、外部キー制約の場合はindexメソッドを使わないといけなさそうなので書き方が結構違いますね。

image.png

https://readouble.com/laravel/7.x/ja/migrations.html

※何か誤解していたり、他にいい方法があれば教えていただけると助かります!!!

Laravel7より前の時の記法でやる方法

もちろん元々使っていた記法を使って、foreignメソッドの中の第2引数に外部キー制約名を指定してもうまくいきます。
このやり方は元々やったことあったのですが、ハマるくらいなら最初からこっち使っておけばよかったなと思いました、、、

        Schema::create('national_basketball_association_players', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->unsignedBigInteger('national_basketball_association_team_id');
            $table->foreign('national_basketball_association_team_id', 'basketball_players_team_id_foreign')->references('id')->on('national_basketball_association_teams');
            $table->timestamps();
        });

image.png

感想

チュートリアルで使うようなusersとかpostsとかのテーブルと違い、実務ではテーブル名が長くなるケースは命名規則によりけりだと思いますが、結構発生しそうなイメージなので意外と困ることもあるかなと思います。

また、今回少し深く調べてみて、フレームワークのコードをより深くみるようにしたのはよかったなと思いました。

それにしてもnameメソッドを使ったときに何故かmigrationファイル通るのに外部キー制約がついていないのは結構たちが悪かったです。。。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelでURLによってDBを切り替える

URLと.envファイルを紐づける

以下のように追記するとURLごとにDBが切り替わる。

bootstrap/app.php
// URLを取得する
$requested_url = $_SERVER["REQUEST_URI"];

// URL中に特定の文字列が含まれていた場合に.envファイルを指定のファイルへ変更する。
if(strpos($requested_url,'sample1') !== false){
    $app->loadEnvironmentFrom('.env.sample1');
}
if(strpos($requested_url,'sample2') !== false){
    $app->loadEnvironmentFrom('.env.sample2');
}

これに合わせて、
.env.sample1
.env.sample2
を.envをコピーして同階層に作成する。

DB_CONNECTIONだけ共通にしておく。

env.sample1/.env.sample2で共通
DB_CONNECTION=samples

database.phpに.envをロードする記述を追記

database.php
        'samples' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],

.envファイルを認識させるのにコマンドを叩く。
Laravelで.envファイルが反映されない時より

php artisan cache:clear
php artisan config:cache

ルーティングの修正

Auth認証など、name属性があるとforeachに失敗するので外しておく。

web.php
$group_id_list = [
    'sample1'
    ,'sample2'
];

foreach($group_id_list as $group_id) {
    Route::group(['prefix' => $group_id],function(){
      Route::get('/','IndexController@index');

        // AuthRouteMethods.phpのルートを手動で記述
        Route::get('login', 'Auth\LoginController@showLoginForm');
        Route::post('login', 'Auth\LoginController@login');
        Route::post('logout', 'Auth\LoginController@logout');

        Route::get('register', 'Auth\RegisterController@showRegistrationForm');
        Route::post('register', 'Auth\RegisterController@register');
});

マイグレーションとシーダーファイルの修正

foreachするなりして複数化する。
シーダーはDBに合わせて変えた方がいい。

Auth認証のルートを上書きする

app/Handlerに以下を追記する
予めセッションにURLの一部を入れている前提で書いていますが、自分のソースに合わせて変えてください。
web.phpでnameを外しているので、route()関数は使えません。

app/Handler.php
    protected function unauthenticated($request, AuthenticationException $exception)
    {
        // セッションからグループURLを取り出す。
        $group_url = request()->session()->get('samples_url');

        return $request->expectsJson()
                    ? response()->json(['message' => $exception->getMessage()], 401)
                    : redirect()->guest($samples_url.'/login');
    }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravelで外部APIを取得し、Ajaxで取得

外部APIを使うことになったためメモ。
Laravelではguzzleというライブラリを使って外部APIを取得。

terminal
composer require guzzlehttp/guzzle
ApiController
<?php

namespace App\Http\Controllers;

use GuzzleHttp\Client;//忘れず

class PostController extends Controller
{
    public function index()
    {
        $api_key = "hogehogehogehogehofe";//ここにAPI_KEY

        $url = "https://hoge.com/api/" . $api_key;//url次第
        $method = "GET";

        //接続
        $client = new Client();

        $response = $client->request($method, $url);

        $posts = $response->getBody();
        $posts = json_decode($posts, true);//jsonに変換

        return view('index', ['posts' => $posts]);
    }
}
api.php
Route::get('/index', 'ApiController@index');
Index.vue
<script>
export default {
    created(){
        axios.get('/api/index')
        .then((response) => {
            console.log(response.data);
        })
    }
}
</script>

キーがない場合はそのままaxiosで取得できるが、キーがある場合はエラーになるためguzzleが必要そう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel! 頑張る! DDDもどき!

DDDもどき

ここではドメイン駆動開発に関してのテクニック、ノウハウ、考えた方資料などをまとめて行きます。

書籍

tyamahoriのおすすめを貼ります。

現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法

ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本

ドメイン駆動設計 モデリング/実装ガイド - little-hands - BOOTH

頑張れる人向け

エリック・エヴァンスのドメイン駆動設計

実践ドメイン駆動設計

.NETのエンタープライズアプリケーションアーキテクチャ第2版 .NETを例にしたアプリケーション設計原則

参考リポジトリ

anfangd/laravel-ddd-sample-for-beginners

参考サイト

[DDD]ドメイン駆動 + オニオンアーキテクチャ概略 - Qiita

ご主人様、小難しいDDDやクリーンアーキテクチャはお忘れになって、“削除しやすい設計”から始められてはいかが? - Qiita

Laravelでドメイン駆動設計(DDD)を実践し、Eloquent Model依存の設計から脱却する - Qiita

https://twitter.com/masuda220/status/1321700797042716672

https://designpatternsphp.readthedocs.io/ja/latest/README.html

ポイント

  • リポジトリパターン
  • オニオンアーキテクチャ
  • モデリング大事!!
  • 業務の理解大事!!
  • ビジネスサイドと話し合い、共通言語を作る
  • 共通言語をクラスに再現する。それがドメインオブジェクトになる
  • これが一番大変。。ここがグダグダしていると良い実装ができない。。
  • クラスの数がめちゃくちゃ増えます。。

クラス設計

  • コントローラークラス
    • HTTPリクエストの取り回し対応
    • viewに値を渡す場合viewmodelクラスを使う(こだわる場合)
  • パラメータークラス
    • 入力で使う
    • 命名は適当。
    • 用途はユーザーの入力値をラップするデータオブジェクト
  • DTOクラス
    • 出力で使う
    • 命名は適当
    • ユースケースクラスがコントローラークラスにデータを渡すときにラップして使う
  • ユースケースクラス
    • リポジトリインターフェースクラスをコンストラクタインジェクションする
    • パラメータクラスをメソッドインジェクションする
    • 必要に応じてドメインサービスクラスをコンストラクタインジェクションする
    • ロジックは書かない!あくまでもドメインクラスのメソッドを利用するだけにとどめる
  • ドメインクラス
    • エンティティクラス
      • ドメインの主役。ロジックの置き場所
    • バリューオブジェクトクラス
      • 型定義のクラス
    • リポジトリインターフェイスクラス
      • データソースとやり取りするクラス
      • インターフェースの理由はデータソースが変わっても柔軟に対応できるようにするため
      • ドメインオブジェクトを返すようにする。Eloquentクラスは返さない
    • ドメインサービス
      • エンティティやバリューオブジェクトでは表現しにくい処理をここで書く
      • 取り扱い注意。基本はエンティティやバリューオブジェクトで対応する。最後の手段として使う場所
  • インフラストラクチャークラス
    • リポジトリインターフェースの具象クラス
    • データソースと直接やり取りするクラス
    • EloquentやQueryBuilderをゴリゴリ使って、データの保存やデータの問い合わせを行う
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む