【Docker環境構築】Laravel10 + Nginx + PostgreSQL + PgAdmin 

# はじめに
Laravel+Nginx+MySQL+phpmyAdminの環境構築例は多いものの、Laravel+Nginx+PostgreSQL+PgAdminの環境構築例はWeb上に少なかったので、備忘録として残すことにしました。

# 開発環境
- Docker Desktop
- PHP 8.3.3
- node v20.11.1
- Laravel Framework 10
- Composer 2.7.1
- PostgreSQL 14
- PgAdmin4
- WSL2

# ディレクトリ構成

全体のディレクトリ構成は以下です。

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

# 各ディレクトリ・ファイルの説明

## docker-compose.yml
Docker Composeを実行するためのyml形式のファイルです。
作成する各コンテナの設定を記述します。

```yml
version: "3"

services:
  web:
    build: ./.docker/php
    volumes:
      - ./src:/var/www
      - ./.docker/php/php.ini:/usr/local/etc/php/php.ini
    depends_on:
      - postgres

  nginx:
    build: ./.docker/nginx
    ports:
      - "8000:80"
    volumes:
      - ./src:/var/www
      - ./.docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - web

  postgres:
    image: postgres:14
    restart: always
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    ports:
      - "5433:5432"
    volumes:
      - ./.docker/db/data:/var/lib/postgresql/data

  pgadmin4:
    image: dpage/pgadmin4
    ports:
      - 5050:80
    volumes:
      - ./.docker/pgadmin4_data:/var/lib/pgadmin
    environment:
      PGADMIN_DEFAULT_EMAIL: test@test.com
      PGADMIN_DEFAULT_PASSWORD: password
    depends_on:
      - postgres

volumes:
  pgadmindata:

```

## .dockerディレクトリ
各コンテナを起動するためのDockefileとその他追加設定のファイルを格納しています。

### db
postgreSQL用コンテナ起動時に生成されます。
初期状態では無くても問題ありません。

### nginx
Nginx用コンテナのDockerfileと設定ファイルを格納しています。

**Dockerfile**
```Dockerfile
FROM alpine:3.6

RUN apk update && \
    apk add --no-cache nginx
RUN mkdir -p /run/nginx

RUN apk --no-cache add tzdata \
    && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && apk del tzdata

CMD nginx -g "daemon off;"
```

**default.conf**
```conf
server {
    listen 80;
    # server_name localhost;
    
    root /var/www/public; 
    index index.php index.html;
    allow all;
    
    access_log /var/log/nginx/ssl-access.log;
    error_log  /var/log/nginx/ssl-error.log;

    location / { 
        root /var/www/public;
        try_files $uri $uri/ /index.php$is_args$args;
    }  

    location ~ \.php$ {
        try_files $uri =404;
        
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass web:9000;
        fastcgi_index index.php;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;

        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
        add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
        add_header Access-Control-Allow-Credentials true;
    }   
}
```

### pgadmin_data
PgAdmin用コンテナ起動時に生成されます。
初期状態では無くても問題ありません。

### php
PHP用コンテナのDockerfileと設定ファイルを格納しています。

**Dockerfile**
```dockerfile

FROM php:8.3-fpm
WORKDIR /var/www
ADD . /var/www

# permission
RUN chown -R www-data:www-data /var/www

# install composer
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer

# install packages
RUN apt-get update \
  && apt-get install -y \
  gcc \
  make \
  git \
  unzip \
  vim \
  libpng-dev \
  libjpeg-dev \
  libfreetype6-dev \
  libmcrypt-dev \
  libpq-dev \
  curl \
  gnupg \
  openssl \
  postgresql postgresql-contrib \
  && docker-php-ext-install pdo pdo_pgsql pgsql \
  && docker-php-ext-configure gd --with-freetype --with-jpeg \
  && docker-php-ext-install -j$(nproc) gd

# Add php.ini
COPY php.ini /usr/local/etc/php/

# install stable node and latest npm
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash
RUN apt-get update \
  && apt-get install -y nodejs 
# install node packages
RUN npm install -g n
RUN n stable
RUN npm update -g npm
```

