クマのブログ

つまづいたところ、学びを書いていきます

サーバーを立てるソフトウェアを知る

前提

・Windows10

背景

  • 先日「仮想サーバー」について調べた

  • ただ「『サーバーを立てる』という点ではいくつか同じようなサービスがあるよな」、と感じ、どう使い分けるか気になった

調べたこと

先日は主にVagrantVirtualBoxについて調べたので、他のサービスを調べた

Docker

よく見る比較対象。

Vagrantカーネルも含めて仮想環境を作るのに対して

という点が大きな違い

イメージとしては

【Docker】

  • 小さく始める(マイクロサービス)のに向いてる

  • DockerはカーネルはホストOSと共通のモノを使う

  • WindowsPCだと使いにくい(Vagrantで環境構築→Docker環境構築が欲しいところ)

※理由はこちらの記事

XAMPP / MAMP

LAMP環境でサーバー環境を作る」という点では類似(こっちではOSとかまで作るわけではないが、自分自身が区別できていないので、メモ)

ただ、

  • WEBサーバーはNginx、プログラミング言語ではRubyPythonなども使われること

  • プロジェクトごとのバージョン管理が大変(xamppなどでのバージョン管理は不可能に等しい)

  • ホストOS(WindowsMac)によって開発環境が異なると、うまく開発が進まない

  • PC買い直した際の環境構築を0から始めなければいけない

などなどのデメリットを考えると、共同開発を大前提とするプロダクト開発にはxamppやMAMPが向いていないことがわかる。

参考記事

自分が Vagrantで LAMP環境を作る理由

DockerとVagrantの違い

所見

研修内でxampp環境でしか開発したことがない僕に対して、先輩社員がVagrantのことを

「xamppみたいなものだね」

とぼそっと言ってたことを理解しました。

(厳密にいうと、Vagrantを使うとなるとVirtualBoxも使うので、セットで「xamppみたいなもの」なんですね。)

「仮想サーバー」を知る

前提

・Windows10

背景

・いよいよプロジェクトに参画するので環境構築をすることに。

・開発環境はVirtualBoxVagrantで仮想サーバーを立てて開発を進める。

・ただ「仮想サーバー」についてあまり理解していないので、簡単に調べたことをメモ

調べたこと

仮想サーバーとは

一言でいうと

1台のサーバー上で複数のオペレーションシステム(OS)を動かし、複数のサーバーとして運用する仕組み

従来は1サーバーに対して、1つのOSやアプリケーションインストールするのが通例だった。

PCのメモリやCPUの性能向上のおかげで1ハード内に複数のOSを処理やアプリケーションを動かすことができるようになった。

仮想サーバーがないとどうなるのか

1OS、1アプリケーションしか開発することができないので、複数プロジェクト開発には複数のサーバー機能を持つハードウェアが必要になる

物理サーバーとの違い

仮想サーバーの対として、「物理サーバー」がある

物理サーバーとは、物理サーバーそのもののリソースを使うサーバーで、ピーク時を想定した環境構築をするため、余裕を持たせることが多い。

それゆえ、本来使えるはずのサーバーリソースを使わずに無駄が生じることが多い。

メリット

1.導入コストのとリプレースコストの削減

サーバーの追加導入に新しいハード(PCなど)は必要ない

2. 設置スペース減少によるランニングコスト減少

サーバー設置のデータセンター代、電気代、保守運用の人件費

3, サーバー管理の一元化による運用負担軽減
4, 必要な時に必要な分だけリソース追加
5. 冗長化構成

VirtualBoxとは

ホストOSにゲストOSを構築する仮想化するためのソフトウェア

ホストOS:WindowsMac

ゲストOS(=仮想マシン):CentOSUbuntu

Windows環境でLinuxを使えるようにするには必要なソフトウェア

Vagrantとは

(厳密には違うが)簡単に言うと、VirtualBoxCUIで操作するためのソフトウェア

VirtualBoxVagrantの違い

大きな違いは環境構築のハードルの高さ

VirtualBox単体の開発環境だと

  • OSのダウンロード、SSHのインストールなど細かな設定も0からやる必要がある

  • 上記設定を自動化できないため、他社との共有時には膨大な量の手順書が必要になる

一方、Vagrantを使えば、

  • コマンド一つで開発環境が整う

  • 設定情報の共有ができる

  • 環境構築の自動化ができる

などなど、共同開発が大前提のシステム開発に必須といっても過言ではない。

