LoginSignup
2
2

More than 1 year has passed since last update.

【初心者向け】LaravelでYoutubeのお気に入りCuration(まとめ)アプリを作る【第1回: Docker環境構築】

Last updated at Posted at 2021-09-28

こんにちは。
ITエンジニアの濱辺(ハマベ)です。

今回は、勉強兼、ポートフォリオ作成のため、お気に入りの動画を共有できる、SNSのようなアプリを作っていきます。

↓コードはこちら(現在は制作途中)
GitHubリンク

前提条件

  • MacOS 11.2
  • PHP 7.4.2
  • Laravel 6.20.34
  • Docker
  • MySQL

はじめに、画面定義所を作成!

まず、完成イメージを固めるところから。

↓画面定義書のリンク
Youtube-Curation 画面定義所 (googleスプレッドシート)

スクリーンショット 2021-09-26 11.08.10.png

先にイメージを作成しておくことで、何を実装すれば良いのか、ハッキリさせる狙いです。ゴールを決めるのは大事!

今回は、そこまで複雑なアプリでは無いので、イメージを用意するだけに留めましたが、大規模なアプリなら、処理を言語化したフローチャートを作成するべきかも知れません。

Docker環境構築

環境構築からやっていきます。

↓参考ページ
【超入門】20分でLaravel開発環境を爆速構築するDockerハンズオン

作業ディレクトリを作成

この中にアプリを設置します。

% mkdir Youtube-Curation
% cd Youtube-Curation

GitHubにて、リモートリポジトリ作成

スクリーンショット 2021-09-26 12.37.07.png

今回は、リポジトリ名「Youtube-Curation」としました。
アプリ名と同じにすると良し。

GitHubに初回コミット&プッシュ

% echo "# Youtube-Curation" >> README.md
% git init
% git add README.md
% git commit -m "first commit"
% git branch -M main

リポートリポジトリを登録

% git remote add origin git@github.com:hamabehayato/Youtube-Curation.git

※↑git@github~ 以降は自分のリモートリポジトリに合わせて置き換えてください。

正しく設定できているか確認してください。

% git remote -v                                                 [main]
origin  git@github.com:hamabehayato/Youtube-Curation.git (fetch)
origin  git@github.com:hamabehayato/Youtube-Curation.git (push)

# もしリモートリポジトリ先を間違えた場合は下記のコマンドから変更できます。
$ git remote set-url origin <リモートリポジトリ>

GitHubへPushする

git push -u origin main
  • -u オプションは --set-upstream の省略
    • 以降は git push だけで git push origin main と同義

テキストエディタで開く

今回はVSC(Visual Studio Code)を使用。
設定によっては、下記コマンドで開ける。

$ code .

スクリーンショット 2021-09-26 13.37.08.png

アプリケーションサーバ(app)コンテナを作る

正直に言って、ここから先はまだあまり理解できておりません。
なので、詳しく知りたい方は参考元のサイトをご参照ください。
ここには、最低限、使用したコードのみ書いていきます。

設定ファイルを作成

$ touch docker-compose.yml

作成したdocker-compose.ymlに下記を記述

version: "3.9"
services:
  app:
    build: ./infra/php
    volumes:
      - ./backend:/work

Dockerファイルのバージョンを3.9とする。
appはサービス名(任意)
buildは、ここにDockerfileを設置しますという宣言
volumesは、「ホスト側のディレクトリや名前付きボリュームをコンテナ側へマウントしたい時に指定します。」とのこと。まだうまく理解できません。

./docker/php/Dockerfile を作成する

$ mkdir -p infra/php
$ touch infra/php/Dockerfile

作成した「Dockerfile」に下記をコピー

FROM php:8.0-fpm-buster
SHELL ["/bin/bash", "-oeux", "pipefail", "-c"]

ENV COMPOSER_ALLOW_SUPERUSER=1 \
  COMPOSER_HOME=/composer

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

RUN apt-get update && \
  apt-get -y install git unzip libzip-dev libicu-dev libonig-dev && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* && \
  docker-php-ext-install intl pdo_mysql zip bcmath

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

WORKDIR /work

ここの理解は後回しとします。

./docker/php/php.ini を作成する

php.iniは設定ファイル

  • PHPエラーメッセージの設定
  • PHPエラーログの設定
  • メモリ等の設定(お好みで)
  • タイムゾーン設定
  • 文字コード設定

などを行なっているらしい。

$ touch infra/php/php.ini

php.iniに下記をコピー

php.ini
zend.exception_ignore_args = off
expose_php = on
max_execution_time = 30
max_input_vars = 1000
upload_max_filesize = 64M
post_max_size = 128M
memory_limit = 256M
error_reporting = E_ALL
display_errors = on
display_startup_errors = on
log_errors = on
error_log = /dev/stderr
default_charset = UTF-8

