0
3

More than 1 year has passed since last update.

【Webアプリ環境構築】GCPインスタンス作成~Webアプリ起動

Last updated at Posted at 2023-09-01

はじめに

ポートフォリオの環境構築をGCPで行うことが2度目なので、
今後も行うことを想定して備忘録として全体の流れをまとめておきます。

駄文ですが、部分的でもどなたかのお役に立てれば幸いです。

ポートフォリオ
ポートフォリオ第二弾

全体の流れ

Springをwarファイルにビルドしたものを、
GCPで生成したCentOS上にTomcatとmariadbを構築して動かします。

  • GCPのインスタンス生成
  • Tomcatインストール
  • ポートフォワーディングの設定
  • mariadbインストール
  • タイムゾーンの設定
  • セッションタイムアウトの設定

GCPのインスタンス生成

インストールする際の各種設定(無料枠について,os,firewall,ネットワーク等)
userのパスワード変更してsshできるように設定

参考:
(2023年版) Google Cloud 無料枠 ホントに課金されない?の検証

インスタンスを作成をクリック
1.png

リージョンを無料枠のオレゴン・アイオワ・サウスカロライナのいずれか選択
2.png

マシンタイプを無料枠のe2-microに選択
3.png

ブートディスクのタイプを無料枠の標準永続ディスクに変更
サイズを無料枠の30GB以下に変更
イメージを無料枠の好きなOSに変更(私はCentOS7にしました)
4.png

5.png

ファイアウォールのHTTP,HTTPSトラフィックの許可(80ポートの許可)
6.png

詳細オプション

静的外部IPの設定をする場合

詳細オプション→ネットワーキングを開く
10.png

ネットワークインターフェースを開く
11.png

外部IPv4アドレスを開く
12.png

静的IPv4アドレスを開く
13.png

任意の名前を入力
14.png

静的IPv4アドレスの登録完了
15.png

TeraTermなどでSSH通信する場合

詳細オプション→セキュリティを開く
7.png

アクセスを管理するを開く
8.png

手動で生成したSSH認証鍵の追加から項目の追加を押して、
自分が生成した公開鍵を追加。
9.png

作成を押すとインスタンスが作られる
16.png

VMインスタンスからSSHをクリックしてサーバーに接続する
17.png

JDK17インストール

参考:下記手順をsudoコマンドで実行します。
CentOS 7にOpenJDK 17をインストール(Azul Zulu Builds of OpenJDK)

Tomcatインストール

参考:
Apache Tomcat 9 を CentOS 7 にインストールする手順
Apache Tomcatをインストールしたらすぐに設定したいセキュリティ対策

Tomcat を動かすための専用ユーザとして tomcat を追加します。

CentOS7
# useradd -s /sbin/nologin tomcat

tar.gz 形式の Apache Tomcat 10 本体をダウンロードします。
(現在の最新版は11だが、Webアプリの作成環境が10なのでこちらを使用)

CentOS7
# cd ~
# curl -O http://ftp.riken.jp/net/apache/tomcat/tomcat-10/v10.1.13/bin/apache-tomcat-10.1.13.tar.gz

ダウンロードした tar.gz ファイルを解凍して配置します。
tar コマンドで解凍して、今回は /opt に配置します。
また、解凍した Apache Tomcat の所有者を作成したtomcatユーザの所有とします。

CentOS7
$ tar -xzvf ~/apache-tomcat-10.1.13.tar.gz
$ sudo mv ~/apache-tomcat-10.1.13 /opt
$ sudo chown -R tomcat:tomcat /opt/apache-tomcat-10.1.13

Apache Tomcat 10 をサービスとして登録します。
まずは /etc/systemd/system/tomcat.service を新たに作成して、
つぎのように記述して保存します。

CentOS7
$ sudo vi /etc/systemd/system/tomcat.service
CentOS7(tomcat.service)
[Unit]
Description=Apache Tomcat 10
After=network.target

[Service]
User=tomcat
Group=tomcat
Type=oneshot
PIDFile=/opt/apache-tomcat-10.1.13/tomcat.pid
RemainAfterExit=yes

ExecStart=/opt/apache-tomcat-10.1.13/bin/startup.sh
ExecStop=/opt/apache-tomcat-10.1.13/bin/shutdown.sh
ExecReStart=/opt/apache-tomcat-10.1.13/bin/shutdown.sh;/opt/apache-tomcat-10.1.13/bin/startup.sh