例えば、仮想マシンを構築する際の、OSのバージョン指定、接続IP、ホスト名などなどを全てVagrantfileに格納しておけば全て自動化できる。

※設定の仕方はRubyで書かれている

所見

「なんでvirtualboxVagrantが必要なんだろう?」

と思っていた点が少し理解できました。ただ、

「ただ、サーバを立てるならxamppでもいいのでは?」

という素人疑問もわいたので、そこは別でインプット・アウトプットします。

参考記事

仮想サーバについて

VirtualBoxとVagrantについて

xamppを知る(Apache編)

前提

・Windows10

・xampp8.0.8(PHP8.0.8)

f:id:kuma_kuma0121:20210728090744p:plain

背景

・xamppの処理の流れを知る 「Apache起動編」

・xampp(Apache/MySQL)関連のエラーに苦しめられたくない

参考記事

www.javadrive.jp

調べたこと

Apacheの起動にはhttpd.confを使う

httpd.conf:Apacheの設定ファイル

場所:C:xampp/apache/conf/httpd.conf

httpd.confでできる事

Serverroot

起動時にapacheの場所指定 ※デフォルトは正常に実行できるようになっている

Listen

外部からリクエストを受け付けるポート番号を指定 ※デフォルトは80番。他のサービスで80番を使っていたら要変更。

DocumentRoot

Apacheを使って公開するコンテンツを指定 ※デフォルトはxampp/htdocs

記事にもある通りApache起動時のリクエスト・レスポンスの関係は以下の通り

ex ブラウザからのリクエスhttp://localhost/index.html

クライアントへ返される実際のファイル C:\xampp\htdocs\index.html

所見

Apacheが起動しない原因を特定する一つの要因として、「パスが違う(=ファイル名が違う)」ことも考えられることがわかった。

【PHP】7.4→8.0へのバージョンアップ

前提

  • Windows 10

  • (前)PHP7.4 → (後)PHP8.0

  • 実務経験歴:21/5~

背景

会社でこれから入るプロジェクトがPHP8.0を使っているとのことでしたので、PHP7.4だった自分のPC環境をバージョンアップすることに。

その中でいくつかエラーにつまづいたので、メモ。

事象

結論:PHP8.0への移行時にたくさんエラーが発生

基本的にコチラの記事を参考に進めてみた

前バージョンのxamppファイルのアンインストール、バックアップファイル(apache, htdocs, mysql, php)を移行し終え、いよいよ動作確認。

エラーの事象ごとに書いていく。

1. MySQL起動時、即切断する

よくあるやつですね。以下エラーです。

f:id:kuma_kuma0121:20210727092145p:plain

↓エラー文

Error: MySQL shutdown unexpectedly. This may be due to a blocked port, missing dependencies, improper privileges, a chash, or a shutdown by another method. Press the Logs button to view error logs and check the Windows Event Viewer for more clues

これは想定の範囲内なので、落ち着いてググる

試したこと

1.頻出対応策を実行

blog.senseshare.jp

コチラがいい感じにまとまっていた。

記事にある通り、

  • ポート競合をチェック

  • 前回クラッシュした際の破損ファイルなどが邪魔していないかチェック

  • 設定ファイルの間違え(ログファイルをチェック)

を実行。

他の記事もざっと目を通したが大体この3つの方法で解決していたので、ほぼエラー対策終了、だと思っていた。

結論:3つとも効果なし。

3つ目のログファイルのチェックについては[ERROR]すら出ておらず、正常動作を示す[NOTE]しかなく原因の特定ができなかった、、、

2.PCを再起動

他の記事を漁りまくったが先述の通り、大体先ほどの対応で解決していることが多く、途方に暮れた

根拠はなかったが、一旦PCを再起動してみた。

結論:効果なし。依然としてMySQLは起動直後即切断される

3.MySQLデータを初期化

これは根本的解決にならず、再現性が非常に低いためあまりやりたくなかったが他に手段がなく実行することに

qiita.com

かなり力技だとわかっていながらも、バックアップファイルによる初期化を実施。

結論:まさかの効果なし。

4.mysqlファイルが空っぽ

途方に暮れる中、もう一度基礎に立ち返って、1.の対応に戻ってみた。

するとエラーログに以下表示されていた

①[ERROR] Could not open mysql.plugin table. Some plugins may be not loaded

②[ERROR] Can't open and lock privilege tables: Table 'mysql.servers' doesn't exist

2.までではこのエラーは出てなかった。

