ブログ

サーバ構築とプロジェクトバージョンアップについて

【投稿者】なから

こんにちは、
最近入社した新人のなからです。
今回は、新人研修で取り組んだサーバ構築とプロジェクトバージョンアップについて、作業中にぶつかった問題なども交えながら語っていこうと思います。

研修の目的は、「当社で数年前開発し現役バリバリのシステムのバージョンアップをしたとき、検索やファイルアップロードなどの処理が前バージョンと比較してどれほど速くなるかを検証する」というものでした。
サーバ構築については学生時代少しだけ取り組んだことがあったのですが、ほぼほぼ素人状態だったため、拙いところもあるとは思いますがよろしくお願いします。

作業1.OSのインストール

一番最初の作業は、OSのインストールでした。
OSのインストール先はVMware Esxi上の仮想サーバ、インストールするOSはRocky Linux最新バージョンということで、Rocky Linux公式サイトに行き、ISOイメージ(Boot)のダウンロードを行いました。
それから、ISOイメージを仮想サーバのデータストアにアップロード、ISOファイルをマウントし、いざインストール!…のはずだったのですが、ここで問題1が発生しました。

OSをインストールして再起動したのですが、何度やってもインストール画面にループしてしまいます。
ISOイメージをMinimalに変えたり、ISOイメージのハッシュ値を公式と比較して確認してみたり、色々やってみたのですが、やはり失敗してしまいました。
結論から言うと、おそらく仮想サーバのスペックが足りないということで、仮想サーバを作り直してスペックを上げ、Rocky Linux をダウングレードすることで成功しました。

作業2.OSの設定

OSの設定では、ユーザの作成・IPアドレスの設定・SSHでログインできるように設定の作業を行いました。
コマンド
・sudo nmcli con mod [接続名] [設定名] [値]
しかし、ここで設定したIPアドレスが、後々問題になってくるとも知らずに、そのまま作業を進めてしまいました。

作業3.秘密鍵の登録

次は秘密鍵の登録です。秘密鍵のセット方法について調べていると、scpコマンドというものにたどり着きました。
コマンド
・scp [オプション] [コピー元パス] [コピー先パス]
このコマンドは、SSHを利用して、コンピュータ間でファイルを安全にコピーできるコマンドです。
オプションには 「-r」や「-p」などがあります。
このコマンドを使ってローカルの秘密鍵をサーバに設置しようとしましたが、ここで問題2が発生しました。

SSHログインができず、秘密鍵の登録ができませんでした。
一時的な対応策として、バージョンアップ前のシステムが動いている仮想サーバを踏み台にして、現在のサーバにSSHログインしました。
SSHログインができない原因は、作業2で行ったIPアドレスの設定のサブネットマスクが間違っていたことでした。
マスク長が本来なら /21 のところ、 /24 になっていました。/24に設定した理由としては、AIにマスク長を計算してもらった結果が/24だったためです。これは失敗でした、、、

作業4.DBのリストア

次に、前のサーバのDBのdumpファイルを新しいサーバにリストアする作業を行いました。
・mysql -u [ユーザ名] -p [DB名] < [dumpファイル名]
DBをリストアするコマンドを実行したところ、
Variable ‘sql_mode’ cant be set to the value of ‘NO_AUTO_CREATE_USER’
というエラーが出たので、
・mysql -u [ユーザ名] -p –init-command=”SET SESSION sql_mode=”” [DB名] < [dumpファイル名]
でSQLモードを空文字にして実行したのですが、これもエラーになったため、
・sed -i ‘279s/NO_AUTO_CREATE_USER//g’ [dumpファイルのパス]
でdumpファイルの「NO_AUTO_CREATE_USER」を削除し、DBのリストアを行いました。
sedコマンドはストリーム形式のテキストエディタで、ファイルを直接開くことがないので、膨大なサイズのテキストファイルを効率的に編集することができます。

作業5.ミドルウェアのインストールと設定ファイルの移植

次に、新しいサーバにApache、MySQL、PHP最新バージョンのインストールと、各設定ファイルを前のサーバから新しいサーバに移植する作業を行いました。
また、コピーする前にdiff [ファイル1] [ファイル2] コマンドで差分を確認しました。
コマンド
scp -r /etc/httpd/conf [ユーザ名]@[サーバのIPアドレス]:/etc/httpd/
scp /etc/my.cnf [ユーザ名]@[サーバのIPアドレス]:/etc/
scp /etc/php.ini [ユーザ名]@[サーバのIPアドレス]:/etc/
この3つのコマンドで前のサーバから設定ファイルをコピーし、それぞれ
・sudo systemctl restart [サービス名]
で再起動したのですが、ここで問題3が発生しました。

Job for mysqld.service failed because the control process exited with error code.
See “systemctl status mysqld.service” and “journalctl -xeu mysqld.service” for details.
というエラーが発生しました。
MySQLの起動に失敗したとのことです。diffコマンドで差分を確認したのですが、少し焦っていて、よく確認せずにコピーしてしまいました。
エラーの原因はscpコマンドに -p オプションをつけておらず、権限が適切でなかったため、またMySQL設定ファイルの古い設定があったためでした。
-pオプションをつけると、ファイルのパーミッション(権限)やタイムスタンプ(更新日時)を保持したままファイルをコピーできるそうです。MySQL設定ファイルの古い設定をコメントアウトし、所有者をもとに戻すことで解決しました。
所有者変更コマンド
・chown [新しい所有者]:[新しいグループ] [ファイルまたはディレクトリ]

