CakePHP5入門【CakePHP5応用編⑩】テストとデプロイ

A子



B美
まぁまぁかな?

C菜

B美

A子
そんなとこまでやらなきゃダメ?

B美
(どこで不具合が発生するか分からないし…)

C菜

A子
それはともかく、B美の提示したテスト項目(No.27~No.32)をやってみよう

A子
(なにしろ、3種類の画像フォーマットごとに4通りのサイズの画像を作ったからね…全12個)
んで、結果はこうだったよ
(クリックすると別ウィンドウで開きます)













C菜
これって何か対策を考えないと…ですね~

A子
画像サイズが小さいときは、拡大表示せずにオリジナルサイズで表示したいところ…

B美
CSSの「object-fit」の値を「contain」から「scale-down」に変えるだけね


C菜
簡単に修正できました~


B美
「削除した投稿に画像が存在した場合、その画像へのアクセスを禁止する」には?

A子

C菜
でも「削除フラグを立てる」方法では、あとで復活させる可能性もありますよ~?

A子
今は「投稿番号.拡張子」だけど、「投稿番号.拡張子.bak」って感じで…

B美
(ダウンロード後にファイル末尾の「.bak」を削除すれば、画像ファイルとして復活することになるわね)

A子
一般ユーザがアクセスできない場所へ…

B美
隔離領域となるそのディレクトリのパーミッション設定とか、ちょっと面倒くさい作業が必要になるけど…(苦笑)

C菜
それを応用して、20文字くらいのランダムな文字列をファイル名の前半にくっつけるというのはどうでしょう~?
元のファイル名が「29.jpg」だったら「xxxxxxxxxxxxxxxxxxxx_____29.jpg」って感じにするんです~
(「xxxxxxxxxxxxxxxxxxxx」の部分はランダムな感じで…)

A子
ランダム文字列を簡単に作れるのかどうか知らんけど…

B美
候補 | 概要 | メリット | デメリット |
---|---|---|---|
「A子」案 | 画像ファイルを一般ユーザがアクセスできないディレクトリへ移動する | セキュリティは完璧 | ディレクトリのオーナーやパーミッションを設定するのが面倒くさい |
「C菜」案 | ファイル名に推測されにくいランダム文字列を付加する | 処理は簡単 | 絶対にアクセスされないという保証はない |
…って感じかな

A子
簡単に実現できるほうが良いからね

B美
だったらChatGPTを使っても良いから、あなたたちで「やってみなはれ」

A子

C菜

A子
まずはランダム文字列を生成するメソッドだね
(「PostsController.php」の中に記述)
private function generateRandomString($length = 20) {
return substr(bin2hex(random_bytes($length)), 0, $length); } |
ChatGPTに教えてもらった関数の先頭に「private」を付けただけなんだけどね