3.の力技を実行したことで、エラーが発生する準備ができたのだ、と推測。

①はエラーの原因が"Some plugins"とあり、原因特定が難しそうだったので、後回し。

②をググってみると、この記事に出会った

記事では

The only and best way to properly fix this would be restore the ‘mysql’ database or just the ‘servers’ table from your backup. 要は「唯一の解決策はバックアップファイルから'servers' table を持ってくることです。」とのこと。

5.mysql/data/mysqlに一つもデータがない。

'mysql.servers'が本来あるべき場所を特定

特に気になったのは②エラー文内のこの一文。

Table 'mysql.servers' doesn't exist

mysql.serversテーブルというファイルがあるべき場所にないのかな」

と推測したため、今回新しくインストールしたxampp内で'mysql.servers'を検索。結果は…

f:id:kuma_kuma0121:20210727222856p:plain

やっぱりない。

そして、本来'mysql.servers'がどこあるものかわからないので、バックアップとっていたxampp内で'mysql.servers'を検索すると

C:xampp/mysql/data/mysql

に本来あるものだと知った。

そして、加えて今まで作ったテーブル情報がここに保存してあった。保存形式は↓こんな感じ。

servers.MYI servers.MYD servers.frm

こんな感じの拡張子がテーブルごとに保存されていた。

ファイルが一個もない…

そして、今回インストールしたxamppで指定のルートを確認。結果は…

f:id:kuma_kuma0121:20210727223637p:plain

'mysql.servers'のみならずファイルが一つも入っていない。。。

ということで、バックアップxamppファイルの同じパスにあるファイルを全て今回のxamppにコピー。

その後、MySQLを起動すると、、、

f:id:kuma_kuma0121:20210727224711p:plain

無事起動しました!!!

所感

今回、mysql/data/mysqlにデータが一つもなかった要因については推測ですが

バックアップファイルからちょこちょこファイルをコピーしたり、ファイル消したりしてる中で誤って消したのでしょう。

何よりも、バックアップを取っていてよかった、と心底感じました。

【Laravel8】Factory(Faker)の書き方が前バージョンと違う

前提

Windows 10

・Laravel 8.0

背景

Laravel実践開発を進めていく中で参考書通り進めたがつまづく。 模索した結果、解決したのでメモ

事象

P284「ユニットテスト」をファクトリ使って実施する際、Factoryの定義が8.0になってから変わった。

詳細

書籍はLaravel5.8を前提にしているので、バージョン違いによる記法の違いが生じた。

具体的にはファクトリ―ファイル内でfakerを作る際の記述が異なっていた

↓書籍(5.8)

<?php
use App\Person;
use Faker\Generator as Faker;
​
$factory->define(Person::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'mail' => $faker->email,
        'age' => $faker->numberBetween(1,100),
    ];
});

試したこと

公式のサイトで記法を確認

「こういう基本的な情報は1次情報が一番!」

ということで、日本語版公式サイトを参考に以下の通り記述。

↓自分の環境(8.0)

<?php
​
namespace Database\Factories;
​
use App\Person;
use Illuminate\Database\Eloquent\Factories\Factory;
​
class PersonFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Person::class;
​
    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => $this->faker->name,
            'mail' => $this->faker->safeEmail,
            'age'  => $this->faker->numberBetween(1,100),
        ];
    }
}

結果:正常に動いた!

主な違い

5.8では

  • Factoryクラスからdefineメソッドを使っている

  • defineメソッド内のクロージャでFakerクラスのインスタンスが引数として使われ、Faker生成は

'name' => $faker->name,
'mail' => $faker->email,
'age' => $faker->numberBetween(1,100),

このように書いている。

一方、8.0はFactoryクラスを継承したうえで、definitioinメソッドを利用し、以下のように記述

'name' => $this->faker->name,
'mail' => $this->faker->safeEmail,
'age'  => $this->faker->numberBetween(1,100),

自分のインスタンス($this)からfakerプロパティを経由して生成するfakerへアクセスする必要があるのは手間だが

defineメソッドとdefinitionメソッドではクロージャ関数を使う必要や$Fakerインスタンスを引数にとる必要がなくなった。

所感

・内容自体はすぐ解決した。

・「なぜこの書き方に変わったか?」については上述の

自分のインスタンス($this)からfakerプロパティを経由して生成するfakerへアクセスする必要があるのは手間だが

defineメソッドとdefinitionメソッドではクロージャ関数を使う必要や$Fakerインスタンスを引数にとる必要がなくなった。

