docker-composeでsymfony 5の環境を作成してみた


私の勉強用でやったものです。間違いなどあれば教えていただければありがたいです。

↓こちらにも設定を用意しました

https://github.com/okumurakengo/docker-symfony

```docker-compose.yml
version: "3"

services:
  web:
    image: nginx
    ports:
      - "8080:80"
    volumes:
      # ホストのdefault.confを同期
      - ./default.conf:/etc/nginx/conf.d/default.conf
      # ホストの./myappフォルダを同期
      - ./myapp:/var/www/html/myapp
    depends_on:
      - php

  php:
    build: .
    volumes:
      # ホストの./myappフォルダを同期
      - ./myapp:/var/www/html/myapp

  db:
    image: mysql:8.0
    # PDOでhostを指定するときにこのコンテナ名を使う
    container_name: mysql
    volumes:
      # データが消えてしまわないようにマウントmysqlのフォルダをマウント
      - ./mysql:/var/lib/mysql
    # MySQL8.0でのデフォルトの認証方式が「caching_sha2_password」なので変更する
    # 設定しないと "The server requested authentication method unknown to the client" とエラーになる
    command: --default-authentication-plugin=mysql_native_password
    environment:
      # 設定必須、rootパスワード
      - MYSQL_ROOT_PASSWORD=root
      # この設定はオプション、イメージの起動時に作成されるデータベース名
      - MYSQL_DATABASE=sample
```

```nginx:default.conf
server {
    server_name  localhost;
    root /var/www/html/myapp/public;

    location / {
        index  index.php index.html;
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
       fastcgi_pass   php:9000;
       fastcgi_index  index.php;
       fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
       include        fastcgi_params;
    }
}
```

```Dockerfile:Dockerfile
FROM php:7.4-fpm

RUN apt-get update \
    && apt-get install -y zlib1g-dev libzip-dev \
    && docker-php-ext-install pdo pdo_mysql zip

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

WORKDIR /var/www/html/myapp
```

```console
$ docker-compose up -d
$ docker-compose exec php pwd #カレントディレクトリのパスを確認
/var/www/html/myapp
$ docker-compose exec php composer create-project symfony/website-skeleton . #myappフォルダにsymfonyのプロジェクト作成
```

symfonyのバージョンを指定する場合は`composer create-project symfony/website-skeleton:^5.1 .`

http://localhost:8080/ でsymfonyの画面が表示される

<img width="996" alt="Screen Shot 2020-07-13 at 8.46.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/965b5f4f-8664-d6b2-fbe5-62c2dcf4a537.png">

---

データベースの確認

`.env`ファイル修正

```diff:myapp/.env
- DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7
+ DATABASE_URL=mysql://root:root@mysql:3306/sample?serverVersion=8.0
```

```console
$ docker-compose exec php php bin/console make:controller ProductController #コントローラ作成
```

`src/Controller/ProductController.php` が作成される

http://localhost:8080/product にアクセスするとコントローラーの内容が表示される

<img width="839" alt="Screen Shot 2020-07-16 at 3.37.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/32281ddc-19c1-4aba-b16c-105ade33a9f8.png">

公式( [Databases and the Doctrine ORM (Symfony Docs)](https://symfony.com/doc/current/doctrine.html) )の通りにEntityを作成してみて、接続できる確認してみる

```console
$ docker-compose exec php php bin/console make:entity

 Class name of the entity to create or update (e.g. GrumpyJellybean):
 > Product

 created: src/Entity/Product.php
 created: src/Repository/ProductRepository.php

 Entity generated! Now let's add some fields!
 You can always add more fields later manually or by re-running this command.

 New property name (press <return> to stop adding fields):
 > name

 Field type (enter ? to see all types) [string]:
 > string

 Field length [255]:
 > 255 

 Can this field be null in the database (nullable) (yes/no) [no]:
 > no

 updated: src/Entity/Product.php

 Add another property? Enter the property name (or press <return> to stop adding fields):
 > price

 Field type (enter ? to see all types) [string]:
 > integer

 Can this field be null in the database (nullable) (yes/no) [no]:
 > no

 updated: src/Entity/Product.php

 Add another property? Enter the property name (or press <return> to stop adding fields):
 > 



  Success! 


 Next: When you're ready, create a migration with php bin/console make:migration
```

↑ `src/Entity/Product.php` と `src/Repository/ProductRepository.php` が作成される

```console
$ docker-compose exec php php bin/console make:migration #migrationファイル作成


           
  Success! 
           

 Next: Review the new migration "migrations/Version20200715184046.php"
 Then: Run the migration with php bin/console doctrine:migrations:migrate
 See https://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html
```

↑ `migrations/Version20200715184046.php` が作成される

```console
$ docker-compose exec php php bin/console doctrine:migrations:migrate #migration実行

 WARNING! You are about to execute a database migration that could result in schema changes and data loss. Are you sure you wish to continue? (yes/no) [yes]:
 > yes

[notice] Migrating up to DoctrineMigrations\Version20200715184046
[notice] finished in 266.3ms, used 18M memory, 1 migrations executed, 1 sql queries
```

↑ マイグレーションが実行された

ProductController修正を修正する

```diff:src/Controller/ProductController.php
  <?php
  namespace App\Controller;


+ use App\Entity\Product;
  use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  use Symfony\Component\Routing\Annotation\Route;

  class ProductController extends AbstractController
  {
    /**
     * @Route("/product", name="product")
     */
     public function index()
     {
+        // 保存
+        $entityManager = $this->getDoctrine()->getManager();
+        $product = new Product();
+        $product->setName('Keyboard');
+        $product->setPrice(1999);
+        $entityManager->persist($product);
+        $entityManager->flush();
+
+        // 取得
+        $id = 1;
+        $product = $this->getDoctrine()
+            ->getRepository(Product::class)
+            ->find($id);
+        if (!$product) {
+            throw $this->createNotFoundException(
+                'No product found for id '.$id
+            );
+        }
+        dd($product);

         return $this->render('product/index.html.twig', [
             'controller_name' => 'ProductController',
         ]);
     }
```

データベースからデータが取れたことを確認

<img width="339" alt="Screen Shot 2020-07-16 at 3.45.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142910/36ca31ff-abe4-d152-a6cd-92fef3b5c6a2.png">

最後まで見ていただいてありがとうございましたm(_ _)m

---



参考

- [Docker に Composer をインストールするベストプラクティス（と解説） - Qiita](https://qiita.com/yatsubashi/items/02bbbebbfe7e5a5976bc)
- [docker-php-ext-install zip fails #61](https://github.com/docker-library/php/issues/61)