作業6.Laravelのアップグレード

次に、PHPのフレームワークであるLaravelをアップグレードする作業を行いました。
具体的には、Composer.jsonの更新・composerのアップデートです。
テキスト編集コマンド
・sudo vi [ファイルのパス]
テキスト読み取り専用
・sudo less [ファイルのパス]
Composer.jsonに必要なライブラリを書き込み、Composer update を実行したのですが、ここで問題4が発生しました。

Composer updateを実行すると、Gitのリポジトリからパッケージをダウンロードしようとした際に認証に失敗するため、githubにアクセスしてトークンを生成し、入力してください、とのエラーが出てしまいました。
調べた方法でunzipをインストールすると成功するというものがあったのですが、これもエラーになってしまいました。
Laravelをアップグレードするのは大分大変なようで、新しくLaravelプロジェクトを作り、そこにアプリ部分だけ移植するという方針になりました。

作業7.Laravelプロジェクト作成・アプリ移植

次に、新しくLaravelプロジェクトを作成し、アプリのソースコードや設定ファイルなどを前のサーバからコピーする作業を行いました。
Laravelプロジェクト作成コマンド
・composer create-project laravel/laravel:^[Laravelバージョン] [作成するプロジェクトのディレクトリ名]
コピーしたファイルは、
app
resources
routes
config
public
.env
の5つです。また、npm installで、外部ライブラリやパッケージが保存されるディレクトリであるnode_modulesの作成を行いました。
一旦ブラウザから新しいサーバにアクセスしてみたところ、「接続がリセットされました」とでて動かないので、Laravelのエラーログを見ようとしたのですが、ここで問題5が発生しました。

ブラウザで新しいサーバにアクセスしたので、エラーログが生成されているはずなのですが、
tail: cannot open ‘storage/logs/laravel.log’ for reading: No such file or directory
tail: no files remaining
というエラーログが見つからない旨のエラーが出てしまいます。
原因は、Webサーバを動かしているPHPプロセスが、エラーをログに書き込もうとしたところ、書き込み権限がなかったためにエラーログが生成されなかったことでした。
権限変更コマンド
・sudo chmod [オプション] [パーミッションコード] [権限を変更するディレクトリやファイルパス]
オプションにはよく「-R」が指定されますが、これはディレクトリ内のファイルやサブディレクトリも再帰的に変更するオプションです。
「-R」は小文字でも大文字でも違いはないですが、慣習的にcpやrm、chownといったコマンドでは「-r」が、chmodでは「-R」が
よく使われるそうです。
パーミッションコードですが、これはファイルやディレクトリへのアクセス権限を管理するための設定です。
8進数の独立した3桁で表され、左から1桁ずつ所有者・グループ・その他の権限を表します。例:775
ディレクトリやファイルに設定されているパーミッションは ls -l コマンドで確認でき、
drwxrwxr-x
のような形で表示されます。左から一つ目の「d」はディレクトリであることを表し、「-」はファイルであることを表します。


2進数で考えるとわかりやすいです。例のパーミッションコード775をそれぞれ2進数にすると、
8進数: 775
2進数: 111 111 101
となります。この2進数の3桁は左から読み取り権限、書き込み権限、実行権限になっています。
権限がONになっていると1、OFFになっていると0になります。
このONとOFFの組み合わせで000~111になり、これを8進数にしたのがパーミッションコードになります。
775の場合は、所有者とグループが全ての権限を、その他が読み取り権限と実行権限を持っていることになります。

作業8.設定ファイル・ソースコードの修正

これで大体作業は終わったので、あとはアプリが動くまでエラーログを見ながら古い設定ファイルやソースコードの修正になります。
Laravelのキャッシュ削除コマンド
php artisan optimize:clear
オートローダーマップを再生成するコマンド
composer dump-autoload
ソースコードを修正した後、これらのコマンドを実行して、ブラウザで新しいサーバにアクセスすると、やっとアプリが動くようになりました。
しかし、ここで問題6が発生しました。

アプリが動いたはいいものの、アプリの機能であるファイルアップロード機能と検索機能が機能しない状態でした。
ファイルアップロード機能が機能しない原因は、ライブラリ不足だったり、MySQLのバージョンの違いによるものでした。
MySQLのバージョンによっては、null値がデフォルト値に置き換わらないこともあるようです。
ライブラリインストールコマンド
・sudo dnf install [ライブラリ名]
また、検索機能が機能しない原因は、SQLクエリの実行計画を最適化するためのオプティマイザの挙動がかわってしまい、それによりオプティマイザが新しいバージョンに合わせた良いアプローチをしようとして、古いバージョンのSQLクエリと合わず逆に動作が重くなり、タイムアウトしていたことでした。
この問題についてはまだ改善できておらず、現在も調査中です。

まとめ

今回研修を受けてみて、サーバ構築・プロジェクトバージョンアップはこんな大変な作業だったんだな、と実感しました。
エラーに対処する力、Linuxコマンドなど、様々なものが身についたと感じています。
これからまたサーバ構築に携わることがあれば、挑戦してみたいです。

関連記事

  1. 決起大会&懇親会を開催しました!

  2. 鉄道好きの楽しい一日

  3. ローコードツールWebPerformer

  4. 花火撮影のススメ

  5. 新しい一年!年に一度の決起大会&懇親会

  6. 宣言!

カテゴリー