より、可読性を意識したことによるものかと推測。

まだ、理解がふわっとしているので、まだまだたくさんLaravelに触れること必要がありそうだ。

参考

Laravel実践開発

【Laravel8.0】キュー・ジョブの処理でのMaximum execution time of 60 seconds exceeded

前提

Windows 10

・Laravel 8.0

背景

Laravel実践開発を進めていく中で参考書通り進めたがつまづく。 模索した結果、解決したのでメモ

事象

P188でキューを非同期で対応させるために、書籍通り進めた。

具体的には

  1. キュー用テーブルの作成
php artisan queue:table
  1. マイグレーション
php artisan migrate
  1. 実行失敗時テーブル作成
php artisan queue:failed-table

の順で実行。

  1. については

A CreateFailedJobsTable class already exists.

というエラーが返ってきたので、マイグレーション不要、と判断。

そして、

「せっかくだしリセットしたい」

という少し謎な判断が働き、

php artisan megrate:fresh

を実行。

(ここで、改めてCreateFailedJobsTableが作成されていることを認識)

  1. .envファイルの修正

以下のように修正

QUEUE_CONNECTION = sync
↓
QUEUE_CONNECTION = database // sync→databaseへ変更

QUEUE_DRIVER = database // 項目ごと追記

5,. ワーカー実行 サーバーを起動しているcmd以外にもう1個cmdを起動し、

php artisan queue:work

を起動

実際のソースコードは以下の通り。

(中略)

public function index(Person $person = null)
{
    if ($person != null)
    {
        MyJob::dispatch($person)->delay(now()->AddMinutes(1));
    }
    $msg = 'show people record.';
    $result = Person::get();
    $data = [
        'input' => '',
        'msg' => $msg,
        'data' => $result,
    ];
    return view('hello.index', $data);
}
use App\Person; 追加

(中略)

class MyJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $person;

    public function __construct(Person $person)
    {
        $this->person = $person;
    }

    public function handle()
    {
        $sufix = ' [+MYJOB]';
        if (strpos($this->person->name, $sufix))
        {
            $this->person->name = str_replace( $sufix, '', $this->person->name);
        } else {
            $this->person->name .= $sufix;
        }
        $this->person->save();
    }
}

エラー発生

これで、指定されたURLにアクセスすればHelloController.php

MyJob::dispatch($person)->delay(now()->AddMinutes(1));

のジョブが1分後に実行される。

実際にアクセスすると

Maximum execution time of 60 seconds exceeded

というエラーが発生。

また、今まで正常にアクセスできたルートまでもアクセスできなくなり、途方に暮れる。

試したこと

一旦元の状態に戻す

一旦態勢を整えるべく.envファイルの設定を元に戻して正常状態に戻そうとした。

QUEUE_CONNECTION = database
↓
QUEUE_CONNECTION = sync  // database→syncへ変更

QUEUE_DRIVER = database // 項目ごと削除

結果:変化なし。解決せず。

エラー原因特定

元に戻せないのはおかしいと思い、次にエラーのあたりを付けるため、storage/logs/laravel.logにてエラーログを確認

