Dockerで環境構築（Next.js+Nginx+CakePHP+PostgreSQL+adminer）

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:
その中でもこれってどういう意味？とかつまづいたところを念入りに書いていこうかと思います。:fist:

# 今回の目的
今までの総決算をします！

https://qiita.com/mr_noppo/items/d921886c5f4d868374ba

https://qiita.com/mr_noppo/items/79e0dbcfaebea8c8192b

https://qiita.com/mr_noppo/items/abe96bd0b7200c0cbc6e

https://qiita.com/mr_noppo/items/2e91db5c96197145fd78

他、記事の中で紹介させていただきます！


# 使用したものや事前準備
・Macbook Pro
・ChatGPT
・Github Copilot
・Docker
・Visual Studio Code
・Next.js(React)
・CakePHP(PHP)
・PostgreSQL
・adminer

# すぐに試したい方へ〜Github〜
パッケージ類を抜いていますが、今回作成した部分はあげております！

https://github.com/takizawa0548/next-cake-nginx-posgres

実際に使う方はclone後に下記を実施してください。
・webフォルダに移動し、コマンドの実施
```
 npm install
 npm run build
```
・api/srcフォルダに移動し、コマンドの実施
```
composer install
```
・api/src/config/app_local.phpのソースを修正(composer install実行後に表示されます）
```php
       'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Postgres',
            'persistent' => false,
            'host' => 'db',
            'username' => 'app',
            'password' => 'app',
            'database' => 'app',
            'encoding' => 'utf8',
            'timezone' => 'UTC',
            'cacheMetadata' => true,
        ],
```
・プロジェクトフォルド直下に移動し、コマンドの実施
```
docker compose up
```
・下記にアクセスして、Helloテーブル＞Helloカラム（character 10)を作成し、データも作成
http://localhost:8080/?pgsql=db&server=db&username=app&db=app
パスワード:app
・http://localhost:80 にアクセス
※DBで失敗する場合は、 http://localhost:80/hello でアクセスしてエラー出てないか確認

# 全体構成

#### 目指した機能
・フロントからAPI呼び出せる。
・APIからDBにアクセスしデータを取り出せる。
・APIからフロントにJSONデータを渡せる。
・返却されたJSONデータを画面に表示できる。

#### 技術構成
フロント（静的ページ）：Next.js
バック（動的ページ）：CakePHP
DB：PostgreSQL
webサーバ：Nginx
アプリケーションWebサーバ：PHP-FPM
DB管理ツール：adminer

#### フォルダ構成
![スクリーンショット 2024-02-26 4.57.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/d663de06-c378-af2b-161b-0feec8dfc92e.png)



# 作成手順

各コンテナサービスごとに進めていきます。

## apiフォルダ

apiフォルダを作成し、その配下にDockerfileを作成しましょう。

![スクリーンショット 2024-02-26 1.09.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/b8924249-0dd8-2400-f0a6-17e385274b05.png)


### Dockerfile作成&ビルド

RUNコマンド
　・パッケージリスト更新
　・PHP拡張機能をコンパイルしてインストールするコマンド
　・CakePHP5をインストールするために必要なintlとZIP関係、依存関係のインストール
　・PostgreSQLデータベースに接続するための拡張機能、intlとZIPのインストール
 
COPYコマンド
 ・Dockerイメージのcomposerを使用

```Dockerfile
FROM php:8.3-fpm-bookworm

ENV TZ Asia/Tokyo

RUN apt-get update && \
  apt-get install -y libonig-dev libicu-dev libpq-dev libzip-dev zip && \
  docker-php-ext-install pdo_pgsql intl zip

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

WORKDIR /var/www
```
参考記事：

https://qiita.com/keitaMax/items/7bc51212a32a6418aa1c


ターミナルを開いて、apiフォルダに移動しビルドします。

```bash
cd api
docker build -t api .
```

イメージができたか確認しましょう。

```bash
docker image ls
```