[Install]
WantedBy=multi-user.target

作成した定義ファイルの権限を 755 に変更。

CentOS7
$ sudo chmod 755 /etc/systemd/system/tomcat.service

定義ファイルの作成が完了したら、
systemctl enable コマンドでサービスを有効にします。

CentOS7
$ sudo systemctl enable tomcat

Apache Tomcat 10 を起動してみます。
Active: activeと表示されたらOK。

CentOS7
$ sudo systemctl start tomcat
$ sudo systemctl status tomcat

● tomcat.service - Apache Tomcat 10
   Loaded: loaded (/etc/systemd/system/tomcat.service; enabled; vendor preset: disabled)
   Active: active (exited) 

firewalledの設定のため、一度stopさせます。

CentOS7
$ sudo systemctl stop tomcat

Firewalldで8080番を有効に設定します。
/etc/firewalld/services/ フォルダに tomcat.xml を作成します。

CentOS7
$ sudo vi /etc/firewalld/services/tomcat.xml

//下記内容をコピペ
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Apache Tomcat 10</short>
  <description>Apache Tomcat 10</description>
  <port protocol="tcp" port="8080"/>
</service>

Firewalld が現時点で通信を許可しているサービスは、firewall-cmdコマンドで確認できます。
確認するとdhcpv6-client と ssh のサービスが許可されていることが分かります。

CentOS7
$ sudo firewall-cmd --list-services --zone=public --permanent
dhcpv6-client ssh

tomcat の通信を許可するように、次のように firewall-cmd を実行します。

CentOS7
$ sudo firewall-cmd --add-service=tomcat --zone=public --permanent
$ sudo firewall-cmd --reload

もう一度、現在通信を許可しているサービスを確認すると、
今度は tomcat が追加されたことが確認できます。

CentOS7
$ sudo firewall-cmd --list-services --zone=public --permanent
dhcpv6-client ssh tomcat

以下はやらなくても可。

GET と POST 以外のメソッドを拒否する設定をします。
Tomcatのホームディレクトリ配下の conf/web.xml (特定のアプリケーションだけ設定したい場合は、アプリケーション内のweb.xml)に<http-method>タグで拒否したいメソッドを列挙します。

conf/web.xml
## 以下をコピペ
<security-constraint>
    <web-resource-collection>
        <web-resource-name>deny method</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method>HEAD</http-method>
        <http-method>PUT</http-method>
        <http-method>DELETE</http-method>
        <http-method>OPTIONS</http-method>
        <http-method>TRACE</http-method>
        <http-method>CONNECT</http-method>
        <http-method>PATCH</http-method>
        <http-method>PROPFIND</http-method>
        <http-method>PROPPATCH</http-method>
        <http-method>MKCOL</http-method>
        <http-method>COPY</http-method>
        <http-method>MOVE</http-method>
        <http-method>LOCK</http-method>
        <http-method>UNLOCK</http-method>
    </web-resource-collection>
    <auth-constraint/>
</security-constraint>

apatch-tomcat/webappsにwarファイルを配置します。
tomcatにリスタートをかけます。

CentOS7
$ sudo systemctl restart tomcat

アクセスできたら完了です。

ポートフォワーディングの設定

私の環境だとTomcatを80番ポートに設定できないので、
ポートフォワーディングで疑似的に80番ポートのアクセスを受け付けます。

参考:
firewalld で ポートフォワーディング

80番ポートのアクセスを8080番に転送しています。

CentOS7
$ sudo firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080
#設定の永久化
$ sudo firewall-cmd --runtime-to-permanent

これでIPアドレスやドメインから直接サインインすることが可能になりました。

mariadb

参考:
初心者向け CentOS7.9 に MariaDB 10.6をインストール
Download MariaDB Server(公式)

公式の手順に従って行います。

まずRepositoryを作ります。

CentOS7
$ sudo vi /etc/yum.repos.d/MariaDB.repo

#以下内容コピペ