[Date]
date.timezone = Asia/Tokyo

[mysqlnd]
mysqlnd.collect_memory_statistics = on

[Assertion]
zend.assertions = 1

[mbstring]
mbstring.language = Japanese

ちゃんと読めば、どこが何を設定してるのかはなんとなく分かりますね。

backend ディレクトリを作成

bindマウントするためのbackendディレクトリを作成する、らしいです。

bindマウントとは

$ mkdir backend

build & up

  • appコンテナの作成
  • PHPのバージョン確認
  • Laravelで必要なPHP拡張機能の確認

ここで、コンテナを作成(実際に仮想環境の作成)をします。

$ docker compose up -d --build

コンテナが立ち上がったか確認

% docker compose ps
NAME                     SERVICE             STATE               PORTS
youtube-curation_app_1   app                 running             9000/tcp

appコンテナに入る

docker-compose exec app bash

なぜか、docker compose exec app bashでは失敗してしまった。
ハイフンをつけたら無事に入れたので、良しとします。

コンテナ内の要素の各種バージョン確認

# PHPバージョン確認
# php -v
PHP 8.0.11 (cli) (built: Sep 23 2021 19:57:06) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.11, Copyright (c) Zend Technologies

# Composerバージョン確認
# composer -V
Composer version 2.0.14 2021-05-21 17:03:37

# インストール済みプラグイン一覧確認
# php -m
[PHP Modules]
bcmath
Core
ctype
curl
date
dom
fileinfo
filter
ftp
hash
iconv
intl
json
libxml
mbstring
mysqlnd
openssl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
readline
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zip
zlib

[Zend Modules]

exit でコンテナから出ます。
control + d でも可

# exit

コンテナを破棄する

docker-compose.yml を変更するので、一度コンテナを破棄します。

$ docker compose down

ウェブサーバー(web)コンテナを作る

もうここからは完全に受け売りです。
作成後、動画や本でDockerについて勉強します。

docker-compose.yml に追記

version: "3.9"
services:
  app:
    build: ./infra/php
    volumes:
      - ./backend:/work

  # 追記
  web:
    image: nginx:1.20-alpine
    ports:
      - 8080:80
    volumes:
      - ./backend:/work
      - ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf
    working_dir: /work

nginx ver1.2の、ports8080:80を使用。構成は./backend:/workを参照。といったところでしょうか。予想です。

app コンテナの設定と同じインデント(スペースの深さ)で貼り付けます。
なんでも、docker.ymlファイルは、インデントに意味を持っているとか。ズレると設定が上手くいかないってことですね。

docker/nginx/default.conf を作成する

nginxの設定ファイルを作成します。
nginxとは

$ mkdir infra/nginx
$ touch infra/nginx/default.conf

default.confに下記をコピー