中を確認したい人はこちらもみましょう。戻りたい時はexitで戻ってこれます。

```bash
docker run -it --rm api:latest /bin/bash 
```

一旦ここで、abi部分は止めておきます。
apiのプロジェクト作成は後半で行います。


## dbフォルダ
compose.ymlを作成し、dbサービスとadminerサービスの設定情報を記述します。

![スクリーンショット 2024-02-26 1.10.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/d52f13be-3f60-4fc0-dcfe-88cbd91c59b6.png)

### compose.yml作成

compose.ymlの記述内容です。

:::note info
※段階的に理解して進めていくために記述しており、後でまとめて再掲するのでいらない部分は消していただいて構いません。
:::

```yml
version: '3'
services:
  db:
    image: postgres:12.18-bookworm
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: app
    volumes:
      - postgres:/var/lib/postgresql/data
    #networks:
      #- api-db-network
      #- db-gui-network
  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
    #networks:
      #- db-gui-network
    depends_on:
      - db

volumes:
  postgres:
#networks:
  # web-api-network:
  #   driver: bridge
  # api-db-network:
  #   driver: bridge
  # db-gui-network:
  #   driver: bridge
```

### :writing_hand:dbのvolumesに設定するパスについて
データの保存先は、使用しているLinuxディストリビューションやPostgreSQLのバージョン等に依存します。
Volumeが二つできた等、不具合が発生した場合は要確認しましょう。

#### /var/lib/postgresql/data
Debianベースのディストリビューション（Ubuntuを含む）でDebianやUbuntuのパッケージマネージャー（apt）を使用してPostgreSQLをインストールした場合、使用されることが多いです。

#### /var/lib/pgsql/data
Red Hatベースのディストリビューション（Fedora、CentOS、RHELなど）でよくみられます。

PGDATAの位置については下記を参照ください。

https://www.postgresql.jp/document/12/html/storage-file-layout.html

### 起動確認

compose.ymlのあるフォルダに移動してから、コマンドを実行しましょう。
起動後にログインできることを確認します。

```bash
docker compose up -d --build
```

http://localhost:8080/?pgsql=db

データベース種類：PostgreSQL
サーバ：db
ユーザ名：app
パスワード：app
データベース：app

![スクリーンショット 2024-02-25 12.28.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/b5f03487-67bd-b8ca-05f4-17327ec38ff1.png)

ログインできたら、試しにテーブルを作成したり、コンテナを再起動してみましょう。テーブルが残っていることが確認できるかと思います。

![スクリーンショット 2024-02-25 12.29.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/d40ec949-b2ad-c439-05a7-aa483b3b74a7.png)

起動したコンテナは終了させます。

```bash
docker compose down
```

## webフォルダ
next.jsをビルドしてデプロイするパターンを作成します。
開発環境用に、ホットリロードしながら開発するパターンはまたいずれ・・・。

ローカルマシンにNode.jsが入っていることが前提で進めていきます。
MacBookの方はこちらの記事を参考にして導入してください。

https://qiita.com/mr_noppo/items/d3bca0ad2a5d4bd9fcc7

Node.jsのバージョンは20.9.0(LTS)を使用します。

https://nodejs.org/en/blog/release/v20.9.0

### webプロジェクトの作成

![スクリーンショット 2024-02-26 1.10.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/7ad1d10a-7d8c-abeb-986e-862b2bfd49fa.png)

説明がわかりづらくて申し訳ないですが、、、:sob:
全体のプロジェクト直下で下記のコマンドを実行し、 Webプロジェクトを作成します。
設問が出てきます。project nameはwebにし、他の設定はデフォルト（下記の画像の通り）に進めましょう。

```
npx create-next-app@latest --typescript
```

![スクリーンショット 2024-02-25 17.58.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/a3cdc66d-9667-adf1-e72e-63f8b562f05f.png)

少し待って、作成が完了したら実行できるか確認してみましょう。
```
cd web
npm run dev
```
http://localhost:3000/

