Docker構築（Nginx+PostgreSQL）

# 参考ページ
[【Docker環境構築】Laravel10 + Nginx + PostgreSQL + PgAdmin](https://qiita.com/so_engineer/items/6abd134e1ad56670c55e)
[Laravel 11 の開発環境をdockerで実現する方法](https://qiita.com/hitotch/items/2e816bc1423d00562dc2)

# 開発環境
- Docker Desktop 4.35.1
- PHP 8.3.14
- node v22.11.0
- Laravel Framework 11.34.2
- Composer 2.8.3
- PostgreSQL 14
- PgAdmin4
- WSL2 1.0.27

# ディレクトリ構成
```
/（ルートディレクトリ）
├── .docker
|    ├── db
|    |── nginx
|    |    |── default.conf
|    |    └── Dockerfile
|    |── pgadmin4_data
|    └── php
|         |──Dockerfile
|         └──php.ini
│── src 
│    └──（Laravelのプロジェクトディレクトリ）
└── docker-compose.yml
```

# 起動方法
## Docker Composeコマンドでコンテナを起動

Docker Desktopアプリを起動後、ルートディレクトリ（docker-compose.ymlのあるディレクトリ）でコマンドを実行し、コンテナを作成・起動する。

```
docker compose up -d
```
※9分くらいかかった

# Dockerの確認
![[Pasted image 20241128114409.png]]

# Laravelをインストールする

Laravelのインストール先は、appサーバー＝phpサーバーです。  
appサーバーに入って、composerを使ってLaravelをインストールします。

## appサーバーのコンソールに入る

```
docker exec -it  postgresql-web-1 bash
```
## サブフォルダにLaravelをインストールする

サブフォルダ「tmp」に一旦インストールし、その後中身をプロジェクトフォルダに移動する。
ここではバージョン11を指定しています。

```
# mkdir tmp
# cd tmp
# composer create-project "laravel/laravel=11.*" . --prefer-dist
```
次に中身をプロジェクトフォルダに移動し、一時サブフォルダを削除。
```
# cd ..
# mv tmp/* ./
# mv tmp/.* ./
# rm tmp -rf
```
## 依存のインストール

サブフォルダからプロジェクトフォルダに移動したので、このフォルダで依存をインストールします。

```
# composer install
# npm install
```
`storage`フォルダ以下はWeb用のユーザー`www-data`が書き込みできなくてはいけないので、書き込み権限を付与しておきます。  
これをやっておかないと、実行テストをした時点で「The stream or file "/src/storage/logs/laravel.log" could not be opened in append mode」というエラーになります。

```
# chmod -R guo+w storage
```
storageのシンボリックリンクを設置します。

```
# php artisan storage:link
```
## LaravelとDBを接続する

Laravel11から、セッションの保存先がデフォルトでDBになりました。これにより、DB設定をしてセッション保存先テーブルを準備しておかないとLaravelのフロントが正常に起動できません。DB設定は`/src/.env`ファイルに`DB_`で始まる変数が記述部分にあるので、デフォルトの記述をコメントアウトするなどして以下のように記述します。

```.env
# DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=

DB_CONNECTION=pgsql  
DB_HOST=postgres  
DB_PORT=5432  
DB_DATABASE=postgres  
DB_USERNAME=postgres  
DB_PASSWORD=postgres
```
さらに、セッションの保存先テーブルを含むデフォルトのテーブルを作ります。

```
# php artisan migrate
```
# Webの動作確認
ブラウザでNginxにアクセスする
localhost:8000

# PgAdmin4 でDBに接続する
### ブラウザで localhost:5050 にアクセスし、
### docker-compose.yml に記載されている情報でログインする
 Email Address: test@test.com
 Password: password

### 接続を登録する
Server＞登録＞サーバー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677479/a6635f5b-ce27-0a50-d09a-0a3780b46996.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677479/06489a53-81e1-98d0-451f-c0ad9f6d2146.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677479/0a374161-1d98-9cae-fa31-954be529d0f2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677479/cb2fa3ab-b812-bc4d-e74f-eb909e2eb31c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677479/fdf76689-3954-83e1-6a16-a0c26fcd87e8.png)


# コンポーネントを作る
```bash
> docker exec -it  postgresql-web-1 bash

# php artisan make:component SelectBox
```

以下のファイルが作られる
src/resources/views/components/select-box.blade.php
```src/resources/views/components/select-box.blade.php
<div>  
  <select class="form-select" aria-label="Default select example">  
    <option selected>果物を選択してください</option>  
    @foreach($options as $key => $value)  
      <option value="{{$key}}">{{$value}}</option>  
    @endforeach  
  </select>  
</div>
```

src/app/View/Components/SelectBox.php
```src/app/View/Components/SelectBox.php
<?php  
  
namespace App\View\Components;  
  
use Closure;  
use Illuminate\Contracts\View\View;  
use Illuminate\View\Component;  
  
class SelectBox extends Component  
{  
  public array $options;  
  
  /**  
   * Create a new component instance.   */ 
  public function __construct(array $options)  
  {  
    $this->options = $options;  
  }  
  
  /**  
   * Get the view / contents that represent the component.   */
  public function render(): View|Closure|string  
  {  
    return view('components.select-box');  
  }  
}
```
コンポーネントを呼び出す
```php
@php  
  // セレクトボックスに渡す配列  
  $fruit = [  
      'apple' => 'xりんご',  
      'orange' => 'みかん',  
      'banana' => 'バナナ'  
  ];  
@endphp  
<x-select-box :options="$fruit"/>
```