C菜
(赤字の部分が追加した箇所です~)
public function delete($id = null)
{ $post = $this->Posts->get($id); //画像があればリネームする if ($post->filepath != '' && file_exists($post->filepath)) { $filename = basename($post->filepath); $newfilepath = ".".DS."files".DS.$this->generateRandomString()."_____".$filename; rename($post->filepath, $newfilepath); } //削除フラグを立てる $post->delete_flag = 1; if ($this->Posts->save($post)) { $this->Flash->success('投稿の削除に成功しました。'); } else { $this->Flash->error('投稿の削除に失敗しました。'); } return $this->redirect(['action' => 'index']); } |
テストした結果もバッチリでしたよ~


A子
ちょっと焦ったよ(苦笑)
ま、とりあえずテスト仕様書のほうは対応済みに変更しといたから…
(クリックすると別ウィンドウで開きます)

B美
さて、それじゃいよいよ最後の作業ね
本番環境(我が社のWebサーバ)にこのWebアプリを設置するよ

C菜

A子
…って何なのさ

B美
あ、でもうちのサーバって、FTPサーバは稼働させてないのよ

C菜

B美
もちろんHTTP(またはHTTPS)でもファイルのアップロードはできるんだけど、一度にアップできるファイル数やファイルサイズに制限がかかるから、こういう作業には向いてないのよね

A子

B美
(いわゆるSCPね)

A子
いや、ちょっと待って
SSHってのはなんか聞き覚えがあるような?

C菜
(開発環境構築編①を参照)


A子
(無視してたけど…)

B美
(CUI操作しかできないけどね)
SCPというのはSecure Copy Protocolの頭文字をとったもので、SSHを利用してファイルを転送するプロトコルのことよ

C菜

B美
あ、SSHサーバって、この開発環境にはインストールしただけで、特に設定作業なんかはしなかったけどさー
(インターネット上に公開する)外部のサーバ上で使う場合は、必ず次の2点を設定するようにね
①秘密鍵を設定すること
②ポート番号を22以外にすること |
SSHってユーザ名とパスワードでログインするんだけど、総当たり攻撃なんかでパスワードを破られちゃう可能性もあるからね
(秘密鍵を設定しておけば、その鍵を盗まれない限り絶対にアクセスできないのよ)
あと、22番ポートを開いておくと、やたらめったら不正アクセスしようとする奴らがやってくるからね(特に海外から)
(それがめっちゃウザイ(笑))

C菜

A子
あくまでもサーバ管理者に対する注意事項でしょ?

B美
ただ、SSHコマンドやSCPコマンドを使用する際、秘密鍵を指定したり、ポート番号を指定しないといけないってことを言いたかっただけ…
というわけで、これが秘密鍵となるファイルよ
USBメモリにコピーしといたから、あなたたちのPCにコピーしておいてね

C菜
あ、でもコピーする先のディレクトリはどこでも良いんですか~?

B美
あなたたちのユーザホームの中に隠しディレクトリである「.ssh」というのがあるから、その中にコピーしてね
(メニューの「表示」→「隠しファイルを表示する」を選択)
あと、コピーしたファイルのパーミッションを「600」に変更すること

↓


A子
それってコマンド操作で設定するの?

B美
「MATE端末」を開いて、こう入力してね
cd .ssh[Enter]
chmod 600 sakura.pem[Enter] |
あ、鍵ファイルのファイル名が「sakura.pem」の場合であって、ファイル名を変更しているならそのファイル名を指定するようにしてね


C菜
確認は
ls -l[Enter] |
で良いですか~?

B美
鍵ファイルの左端の表示が「-rw-------」となっていたらOKよ


B美
あ、パスワード(パスフレーズ)を聞かれたら「xxxxxxxx」と入力してね
(「xxxxxxxx」はもちろん伏字です)
cd[Enter]
ssh -i .ssh/sakura.pem -p nnnn xxxx@friction-river.jp[Enter] |
「-i」オプションは秘密鍵指定、「-p」オプションはポート番号指定よ(指定しなければ、デフォルトの22番ポートとなります)
(「nnnn」の箇所については本来数字ですが、当然秘密です)
あ、接続先については「ユーザ名@ドメイン名」という形で指定するからね
(上記の「xxxx」の部分はユーザ名ですが、伏字にしています)


A子
なんか怖いね

C菜
SSH接続のためだったんですね~?

B美
コマンド操作(CUI操作)というのは、Web系プログラマにとっては必須知識だからね
(データベースを作ったり、操作したりもCUIで行うしね)
おっと、接続確認できたら
exit[Enter] |
を叩いて、すぐにログアウトしておいてね
(使わないのに、接続しっぱなしはダメよ)

A子
やっぱりコマンドでやるの?

B美
「MATE端末」を開いて、rootになったあと、aptでインストールしてね
su -[Enter]
apt install -y gftp[Enter] |

↓


C菜


B美
ちなみに「このランチャをデスクトップへ追加」を選んで、デスクトップ上にショートカットを作っておいても良いかもね
(今後よく使うことになるから…)


A子

B美
で、まずは下準備だけど、上にあるメニューの「gFTP」→「Preferences...」を選択します
タブの右端「SSH」をクリックしてから二ヶ所の入力欄を埋めてね
SSHプログラム名:ssh
SSH引数:-i .ssh/sakura.pem |

↓


C菜
んで、最後に「OK」ボタンを押せば良いんですよね~?

A子
あとはメイン画面の上にある「Host」「ポート番号」「User」「Pass」の欄に入力していけば良いのかな?

B美
Host:friction-river.jp(ドメイン名またはIPアドレスを入力)
ポート番号:nnnn(伏字です) User:xxxx(ユーザ名…伏字です) Pass:xxxxxxxx(パスワード…伏字です) Passの右側:SSH2(FTPではありません) |
を入力した後、Hostの左側にあるアイコンをクリックしてね
(このアイコンによって接続・切断を行います)


C菜
これって、左側がこのPC内の一覧で、右側がVPSサーバ内の一覧なんですよね~?

B美
接続確認できたら、Hostの左側にあるアイコンをもう一度クリックしてね
(接続が切れるから…)

A子

B美
ちょっと準備してからね
「MATE端末」を開いて、次のコマンドを実行します
mysqldump -u root -p bbsdb > bbsdb_backup.sql[Enter] |
これはデータベースをバックアップするためのコマンドよ


A子

B美
同じディレクトリ内に「bbsdb_backup.sql」というファイルができてるはずだから、それをエディターで開いてね


B美
で、そのあと、一番上に次の二行を追加してね
create database bbsdb;
use bbsdb; |
あ、各テーブル定義の末尾にある「AUTO_INCREMENT=○○」という箇所は削除してちょうだい
全て終わったら「保存」(上書きでOK)してね



C菜

B美
あれによってテーブルが二つほど自動作成されたってわけ
(本番環境で同じことをやっても良いんだけど、面倒くさいからここに全部まとめちゃえ…って意図です)

A子
さて、これでもう準備はOK?

B美
「MATE端末」上で以下のコマンドを実行してね
cd html/bbsapp[Enter]
bin/cake cache clear_all[Enter] |
これにより「bbsapp/tmp」ディレクトリ内に作られたキャッシュファイルが全て削除されるの


C菜

B美
削除せずにアップロードした場合、本番環境側でわざわざchownコマンドを実行して、所有者をWebサーバ(www-data)にしなきゃいけなくなるからね
(ただ単に面倒くさい…ってだけ(苦笑))
さて、これで準備完了よ

A子
アップロードしよう!

B美
(ユーザ名である「xxxx」の箇所は伏字です)
①右側では「html」ディレクトリをダブルクリックして、カレントを「/home/xxxx/html」にする
②左側で「bbsapp」ディレクトリを選択してから、真ん中にある「→」アイコンをクリックする
という手順よ


C菜
あ、さっき作った「bbsdb_backup.sql」もアップロードするんですよね~?

B美
ただし「/home/xxxx/html」ではなく、一階層上の「/home/xxxx」ディレクトリにアップしてね
(ユーザ名である「xxxx」の箇所は伏字です)
おっと、ディレクトリ階層を一段上がるには、「..」をダブルクリックすれば良いから…


B美
んじゃ次は、SSH接続でコマンド操作をやります
さっきやったから覚えてるわよね?

C菜
ssh -i .ssh/sakura.pem -p nnnn xxxx@friction-river.jp[Enter] |
でしたよね~?
(「nnnn」と「xxxx」の箇所は伏字です~)


A子

C菜
何気に便利です~

A子
まじか…
…って、ほんとだ
まじで便利じゃん

B美
これはシェルの履歴機能ってやつで、知っておくとめっちゃ便利なのよね
(まぁ、コマンドを打ち込むこと自体が練習になるから、あえて教えなかったんだけど…(苦笑))
ま、それはともかく…
次はデータベースの作成よ
mysql -u root -p < bbsdb_backup.sql[Enter] |
を実行してね
あ、VPSサーバ上で動いているデータベース(MariaDB)のrootパスワードは「xxxxxxxx」よ
(「xxxxxxxx」の箇所は伏字です)

C菜
データベースのrootパスワードがそれってことは、「bbsapp/config/app_local.php」についても書き換えなきゃいけないんじゃ~?

B美
ほかには「bbsapp/config/const.php」の中の管理者パスワードについても、複雑で推測されにくいものに変更したほうが良いかもね
(別に強制じゃないけど…)
あ、ファイルの編集については「nano」でも「vi」でも好きなエディターソフトを使ってね
(「vi」の説明をやってないけど…)

A子
もうブラウザからアクセスしても良いの?

B美
最も重要なパーミッション設定が残ってるわ
…と言いたいところなんだけど、実はパーミッション設定は不要なの
なぜならアップロード時にパーミッション設定ごと、VPSサーバ側にコピーしたからね
(これがLinux環境で開発して、そのままLinuxサーバへアップロードするときのメリットね)
ただし、これだけはやっておいて
cd[Enter]
cd html/bbsapp/logs[Enter] ls[Enter] rm -f error.log[Enter] cd ../webroot/files[Enter] ls[Enter] rm -f *[Enter] |
もともと「error.log」の所有者はWebサーバ(www-data)なんだけど、アップロード時には一般ユーザに変更されちゃうの
(ファイルを削除しちゃえば、新たに「error.log」が作られるときの所有者は自動的にWebサーバになるからね)
あと、開発環境でテスト投稿した画像ファイルについても、全て削除しておかないといけないわ
(「rm」はリムーブの略で、ファイルを削除するコマンドよ)

A子

B美
特に「rm -f *」を叩くと、問答無用でそのディレクトリ内の全てのファイルを削除するわよ
(しかもゴミ箱行きじゃなく、完全に削除されちゃう)
だから「rm」するときは必ず「ls」で事前確認するように!

C菜
もしもWindowsからアップロードするときは、どうやるんですか~?

B美
ただし、パーミッション設定については、別途手動で行わないといけなくなるの
その場合、どこを変更するのかを一応書いておくわね
(右側の数値がパーミッションの値)
①bbsapp/bin/cake → 755
②bbsapp/logs → 757 ③bbsapp/tmp → 757 ④bbsapp/tmp/cache → 757 ⑤bbsapp/tmp/cache/models → 757 ⑥bbsapp/tmp/cache/persistent → 757 ⑦bbsapp/tmp/cache/views → 757 ⑧bbsapp/tmp/sessions → 757 ⑨bbsapp/tmp/test → 757 ⑩bbsapp/webroot/files → 757 |

A子
面倒くさそう…(苦笑)

B美
さて、それじゃブラウザからアクセスしてみましょうか
URLは「https://friction-river.jp/bbsapp」よ
(クリックすると別ウィンドウで開きます)


C菜

↓


A子
画像をクリックすると、別ウィンドウにオリジナルサイズで表示できるのも確認したよ

C菜

B美
それを「運用テスト」と呼びます
データベースやパーミッション設定関連で不具合が出る可能性もあるからね
設置後は、必ず「運用テスト」を実施するように!

A子
(クリックすると別ウィンドウで開きます)
あ、No.33~No.35のテスト項目を追加したからね
てかさぁ
テストのために投稿や削除を繰り返すと、データベースがなんか汚くなっていくんだけど…(苦笑)
特に「投稿番号」がどんどん大きくなっていっちゃうのは、なんとかならないの?

B美
ヒントとしては「データベースの削除」は、「drop database (データベース名);[Enter]」よ

C菜

A子
だとしたら、本番環境にSSH接続してから
mysql -u root -p[Enter] |
drop database bbsdb;[Enter]
quit;[Enter] |
mysql -u root -p < bbsdb_backup.sql[Enter] |


C菜
cd html/bbsapp/webroot/files[Enter]
ls[Enter] rm -f *[Enter] |
で、どうでしょう~?


B美
もちろんほかのやり方もあるんだけど、その手順が一番シンプルでしょうね

B美
あとは経験を積み重ねていくだけだから、積極的に色々なWebアプリケーションを作っていきなさいね
(経験こそがプログラマにとっての財産だから…)

C菜

A子
「こういうアプリが欲しいな」と思ったときに、(無ければ)自分で作れる…ってのは良いよね

C菜