![スクリーンショット 2024-02-25 18.04.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/8059d546-5cd7-c360-886b-73331e7d00f7.png)

ホットリロードで変更がかかるのも確認できると尚いいです。
web/app/page.tsxの18行目に自分の名前を入れてみて表示が変わるか確認してみてください。

![スクリーンショット 2024-02-26 1.00.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/d01307bc-7ace-48af-ce8d-5d65328c74bf.png)

![スクリーンショット 2024-02-26 1.02.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/f3e35409-918f-9689-7a37-edab43ae6e76.png)

ある程度堪能したらcontrol+c(ctrl+c)で終了します。
次の手順に進みましょう。:thumbsup:

### ビルド設定変更

Next.jsには静的部分を担当してもらうので、ビルド時にreactと同じように配置するだけで動く設定に変更します。

参考：

https://zenn.dev/dev_shun/articles/ace43099ba43ed

（動的な部分が必要な場合には、Nginx使う場合どう構成するのだろうとか、そもそもPHP以外に使うものなのかも整理できていないなとか色々思いましたが、とりあえず今回は置いておきます。。:rolling_eyes:）

ちなみに今回の設定をしないと、Next.jsはreactのみの時と違い、ビルド後もサーバー上でnpm startが必要です。Vercelを使用する方法がよくみられたのでいずれ調べることができたらと思います。

webフォルダ直下の next.config.mjs を開いてください。
nextConfig に output: 'export' を追加して保存してください。
```yml
output: 'export'
```

![スクリーンショット 2024-02-25 17.43.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/c138b230-3d08-7702-b7f7-22bb39233e24.png)

ビルドした時に、outフォルダが作成されることを確認します。（今回のNginxサーバーに配置する資材です。）
webフォルダに遷移し、下記コマンドを実行してみてください。

```
npm run build
```

![スクリーンショット 2024-02-25 18.08.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/c7dda595-e28e-2bf9-2e89-b735852d0723.png)


次にいきましょう。:ok_hand:

## nginxフォルダ
全体のプロジェクト直下にnginxフォルダを追加しましょう。

![スクリーンショット 2024-02-26 1.15.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/6443c894-309a-e1bb-afc8-f989de8d9d65.png)

下記記事を参考にして設定します。

https://qiita.com/mr_noppo/items/2e91db5c96197145fd78

Nginxのバージョンはメジャーバージョン（mainline）の1.25.4を設定します。

https://nginx.org/

### Nginx関連ファイル修正

#### compose.yml
下記設定に変更しましょう。
・- ./web/out:/usr/share/nginx/htmlは、Web部分で行なったビルドファイルと紐づけています。

``` yml
version: '3'
services:
  nginx:
    image: nginx:1.25.4-bookworm
    ports:
      - 80:80
    volumes:
      - ./web/out:/usr/share/nginx/html
      - ./nginx/fastcgi_params:/etc/nginx/fastcgi_params
      - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
    # depends_on:
    #   - api
    # networks:
    #   - web-api-network
```

#### fastcgi_params
nginxフォルダ直下にファイルを作成し、下記内容を追加しましょう。

```config
fastcgi_param   QUERY_STRING            $query_string;
fastcgi_param   REQUEST_METHOD          $request_method;
fastcgi_param   CONTENT_TYPE            $content_type;
fastcgi_param   CONTENT_LENGTH          $content_length;

fastcgi_param   SCRIPT_FILENAME         $document_root$fastcgi_script_name;
fastcgi_param   SCRIPT_NAME             $fastcgi_script_name;
fastcgi_param   PATH_INFO               $fastcgi_path_info;
fastcgi_param   PATH_TRANSLATED         $document_root$fastcgi_path_info;
fastcgi_param   REQUEST_URI             $request_uri;
fastcgi_param   DOCUMENT_URI            $document_uri;
fastcgi_param   DOCUMENT_ROOT           $document_root;
fastcgi_param   SERVER_PROTOCOL         $server_protocol;

fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;
fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;

fastcgi_param   REMOTE_ADDR             $remote_addr;
fastcgi_param   REMOTE_PORT             $remote_port;
fastcgi_param   SERVER_ADDR             $server_addr;
fastcgi_param   SERVER_PORT             $server_port;
fastcgi_param   SERVER_NAME             $server_name;

fastcgi_param   HTTPS                   $https;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param   REDIRECT_STATUS         200;
```