default.conf
server {
    listen 80;
    server_name example.com;
    root /work/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

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

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

build&up (コンテナを立ち上げる)

$ docker compose up -d

立ち上がったコンテナを確認

% docker compose ps
The new 'docker compose' command is currently experimental. To provide feedback or request new features please open issues at https://github.com/docker/compose-cli
NAME                     SERVICE             STATE               PORTS
youtube-curation_app_1   app                 running             9000/tcp
youtube-curation_web_1   web                 running             0.0.0.0:8080->80/tcp

nginx のバージョン確認

% docker-compose exec web nginx -v
nginx version: nginx/1.20.1

docker compose だと、Dockerのバージョンが表示されました。なぜ…?

webコンテナ動作確認

$ mkdir backend/public
$ echo "Hello World" > backend/public/index.html
$ echo "<?php phpinfo();" > backend/public/phpinfo.php

上記でやっていることは、

  1. backend/publicフォルダを作る
  2. その中に"Hwllo World"とだけ書かれたindex.htmlファイルを作る
  3. さらに、"<?php phpinfo(); >"と記述されたphpinfo.phpファイルを作る

ですね。

以下にアクセスしてみましょう。

http://127.0.0.1:8080/index.html
http://127.0.0.1:8080/phpinfo.php

すると、このように表示されるはずです。

スクリーンショット 2021-09-27 15.00.04.png

スクリーンショット 2021-09-27 15.02.19.png

今作成したファイルはあくまで動作確認用なので、消去しておきましょう。

% rm -rf backend/*

git commit

さて、無事にwebコンテナが動作することが確認できましたので、
gitにcommit しておきましょう。

% git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   docker-compose.yml
    modified:   infra/php/Dockerfile

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    infra/nginx/default.conf

% git add .
% git status                                         ![main]
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   docker-compose.yml
    new file:   infra/nginx/default.conf
    new file:   infra/php/Dockerfile
    new file:   infra/php/php.ini

% git commit -m "feat create docker web container"   ![main]
[main 9382a77] feat create docker web container
 4 files changed, 89 insertions(+)
 create mode 100644 docker-compose.yml
 create mode 100644 infra/nginx/default.conf
 create mode 100644 infra/php/Dockerfile
 create mode 100644 infra/php/php.ini

% git log

Laravel をインストール

  1. コンテナに入る
  2. Laravelをインストール
  3. Laravelのバージョン確認
  4. コンテナを出る
# docker compose exec app bash
# composer create-project --prefer-dist "laravel/laravel=6.*"
# php artisan -V
Laravel Framework 6.20.34
# exit

composer create ~ を実行したときに、work/. is not emptyというエラーが出ました。

ls -laでworkディレクトリを見てみると、謎の.DS_Storeファイルが。
消去して再実行で無事にLaravelインストール出来ました。

上手くいけば、下記にアクセスで画像と同じ画面が表示されます。

↓アクセス!
http://127.0.0.1:8080/

スクリーンショット 2021-09-27 16.41.30.png

gitにcommit

無事にLaravelのウェルカム画面を表示できたので、ここまでをcommitしておきます。

% git status
% git add .
% git status
% git commit -m "feat laravel install"
% git log

コンテナを破棄

docker-compose.ymlをいじるので、一旦コンテナを破棄します。

% docker compose down

データベース(db)コンテナを作る

MySQLデータベースコンテナを作成します。

docker-compose.ymlに追記します。

docker-compose.yml
version: "3.9"
services:
  app:
    build: ./infra/php
    volumes:
      - ./backend:/work

  web:
    image: nginx:1.20-alpine
    ports:
      - 8080:80
    volumes:
      - ./backend:/work
      - ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf
    working_dir: /work

  # 追記
  db:
    build: ./infra/mysql
    volumes:
      - db-store:/var/lib/mysql

volumes:
  db-store:

./docker/mysql/Dockerfile を作成する

dbコンテナの設定ファイルを作成します。

% mkdir infra/mysql
% touch infra/mysql/Dockerfile

mysql/Dockerfile に下記を記述

FROM mysql/mysql-server:8.0

ENV MYSQL_DATABASE=laravel_local \
  MYSQL_USER=phper \
  MYSQL_PASSWORD=secret \
  MYSQL_ROOT_PASSWORD=secret \
  TZ=Asia/Tokyo

COPY ./my.cnf /etc/my.cnf
RUN chmod 644 /etc/my.cnf

docker/mysql/my.cnf を作成する

mySQLの設定ファイルを作成します。

  • 文字コードの設定
  • タイムゾーンの設定
  • ログ設定
% touch infra/mysql/my.cnf

my.cnfに下記を記述

my.cnf
[mysqld]
# default
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

pid-file=/var/run/mysqld/mysqld.pid

# character set / collation
character_set_server = utf8mb4
collation_server = utf8mb4_ja_0900_as_cs_ks

# timezone
default-time-zone = SYSTEM
log_timestamps = SYSTEM

# Error Log
log-error = mysql-error.log

# Slow Query Log
slow_query_log = 1
slow_query_log_file = mysql-slow.log
long_query_time = 1.0
log_queries_not_using_indexes = 0

# General Log
general_log = 1
general_log_file = mysql-general.log

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4

dbコンテナ立ち上げ

% docker-compose up -d
% docker compose ps
The new 'docker compose' command is currently experimental. To provide feedback or request new features please open issues at https://github.com/docker/compose-cli
NAME                     SERVICE             STATE               PORTS
youtube-curation_app_1   app                 running             9000/tcp
youtube-curation_db_1    db                  running             3306/tcp, 33060/tcp, 33061/tcp
youtube-curation_web_1   web                 running             0.0.0.0:8080->80/tcp

マイグレーション実行(エラーします)

ここでマイグレーションが可能か試します。

% docker-compose exec app bash
# php artisan migrate

   Illuminate\Database\QueryException  : SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE')

~以下略

SQLSTATE[HY000] [2002] Connection refusedはSQL接続エラー。接続設定が間違っている可能性が高いです。

backend/.env のDB接続設定を下記に修正しましょう。

backend/.env
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel_local
DB_USERNAME=phper
DB_PASSWORD=secret

backend/.env.example も同様に修正しておきます。

backend/.env.ecample
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel_local
DB_USERNAME=phper
DB_PASSWORD=secret

マイグレーション再実行

コンテナの中に入り、マイグレーションします。
今度は成功するはずです。

# php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.05 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.04 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.02 seconds)

成功です!

試しにユーザ登録してみる

コンテナ内で下記を実行します。

# php artisan tinker
>>> $user = new App\User();
=> App\User {#3309}
>>> $user->name = 'phper';
=> "phper"
>>> $user->email = 'phper@example.com';
=> "phper@example.com"
>>> $user->password = Hash::make('secret');
=> "$2y$10$5bakPOgMEimSXMFHvpUog.xOnVx54csBc2FjH7VOGhrayMQuQiSFC"
>>> $user->save();
=> true

dbコンテナに入り、ユーザが登録されているか確認します。

% docker-compose exec db bash
# mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE
mysql> SELECT * FROM users;
+----+-------+-------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
| id | name  | email             | email_verified_at | password                                                     | remember_token | created_at          | updated_at          |
+----+-------+-------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
|  1 | phper | phper@example.com | NULL              | $2y$10$5bakPOgMEimSXMFHvpUog.xOnVx54csBc2FjH7VOGhrayMQuQiSFC | NULL           | 2021-09-28 03:14:14 | 2021-09-28 03:14:14 |
+----+-------+-------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
1 row in set (0.01 sec)

GitHubにcommit

dbコンテナの動作確認ができましたので、一旦commitしましょう。

% git status
% git add .
% git status
% git commit -m "feat create docker db container"
% git log

git push

必要なコンテナ3つが揃ったので、pushしましょう。

% git push

Docker環境を再構築してみる

Docker環境を破棄して、GitHubからインストールし再構成してみます。
これが出来れば、失敗しても何度だって同じ環境を構築して開発ができます。心強い!

Docker環境の破棄

% docker-compose down --rmi all --volumes --remove-orphans

コンテナの停止、ネットワーク・名前付きボリューム・コンテナイメージ、未定義コンテナを削除

だそうです。
これをやれば、Docker環境をクリアできる、って認識で良さげですかね😅

作業ディレクトリを削除

今まで作っていたYoutube-Curationフォルダをまるっと削除します。
ちょい緊張ですね…。ちゃんと戻せるでしょうか。

% cd ..
% rm -rf Youtube-Curation

環境の再構築

GitHubからクローンしてきます。
下記コードは自身のリポジトリに一部置き換えて使用しましょう。

% git clone git@github.com:hamabehayato/Docker-Youtube-Curation.git
% ls                                                      
Docker-Youtube-Curation
% cd Docker-Youtube-Curation
% docker compose up -d --build

よし、コピーできたしコンテナも立ち上がった!
http://127.0.0.1:8080/にアクセスすれば、welcome画面が表示されるはず。

と思ったのですが、下記のようなエラーが…。

スクリーンショット 2021-09-28 14.20.00.png

Warning: require(/work/public/../vendor/autoload.php): Failed to open stream: No such file or directory in /work/public/index.php on line 24

Fatal error: Uncaught Error: Failed opening required '/work/public/../vendor/autoload.php' (include_path='.:/usr/local/lib/php') in /work/public/index.php:24 Stack trace: #0 {main} thrown in /work/public/index.php on line 24

とりあえず、index.phpの24行目を見てみます。

require __DIR__.'/../vendor/autoload.php';

ふむ、autoload.phpというファイルがない、と。
そこまで分かれば、ググって何とかなります。

調べたところ、composerをインストールしていないから、autoload.phpファイルがないらしいです。

ならば、Laravelをインストールしたフォルダに移動し、composerをインストールすれば良し!(のはず)

% cd backend
% composer install

これで大丈夫なはず。

スクリーンショット 2021-09-28 14.36.34.png

500エラー。
サーバのエラーであることは確かなので、サーバ設定がおかしいのだと思われます。

調べたら、.envファイルがそもそも無いですね。
そこはクローンできないのですね。

.env.exampleはあるので、これをコピーすれば良いでしょう。

% cp .env.example .env

スクリーンショット 2021-09-28 14.41.49.png

あれ、まだダメでした。
Your app key is missingなので、App key がないらしいですね。

.envにそんな設定項目があった気がします。
ググります。

下記のコマンドで、app keyを生成できます。

% php artisan key:generate

その他、必要な処理をしていきます。

% php artisan storage:link

システムで生成したファイル等をブラウザからアクセスできるよう公開するためにシンボリックリンクを張っているそうです。
シンボリックリンクとは?

% chmod -R 777 storage bootstrap/cache

storage, bootstrap/cache はフレームワークからファイル書き込みが発生するので、書き込み権限を与える必要があるそうです。
これは単純にbootstrap/cacheの権限を変えているってことで良さそう。

スクリーンショット 2021-09-28 14.48.55.png

無事表示。イェイ!🎉

マイグレーションします。

# php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.05 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.04 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.03 seconds)

無事通りました。完璧です。

第1回おわり

思ったより長くなったので、ここまでを「環境構築編」として区切ります。
第2回からは、Laravelアプリを実際に作っていきます。楽しみ!😄

↓第2回はこちら
LaravelでYoutubeのお気に入りCuration(まとめ)アプリを作る【第2回】

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2