**php.ini**
```ini
[Date]
date.timezone = "Asia/Tokyo"

[Core]
display_errors = On
error_reporting = E_ALL
error_log = /var/log/apache2/error.log
log_errors = On
```

## srcディレクトリ
srcディレクトリ直下にLaravelプロジェクトファイルを設置します。
以下はLaravelプロジェクトを設置した際の、ディレクトリ例です。

```
src/
├── app/
├── bootstrap/
├── config/
├── database/ 
│── public/ 
│── resource/ 
│── route/ 
│── storage/ 
│── tests/ 
│── .env.example
│── composer.json
│── package.json
・
・
└── .gitignore
```

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

## Laravelプロジェクト構築
### Laravelプロジェクトの作成
例）Laravelプロジェクトの作成でできたプロジェクトファイル群のみを```/src```配下に設置してください。

Laravelプロジェクト作成コマンド例
```
composer create-project laravel/laravel:^10.0 example-app
```

```/src```ディレクトリ配下は以下のようにします。
```
/（ルートディレクトリ）
└── src/
    ├── app/
    ├── bootstrap/
    ├── config/
    ├── database/ 
    │── public/ 
    │── resource/ 
    │── route/ 
    │── storage/ 
    │── tests/ 
    │── .env.example
    │── composer.json
    │── package.json
    ・
    ・
    └── .gitignore
```

### webコンテナに入る
```
 docker exec -it [webコンテナ名] bash
```

[webコンテナ名]は、```docker ps```コマンドでコンテナ名を確認できます。

## これより以下はwebコンテナに入った状態で行います。
### 環境変数ファイルの設定
.env.exampleファイルをコピーして、.envファイルを作成します。

```
cp .env.example .env
```

### データベース設定
.envファイルにデータベース情報を記述します。

```
DB_CONNECTION=pgsql
DB_HOST=[dbコンテナ名]※今回はpostgres
DB_PORT=5432
DB_DATABASE=postgres
DB_USERNAME=postgres
DB_PASSWORD=postgres
```

### ライブラリのインストール
```
composer update
```
src/ディレクトリ配下に```vendor```フォルダが生成されます。


```
npm install
```
src/ディレクトリ配下に```mode_modules```フォルダが生成されます。

### マイグレーションの実行
```
php artisan migrate 
```

### アプリケーションキーの生成
```
php artisan key:generate
```

.envファイルのAPP_KEYに、アプリケーションキーが生成され記載されます。

### ビルドツールの起動
npmコマンドでビルドツールを起動します。
```
npm run build
```

### シンボリックリンクの作成
```
php artisan storage:link
```
src/public/storage　に　src/storage/app/publicへのシンボリックリンクが作成されます。
src/storage/app/publicに保存されたファイルをWeb上からアクセスする際に必要になります。

## ブラウザからアクセスする
ブラウザから [localhost:8000](localhost:8000) にアクセスしてLaravelのホーム画面が表示できることを確認します。

![スクリーンショット 2024-06-01 18.51.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774903/947135ed-4bfb-5c05-2ce5-cab5ef0e7b6a.png)


# PgAdminへのアクセス
ブラウザから [localhost:5050](localhost:5050) にアクセスします。

![スクリーンショット 2024-06-01 19.14.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774903/14433bca-0067-f8c7-402d-4680cc2fc7ee.png)

ログイン画面で以下の情報は以下で設定しています。(docker-compose.yml参照)
```
ログインメールアドレス：test@test.com
ログインパスワード：password
```

上記、認証情報を入力してログインします。
以下がログイン成功時の画面です。

![スクリーンショット 2024-06-01 19.15.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774903/33a1d260-ba0a-3b8f-ac11-e29172ea6567.png)