#### default.conf
nginx/conf.d直下にファイルを作成し下記内容を追加しましょう。
・location / {〜は、Next.jsを見にいくように作成しています。
・location /Hello {は、apiサービスが完成していないため、一時的に127.0.0.1へ変更しています。

``` conf
server {
    listen       80;
    server_name  localhost;

    location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    }

    location /Hello {
       root /var/www/src/webroot/index.php;
       fastcgi_param HTTP_PROXY "";
       fastcgi_pass 127.0.0.1:9000;
       include fastcgi_params;
    }
}
```

### コンテナ起動確認

全体のプロジェクト直下で下記のコマンドを実行してください。
コンテナを起動し、webプロジェクトのビルドファイルで画面を表示できるか確認します。
```bash
cd ../
docker compose up -d --build
```

下記にアクセスしてNode.js画面が表示されたら成功です。

http://localhost:80/

先ほどと同様に修正しても更新がかからないことも確認してみるといいでしょう。


起動したコンテナは終了させます。

```bash
docker compose down
```

### :writing_hand:NginxイメージにNode.jsを入れたいときは
Dockerfileを作成してこちらの設定を入れましょう。
```Dockerfile
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash && \
  export NVM_DIR="$HOME/.nvm" && \
  [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
  [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  && \
  nvm install 20.9.0
```

# コンテナ起動準備

全体の確認が取れたので協調して動くようにプロジェクト作成と再度修正します。

## CakePHPプロジェクト作成
compose.ymlにapiの設定を追加します。他は全てコメントアウトか削除してください。
```yml
version: '3'
services:
  api:
    build: ./api
    volumes:
      - ./api:/var/www/
    # networks:
    #   - web-api-network
```

apiサービスのみ起動します。
compose.ymlがあるフォルダでコマンドを実行しましょう。

```bash
docker compose up -d --build
```

実行コマンドにsrcを追加し、compose.ymlがあるフォルダでコマンドを実行します。（srcフォルダは自動追加されます。）
※Dockerfileがある階層では作成するとフォルダがからじゃないと怒られてエラーが発生します

```bash
docker compose exec api bash -c 'composer create-project --prefer-dist cakephp/app:5 ./src'
```
パーミッションの設定を自動でやってくれるかですがデフォルトのまま（Y）で進めます。

![スクリーンショット 2024-02-26 2.05.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/cf03f2c9-610a-d5f5-871a-a92e3d0817de.png)

フォルダが作成されました。

![スクリーンショット 2024-02-26 2.07.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/406bc320-aa92-3a35-deab-89cf7f42c802.png)


起動したコンテナは終了させます。

```bash
docker compose down
```

## 設定ファイル＆ソースファイル修正




### default.conf
パス：nginx/conf.d/default.conf

nginxサービスがapiサービスに繋げられるようにfastcgi_passのポート番号を api に変更します。

```conf
    location /Hello {
       root /var/www/src/webroot/index.php;
       fastcgi_param HTTP_PROXY "";
       fastcgi_pass api:9000;
       include fastcgi_params;
    }
```

### app.php

接続設定情報は下記ページの設定項目を参考にしています。

https://book.cakephp.org/5/ja/orm/database-basics.html#id1

```php
    'default' => [
        'className' => 'Cake\Database\Connection',
        'driver' => 'Cake\Database\Driver\Postgres',
        'persistent' => false,
        'host' => 'db',
        'username' => 'app',
        'password' => 'app',
        'database' => 'app',
        'encoding' => 'utf8',
        'timezone' => 'UTC',
        'cacheMetadata' => true,
    ],
```

## 検証ソースファイル&検証データ作成

### api(CakePHP)

#### HelloController.php 

api/src/src/Controller 配下に HelloController.php を作成します。
http://localhost:80/Hello でアクセスすると HelloController.php が対応してくれます。
アクセスしてきた時にテーブル取得結果のJSONデータを返却するように作成します。

```php
<?php

namespace App\Controller;

use Cake\Controller\Controller;
use Cake\Http\Response;
use Cake\Datasource\ConnectionManager;

class HelloController extends Controller
{
    public function index(): Response
    {

        $connection = ConnectionManager::get('default');

        // SQLクエリを実行
        $results = $connection->execute('SELECT "Hello" FROM "Hello"')->fetchAll('assoc');
        $message = 'Hello';
        $this->set(compact('results'));
        $this->viewBuilder()->setOption('serialize', ['results']);

        return $this->response->withType('application/json')->withStringBody(json_encode(compact('results')));
    }
}
```

### web(Next.js)
web/app/page.tsxを変更します。おしゃれなページで名残惜しいですがすっきり消しちゃいましょう！

###### コード補足
"use client"でクライアント処理であることを明示しています。これがないとuseEffectとuseStateが使えません。（Next.js 13以降からの仕組み）

ルーティングの仕組みは、app配下のpage.tsxがindex.html扱いになります。
他のページにアクセスさせたい場合は、app配下でフォルダを作成しpage.tsxを配置すればルーティングできます。
（例：/testでアクセスした時はtest/page.tsxが呼ばれる。）

Nginx経由でやる方法が地味に理解するのが難しかったです。:sweat:
今後改善していきたいと思います。

#### page.tsx

```tsx
"use client";

import React, { useEffect, useState } from 'react';
import axios from 'axios';

const HelloWorld: React.FC = () => {
  const [data, setData] = useState('');

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get('http://localhost:80/Hello');
        console.log("ok");
        setData(response.data);
      } catch (error) {
        console.error('Error fetching data:', error);
      }
    };

    fetchData();
  }, []);

  return (
    <div>
      <h1>Hello, World!</h1>
      <p>{JSON.stringify(data)}</p>
    </div>
  );
};

export default HelloWorld;
```

#### axiosインストール
不足しているパッケージをインストールします。

```bash
cd web
npm install axios
```

### db（PostgreSQL+adminer)

テーブルとデータを作成します。

#### compose.yml修正

compose.ymlをdbサービスとadminerサービスのみにします

```yml
version: '3'
services:
  db:
    image: postgres:12.18-bookworm
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: app
    volumes:
      - postgres:/var/lib/postgresql/data
    networks:
      # - api-db-network
      - db-gui-network
  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
    networks:
      - db-gui-network
    depends_on:
      - db

volumes:
  postgres:
networks:
  # web-api-network:
  #   driver: bridge
  # api-db-network:
  #   driver: bridge
  db-gui-network:
    driver: bridge
```

#### サービス起動 & adminer接続

compose.ymlが配置されているフォルダでコマンドを実行します。

```
cd ../
docker compose up -d --build
```

adminerに接続します。

ユーザ名：app
パスワード：app
データベース:app

http://localhost:8080/?pgsql=db


#### テーブル作成

左のメニューの「テーブル作成」を押下します。
HelloテーブルにHelloカラムを追加し「保存」を押下します。
テーブル名：Hello
列名：Hello
型：character
長さ：10

![スクリーンショット 2024-02-26 2.32.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/4c1e111a-963a-64b4-6384-05e9fdc13bd3.png)

#### データ作成
作成後、左画面から「テーブル名（Hello）」を押下します。
「項目の作成」を押下します。データの内容はなんでも構わないので入力後、「保存」を押下します。
（例：DBから出てきました）

![スクリーンショット 2024-02-25 23.58.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/b03197d4-3249-baea-ac88-8b0bf954c5ea.png)

#### SQL確認
左に表示されている「SQLコマンド」を押下します。
下記のSQLをコピペし、「実行」を押下します。
```SQL
SELECT "Hello" FROM "Hello"
```

データが表示されればOKです。:raised_hands:

![スクリーンショット 2024-02-26 0.00.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/b8f25dc7-37eb-e05e-2396-7f235b5984b8.png)

起動したコンテナは終了させます。

```bash
docker compose down
```

## compose.yml完成

全ての確認が取れたので、compose.ymlを完成させます。
コピーして貼り付けましょう。

```yml
version: '3'
services:
  nginx:
    image: nginx:1.25.4-bookworm
    ports:
      - 80:80
    volumes:
      - ./web/out:/usr/share/nginx/html
      - ./nginx/fastcgi_params:/etc/nginx/fastcgi_params
      - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - api
    networks:
      - web-api-network
  api:
    build: ./api
    volumes:
      - ./api:/var/www/
    networks:
      - web-api-network
      - api-db-network
  db:
    image: postgres:12.18-bookworm
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: app
    volumes:
      - postgres:/var/lib/postgresql/data
    networks:
      - api-db-network
      - db-gui-network
  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
    networks:
      - db-gui-network
    depends_on:
      - db

volumes:
  postgres:
networks:
  web-api-network:
    driver: bridge
  api-db-network:
    driver: bridge
  db-gui-network:
    driver: bridge
```

下記、サービスごとの補足説明です。

追加で設定しているのは２点です。
depends_on　:　apiサービスの後に起動を開始するようにしています
networks　:　web-api-networkを設定しているサービスとのみ通信するようにしています。

#### nginxサービス
ここに記載はありませんが、adminerとポート番号が被らないように注意しましょう。
```yml
    depends_on:
      - api
    networks:
      - web-api-network
```

#### apiサービス

```yml
    networks:
      - web-api-network
```
#### dbサービス

```yml
    networks:
      - api-db-network
      - db-gui-network
```

#### adiminer

```yml
    networks:
      - db-gui-network
    depends_on:
      - db
```

#### その他
ネットワークの依存関係を追加しています。

```yml
networks:
  web-api-network:
    driver: bridge
  api-db-network:
    driver: bridge
  db-gui-network:
    driver: bridge
```


# コンテナ起動＆動作確認
だいぶ長くなりました。お疲れ様でした。:upside_down:
ここで全体の稼働確認をします。

#### nginx/conf.d/default.conf
127.0.0.1のままになっていないか念のため確認しましょう。変更していなかった場合は api に変更します。

### コンテナ起動

webプロジェクトのビルドを行います。
```
cd web
npm run build
```
ビルドが完了したら起動しましょう。
```
cd ../
docker compose up -d --build
```

Docker Desktopがある方はコンテナが全て稼働しているか確認しやすいです。

![スクリーンショット 2024-02-26 0.08.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/2ef785d9-6feb-5649-01c9-6852be8253d2.png)

アクセスして、結果が表示されれば成功です。

http://localhost:80/

![スクリーンショット 2024-02-26 0.18.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/05ba51f6-5fc6-daaa-ed62-67b35655431d.png)



# 最後に
なるべく分解して取り組むことにとても悩みました。
入り組んでくるとややこしくなり把握できなくなるため、段階踏んでやりたかったですがなかなかできず気づいたら鳥の声が聞こえていました。:sunny:
後半に至っては知らないことばかりで、ChatGPTとレスバトルを繰り広げるなど、AIいてくれてよかったと思います。一人ではとてもできなかったです！
開発環境をホットリロードで実施できたらなと思うので引き続きやっていきたいと思います！

# おまけ
開発環境整備してみた

https://qiita.com/mr_noppo/items/11a179cb2569260b6771