こんにちは。
ITエンジニアの濱辺(ハマベ)です。
今回は、勉強兼、ポートフォリオ作成のため、お気に入りの動画を共有できる、SNSのようなアプリを作っていきます。
↓コードはこちら(現在は制作途中)
GitHubリンク
前提条件
- MacOS 11.2
- PHP 7.4.2
- Laravel 6.20.34
- Docker
- MySQL
はじめに、画面定義所を作成!
まず、完成イメージを固めるところから。
↓画面定義書のリンク
Youtube-Curation 画面定義所 (googleスプレッドシート)
先にイメージを作成しておくことで、何を実装すれば良いのか、ハッキリさせる狙いです。ゴールを決めるのは大事!
今回は、そこまで複雑なアプリでは無いので、イメージを用意するだけに留めましたが、大規模なアプリなら、処理を言語化したフローチャートを作成するべきかも知れません。
Docker環境構築
環境構築からやっていきます。
↓参考ページ
【超入門】20分でLaravel開発環境を爆速構築するDockerハンズオン
作業ディレクトリを作成
この中にアプリを設置します。
% mkdir Youtube-Curation
% cd Youtube-Curation
GitHubにて、リモートリポジトリ作成
今回は、リポジトリ名「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 .
アプリケーションサーバ(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に下記をコピー
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ディレクトリを作成する、らしいです。
$ 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に下記をコピー
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
上記でやっていることは、
- backend/publicフォルダを作る
- その中に
"Hwllo World"
とだけ書かれたindex.html
ファイルを作る - さらに、
"<?php phpinfo(); >"
と記述されたphpinfo.php
ファイルを作る
ですね。
以下にアクセスしてみましょう。
http://127.0.0.1:8080/index.html
http://127.0.0.1:8080/phpinfo.php
すると、このように表示されるはずです。
今作成したファイルはあくまで動作確認用なので、消去しておきましょう。
% 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 をインストール
- コンテナに入る
- Laravelをインストール
- Laravelのバージョン確認
- コンテナを出る
# 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/
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に追記します。
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に下記を記述
[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接続設定を下記に修正しましょう。
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel_local
DB_USERNAME=phper
DB_PASSWORD=secret
backend/.env.example
も同様に修正しておきます。
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画面が表示されるはず。
と思ったのですが、下記のようなエラーが…。
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
これで大丈夫なはず。
500エラー。
サーバのエラーであることは確かなので、サーバ設定がおかしいのだと思われます。
調べたら、.env
ファイルがそもそも無いですね。
そこはクローンできないのですね。
.env.example
はあるので、これをコピーすれば良いでしょう。
% cp .env.example .env
あれ、まだダメでした。
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の権限を変えているってことで良さそう。
無事表示。イェイ!🎉
マイグレーションします。
# 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アプリを実際に作っていきます。楽しみ!😄