local.ERROR: Maximum execution time of 60 seconds exceeded {"exception":"[object] (Symfony\\Component\\ErrorHandler\\Error\\FatalError(code: 0): Maximum execution time of 60 seconds exceeded at C:~\\~\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Connection.php:685)

先ほど、QUEUE_CONNECTION = syncに直したにも関わらず、Databaseへアクセスしようとしている。 これが原因?

cacheによるエラー可能性

.envファイルを変更したため、変更前情報がcacheに保存されており、その情報を自動的に拾ってきていないか確認するため、以下実行。

php artisan cache:clear

結果:変化なし。解決せず。

configによるエラー可能性

では、configは?とダメもとで以下実行。

php artisan config:clear

結果:変化なし。解決せず。

PCをシャットダウン・再起動

ここで集中が切れて、次の日へ持ち越し。

一旦、再起動し、シャットダウン実行。

再度、参考書の通りに実装

次の日に手順の最初から実装し直し。

結果:エラーが出なくなった。

一旦は安心。(ただ、根本的な原因がわからずじまい)

ただ、ここで別の問題が。

ジョブの保存先がdatabaseなので、アクセス時にジョブが一時的にテーブルに保存されなければいけない。

↓これができていない… f:id:kuma_kuma0121:20210723231119p:plain

cacheによるエラー可能性②

再度、以下実行。

php artisan cache:clear

結果:変化なし。解決せず。

configによるエラー可能性②

では、configは?とダメもとで以下実行。

php artisan config:clear

結果:解決。databaseにジョブが保存されるようになった。 f:id:kuma_kuma0121:20210723231239p:plain

所感

・.envファイル、configフォルダ直下のファイルを触ったら残ったcacheやconfigを疑う、というスタンスの定着に1歩近づきました。

・laravel.logを確認することでcmd以上の詳細のエラー情報が確認できるため、必ず確認すべきと実感。

・何よりも最初の

Maximum execution time of 60 seconds exceeded

の要因が特定できなかったことは非常に悔しい点。

参考記事

Laravel実践開発

【Laravel 8.0】laravel auth機能が実装できない

前提

Windows 10

・Laravel 8.0

背景

Laravel入門書進めていく中で参考書通り進めたがつまづく。 模索した結果、解決したのでメモ

事象

参考書に従ってLaravelのAuth機能を実装しようと以下コマンドを実行

php artisan make:auth

だが、以下エラーが返ってきた

f:id:kuma_kuma0121:20210719091426p:plain

「おや?」

少しググってみると、Laravel 6.0以降から

php artisan make:auth

は使えなくなっているらしい。

では解決方法を引き続き調査

試したこと

laravel uiのインストール

コチラの記事を参考にAuth機能を実行

まずは以下コマンドを実行してlaravel uiをインストール

composer require laravel/ui

⇒Successfully!

ユーザー登録や認証関連のビューファイルを生成

引き続き以下コマンドでユーザー登録や認証関連のビューファイルを生成

php artisan ui vue --auth // Vue.js使用の場合
or
php artisan ui bootstrap --auth // bootstrapの場合

⇒Successfully (ぼくの場合はVue.js)

node.js(npm)のインストール

上記コマンド実行後以下指示が表示された

Vue scaffolding installed successfully.

Please run "npm install && npm run dev" to compile your fresh scaffolding.

Authentication scaffolding generated successfully.

訳: 「問題なくインストールされました。 npm install とnpm run devを実行してインストールしたモノをコンパイルしてください。」

ここで、npm installする前にnode.jsをインストールしてなかった(※)ので、インストール。 コチラを参照。

インストール後は正常に動くか確認も忘れずに。

node --version // nodeのバージョン確認
npm --version // npmのバージョン確認

※npmはnode.jsと一緒にインストールされる。

npm install

nodejs、npmをインストールし終えたので早速以下実行

npm install

わーっといろんなものがインストールされていく様子をドキドキしながら待つ

⇒Sucessfully

【本題】npm run dev

あと、これを実行し終えたらAuth機能実装!というところで以下実行

npm run dev

npm install 同様、ワーッといろんなものが実行されていく。

その時、出てきてしまった…ERRORが…

エラー文は以下の通り。

AssertionError [ERR_ASSERTION]: mix.js() is missing required parameter 1: entry

解決方法

エラー文でググっても海外のサイトしかなく、こちらを参考にした

本記事によるとpackage.json内にある"laravel-mix"のバージョンを手動で切り替えたのち、再度npm installする必要があるらしい。

ということで

laravel-mix: "^5.0.1" ⇒ "laravel-mix": "^6.0.6"

に変更し、再度

npm install 

実行。

すると、何かが追加でインストールされた。そして、

npm run dev

を実行。以下画面となった。

f:id:kuma_kuma0121:20210719214515p:plain

Errorは出ているものの、

Finished. Please run MIx again.

と表示されたので、再度

npm run dev 

を実行。すると、緑色のバーが表示されどんどんたまっていく。

f:id:kuma_kuma0121:20210719215153p:plain

どんどん処理は進んでいき、 f:id:kuma_kuma0121:20210719215217p:plain

無事done。 f:id:kuma_kuma0121:20210719215250p:plain

結果

bladeやController、Model、Routeを整えて、ブラウザを確認すると… f:id:kuma_kuma0121:20210719215442p:plain

無事、Auth機能が実装できました!

所見

後で知ったんですが、Laravel8.0でのAuth機能の実装はjetstreamを使った方法が推奨されているんですね。

最近話題のtailwind.cssを使っているんですよね。 jetstream自体もどんなものかわかっていないので、 今度はjetstream verも試してみよう!

参考記事

Laravel6.x以降のAuth機能実装手順

node.js(npm)のインストール方法

npm run dev後のエラー対応方法