# MariaDB 11.1 CentOS repository list - created 2023-08-29 12:25 UTC
# https://mariadb.org/download/
[mariadb]
name = MariaDB
# rpm.mariadb.org is a dynamic mirror if your preferred mirror goes offline. See https://mariadb.org/mirrorbits/ for details.
# baseurl = https://rpm.mariadb.org/11.1/centos/$releasever/$basearch
baseurl = https://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/yum/11.1/centos/$releasever/$basearch
module_hotfixes = 1
# gpgkey = https://rpm.mariadb.org/RPM-GPG-KEY-MariaDB
gpgkey = https://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/yum/RPM-GPG-KEY-MariaDB
gpgcheck = 1

mariadbのインストールを実行します。

CentOS7
$ sudo yum install MariaDB-server MariaDB-client

#ひたすらyを押して、以下が出たら完了
Replaced:
  mariadb-libs.x86_64 1:5.5.68-1.el7

Complete!

mariadbを実行します。

CentOS7
$ sudo systemctl enable mariadb
$ sudo systemctl start mariadb
$ sudo systemctl status mariadb

#以下表示ならOK
Active: active (running)

mariadbの最低限の設定を行います。

CentOS7
$ sudo mariadb -u root -p
Enter password: #そのままEnterキーを押す

#パスワードを設定
mariaDB[(none)]> ALTER USER 'root'@'localhost' IDENTIFIED BY "ここにパスワードを設定";

この後はWebアプリで使用するデータベースを構築するだけです。

タイムゾーンの設定

参考:
タイムゾーンを日本標準時(JST)に変更する CentOS 8, 7

私の作成したWebアプリでは日時を表示する機能があります。
そのため、Linuxのタイムゾーンを東京に変えます。

timedatectlコマンドでタイムゾーンを東京に設定します。

CentOS7
$ sudo timedatectl set-timezone Asia/Tokyo
$ sudo timedatectl status

#以下が出力される
      Local time: Wed 2023-08-30 16:30:52 JST
  Universal time: Wed 2023-08-30 07:30:52 UTC
        RTC time: Wed 2023-08-30 07:30:52
       Time zone: Asia/Tokyo (JST, +0900)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

mariadbを再起動してタイムゾーンを更新します。

CentOS7
$ sudo systemctl restart mariadb
$ mariadb -u root -p

MariaDB [(none)]> select @@time_zone; select @@system_time_zone;
+-------------+
| @@time_zone |
+-------------+
| SYSTEM      |
+-------------+
1 row in set (0.000 sec)

+--------------------+
| @@system_time_zone |
+--------------------+
| JST                |
+--------------------+
1 row in set (0.000 sec)

JSTに変更できました。

余談

500エラーの事例

Webアプリを動かすと500エラーが発生したので事例を載せておきます。

そもそもどこのログを見たら良いか
500エラーが発生した場合、エラーページでは詳細が分かりません。 Tomcatでは`apache-tomcat/logs/catalina.out`で分かります。
小文字、大文字の統一
catalina.out
org.springframework.jdbc.BadSqlGrammarException: 
PreparedStatementCallback; bad SQL grammar [SELECT NAME FROM USER WHERE NAME = ?]
...
Caused by: java.sql.SQLSyntaxErrorException:
(conn=31) Table 'learning_stopwatch.USER' doesn't exist

データベースの全ての定義を小文字で行っているにも関わらず、
JavaのSQL文に一部、大文字で指示している部分がありました。
小文字に修正すれば動きました。

文字コード

参考:
文字コードに関する設定を記述する
MySQLのテーブル作成後に、文字コードをutf8mb4に変更する

catalina.out
o.m.jdbc.message.server.ErrorPacket:
Error:1366-22007:Incorrect string value:'\xE5\xAE\x8C\xE6\x88\x90...' for column

insert intoした文字列が、
サポートする文字コードと合わない場合に表示されるエラーのようです。

mariadbの文字コードを確認してみます。

mariadb
MariaDB [(none)]> SHOW VARIABLES LIKE 'chara%';
+--------------------------+------------------------------+
| Variable_name            | Value                        |
+--------------------------+------------------------------+
| character_set_client     | utf8mb3                      |
| character_set_connection | utf8mb3                      |
| character_set_database   | latin1                       |
| character_set_filesystem | binary                       |
| character_set_results    | utf8mb3                      |
| character_set_server     | latin1                       |
| character_set_system     | utf8mb3                      |
| character_sets_dir       | /usr/share/mariadb/charsets/ |
+--------------------------+------------------------------+

クライアントに関係する部分は以下の3つのようです。
全てutf8なので問題なさそうです。

character_set_client
クライアントからSQL文などが送信される時に使用される文字コード

character_set_connection
クライアント側から受け取った文字を変換する文字コード

character_set_results
クライアントへ結果を送信する時に使用される文字コード

続いて、データベースとテーブルの文字コードと照合順序を確認してみます。

mariadb
#データベース
MariaDB [(none)]> 
SELECT SCHEMA_NAME,DEFAULT_CHARACTER_SET_NAME,DEFAULT_COLLATION_NAME 
FROM INFORMATION_SCHEMA.SCHEMATA 
WHERE SCHEMA_NAME = 'learning_stopwatch';

+--------------------+----------------------------+------------------------+
| SCHEMA_NAME        | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME |
+--------------------+----------------------------+------------------------+
| learning_stopwatch | latin1                     | latin1_swedish_ci      |
+--------------------+----------------------------+------------------------+

#テーブル
MariaDB [(none)]> 
SELECT TABLE_NAME,TABLE_COLLATION
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='learning_stopwatch';
+---------------------+-------------------+
| TABLE_NAME          | TABLE_COLLATION   |
+---------------------+-------------------+
| daily_learning_time | latin1_swedish_ci |
| user                | latin1_swedish_ci |
+---------------------+-------------------+

データベース、テーブルの文字コードはlatin1になっていますね。

mariadbの文字コードをもう一度確認すると、
クライアントから受け取る文字コードはutf8mb3ですが、
データベースの文字コードはlatin1になっています。
データベースの文字コードをutf8mb3に変更すれば動きそうです。

mariadb
MariaDB [(none)]> SHOW VARIABLES LIKE 'chara%';
+--------------------------+------------------------------+
| Variable_name            | Value                        |
+--------------------------+------------------------------+
| character_set_client     | utf8mb3                      |
| character_set_connection | utf8mb3                      |
| 'character_set_database' | 'latin1'                     |
| character_set_filesystem | binary                       |
| character_set_results    | utf8mb3                      |
| character_set_server     | latin1                       |
| character_set_system     | utf8mb3                      |
| character_sets_dir       | /usr/share/mariadb/charsets/ |
+--------------------------+------------------------------+

データベースとテーブルの文字コードを変更します。

mariadb
#まずはデータベースから変更
MariaDB [(none)]> 
ALTER DATABASE learning_stopwatch
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;

Query OK, 1 row affected (0.035 sec)

MariaDB [(none)]> 
SELECT SCHEMA_NAME,DEFAULT_CHARACTER_SET_NAME,DEFAULT_COLLATION_NAME     
FROM IMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'learning_stopwatch';
+--------------------+----------------------------+------------------------+
| SCHEMA_NAME        | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME |
+--------------------+----------------------------+------------------------+
| learning_stopwatch | utf8mb4                    | utf8mb4_general_ci     |
+--------------------+----------------------------+------------------------+
#つづいてテーブルを変更
MariaDB [learning_stopwatch]>
ALTER TABLE user
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;

Query OK, 1 row affected (0.217 sec)
Records: 1  Duplicates: 0  Warnings: 0

MariaDB [learning_stopwatch]>
ALTER TABLE daily_learning_time
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;

Query OK, 0 rows affected (0.029 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [learning_stopwatch]>
SELECT TABLE_NAME,TABLE_COLLATION
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='learning_stopwatch';
+---------------------+--------------------+
| TABLE_NAME          | TABLE_COLLATION    |
+---------------------+--------------------+
| user                | utf8mb4_general_ci |
| daily_learning_time | utf8mb4_general_ci |
+---------------------+--------------------+

これで正常に稼働しました。

セッションタイムアウトの設定

参考:
Spring Boot - セッションタイムアウト時間の設定方法

warビルドの場合

web.xml を作成して設定する。

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    version="4.0">

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

</web-app>

TOMCAT_HOME/conf/web.xml でアプリケーションサーバに対するデフォルトのセッションタイムアウト設定することが可能。ただし、ほとんどの場合はアプリケーション個別にセッションタイムアウトを設定したいことのほうが多いと思う。その場合は、アプリケーションプロジェクトに src/main/webapp/WEB-INF/web.xml を作成する。

おわりに

どなたかの参考になれば幸いです。

0
3
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
0
3