System.out.println("Java学習中");

【Java / Spring Boot】UI/UXの視点を活かしたバックエンド開発の学習ポートフォリオ

未経験から挑んだAWSデプロイ奮闘記:Spring Bootタスク管理アプリを本番公開するまでの軌跡

Adobe Fireflyで作成

🟢 はじめに

💻 Java 会員制タスク管理アプリ

ログイン画面

タスク管理画面

▼ 完成したアプリはこちら

task-app.kenichikamoi.com

これまでサーバーヘルプデスクテスターとしてITサポート「後方支援」を担ってきた経験を活かし、現在はJavaエンジニアへのキャリアチェンジを目指して日々学習に取り組んでいます。

今回は、ローカル環境での開発から一歩踏み出し、

🔸AWS(EC2)サーバーの構築

🔸Nginxの配置

🔸HTTPS化

までを自力で完遂し、

Spring Boot製のWebアプリ

本番公開しました。

この記事では、そのデプロイ奮闘記をお届けしたいと思います。


📝 なぜこのアプリを作ったのか?(開発の背景)

現在、Java Silver資格取得に向けて問題集(紫本)を周回中なのですが、

毎日の学習タスクを管理する、自分好みの居心地の良いアプリが欲しい

と思ったのが開発のきっかけです。

タスク管理ツール

は世の中にたくさんありますが、毎日開くものだからこそ、無機質な画面ではなく、

冒険者がギルドに立ち寄るように、ホッと一息つける空間にしたい

と考えました。

そこで、Webクリエイターとしてのデザインスキルも活かし、UI全体

温かみのある「北欧ナチュラル」テイスト

で統一しています。


🛠️ 実装した主な機能

安全に、そして確実にデータを管理する

という実務的な視点を大切にし、以下の基本機能を実装しました。

🔹セキュアなログイン機能: Spring Securityを活用し、会員のみが自分のタスクギルドに入場できる仕組みを構築。データベース内のパスワードはBCryptで強力に暗号化しています。

🔹クエスト(タスク)のCRUD機能: 新しい学習タスクの「追加(Create)」、一覧の「表示(Read)」、内容の「編集・更新(Update)」、完了したタスクの「削除(Delete)」というWebアプリの基本となるデータ操作を網羅しています。

💻 アーキテクチャと技術スタック

今回の開発・インフラ構築で使用した主な技術は以下の通りです。

ただ機能を作るだけでなく、

本番環境を見据えたインフラ構築とセキュリティ対策

にこだわりました。

🔸フロントエンド: HTML, CSS, JavaScript, Thymeleaf

🔸バックエンド: Java 17, Spring Boot

🔸セキュリティ: Spring Security (BCryptによるパスワード暗号化、CSRF対策)

🔸データベース: MySQL

🔸インフラ・サーバー: AWS (EC2), Nginx (リバースプロキシ)

🔸その他: Let's Encrypt (SSL証明書/HTTPS化), Git/GitHub, Visual Studio Code

🟦 Spring Security

今回、最も高くそびえ立った壁の一つでした。

特にローカル環境では気づけなかった

本番特有の「403 Forbidden(CSRFエラー)」

には苦戦しましたが、

フォームにトークンを仕込む

ことで突破しました。

セキュリティの奥深さを痛感しました。

🟨 AWS (EC2)

まっさらなクラウド上にサーバーを建て

SSH接続やセキュリティグループ(ポートの開閉)

を設定しました。

ローカル開発では意識しなかった

ネットワーク通信の仕組み

を学ぶことができました。

⚙️ Nginx

URLから

裏口のポート番号(:8080)

を隠し、

プロキシとして通信を安全に中継する「受付係」

として導入しました。

🗝️ Let's Encrypt

ポートフォリオとしての信頼性を高めるため、SSL証明書を発行しHTTPS化を実施しました。

導入直後に404エラーが出た際はヒヤッとしましたが、

通信のバケツリレー自体は成功している

ログを見ながら原因を切り分け、ルーティングを追加して解決しました。


🛡️ 苦闘録①:AWSネットワークの壁と「アジャイルな決断」

🏰 【理想】プロの設計「WebとDBの分離」を目指して

インフラ構築を始めるにあたり、当初からAWSのベストプラクティスである

Webサーバーとデータベースサーバーの分離

を目指していました。

システム建物に例えるなら、

EC2(Webサーバー)は「お客さんを接客するお店の店舗」

であり、

MySQL(データベース)は「顧客データが入った金庫」

です。

セキュリティや今後の負荷分散を考えると、店舗の奥に金庫をそのまま置くのではなく、

AWSのRDSを活用して「お店とは別の、隔離された地下金庫室」を構築する

のが、本番環境における最も正しい設計だと考えていたからです。

🧩 【壁】AWSネットワークという難解なパズル

しかし、ここでAWSの巨大な壁にぶつかりました。

RDSという地下金庫室

を作るためには、

VPCやサブネット、ルートテーブルといったネットワーク機能

を使って

インターネットからは絶対に入れないけれど、EC2の店舗からだけは通れる秘密の地下通路

正確に設定する必要があります。

しかし、見えないネットワークの設定パズルのように複雑で、通信エラーが解消できませんでした。

さらに、RDSの設定画面では無意識のうちに

マルチAZ(予備サーバー)の設定が有効

になっており、

1年間の「無料枠」がグレーアウトして選択できなくなる

という、

AWS特有の初見殺しの罠

にも苦戦しました。

🏃‍♂️ 【決断】完璧な設計よりも「まずは動くものを世に出す」こと

ネットワークのエラー画面と睨み合う中で、

RDSの構築に固執して立ち止まる

のではなく、

EC2の中にMySQLを同居させる構成へ軌道修正する

という決断を下しました。

サーバーヘルプデスクとして現場のシステムに関わってきた経験上、

完璧を求めていつまでもリリースできない

ことのリスクを考えると、今の自分にとって最優先すべきは、

まずはインターネットの海へアプリをデプロイし、一連の開発・公開サイクルを最後まで回し切ること

だと判断しました。

「アジャイルな開発」の第一歩としての戦略的撤退

として捉え、まずは今の構成で無事にリリースを完遂し、今後のスキルアップの課題として、

ネットワーク知識を深めてRDS分離構成へ再チャレンジしたい

と考えています。


🚫 苦闘録②:Spring Securityが放つ「403 / 404」エラー

⚠️ 「ローカルでは動いたのに!」突然のWhitelabel Error Page

インフラ側の設定を終え、ブラウザからアクセスした私を待っていたのは、無情にも表示された真っ白な

Whitelabel Error Page

でした。

自分のPC(ローカル環境)では完璧に動いていたログイン画面が、AWSに乗せた途端に動かなくなる絶望感。

「Web開発あるある」の洗礼

を全身で浴びた瞬間でした。

ここで、「エラーログの解読」「原因の切り分け」を行いました。

🛡️ 403 Forbidden:本番環境に潜む「CSRFの罠」

最初に立ちはだかったのは、

データを送信(POST)しようとした時に発生する「403 Forbidden(アクセス権限なし)」エラー

です。

403 Forbidden(アクセス権限なし)画面

ログを追跡した結果、

システムを守るはずの「Spring Security」自身が通信を遮断している

ことが判明しました。

原因は

CSRF(クロスサイトリクエストフォージェリ)対策

でした。

悪意のある攻撃を防ぐための重要な機能

ですが、本番環境では、正規のフォームからの通信であっても「合言葉(トークン)」がないと弾かれてしまいます。

そこで、HTML側のフォーム内

CSRFトークンを自動生成して埋め込む処理

を追加しました。

「これは正規の入り口からのアクセスです」という通行手形を持たせる

ことで、この強固な門番を突破しました。

🌐 404 Not Found:HTTPS化成功と「コンシェルジュの不在」

次なる試練は、NginxLet's Encryptを用いて「HTTPS化(通信の暗号化)」を完遂した直後に訪れました。

ターミナルに「Congratulations!」の文字が表示されたことを確認し、鍵マーク🔒のついたURLへアクセスしましたが、

404 Not Found(ページが見つかりません)

というエラー画面が表示されました。

404 Not Found(ページが見つかりません)画面

一瞬ヒヤッとしましたが、冷静に状況を切り分けてみました。

ブラウザに鍵マークは表示されている。
つまり、AWSの玄関(443番ドア)から受付係(Nginx)を通り、裏側のJavaアプリまでは『通信のバケツリレー』が成功している証拠だ。

原因はインフラ側ではなく、

Javaアプリ側に「URLの末尾が何もないルート(/)へアクセスされた時の案内図」がないだけ

だと分かりました。

そこで、

アクセス時に自動でログイン画面へ案内する RootController.java (リダイレクト処理)

を追加しました。

このコンシェルジュの配属により、ユーザーエラー画面で迷わせることなく、ログイン画面へ誘導できるようになりました。


✍️ おわりに:インフラ構築を通して得た学びと次なる目標

🌍 システム全体の「解像度」が高まったインフラ構築

単にプログラミング言語を書くだけでなく、

AWSでのサーバー構築からドメイン設定、Nginxによるルーティング設定までを通しで行った

ことで、

Webシステム全体がどう動いているのか

その「解像度」が劇的に高まりました。

特に印象深かったのは、

VPCやプライベートサブネットを用いた「セキュアなネットワーク通信」の構築

です。

ここで想定以上に時間がかかり、最終的に

RDS(データベース専用サーバー)の分離を断念したこと

は悔しい経験でした。

しかし、

AWSコンソールでマルチAZなどを無意識に選ぶと「無料枠」がグレーアウトする初見殺しの罠

など、

「AWSを触るエンジニアが必ず一度は引っかかるであろうあるある」を体感できたこと

は大きな収穫です。

単なる操作ミスではなく、クラウドの複雑な仕様に触れたからこその学びでした。

⚖️ 「理想の理解」と「アジャイルな決断」

RDSの構築は見送りましたが、

なぜWebサーバーとDBサーバーを分けるのか

というベストプラクティスの意図は明確に理解できました。

🔹万が一EC2(店舗)が乗っ取られてもデータベース(地下金庫)を守る「セキュリティの向上」

🔹面倒なバックアップや更新をAWS側が自動で行う「マネージドサービスの恩恵」

🔹「負荷分散」によるシステムダウンの回避

「プロが現場で使っている安全な形」を再認識できたからこそ、

今回は

「理想の形は理解しつつも、リリース期限や目標のために柔軟に手段を切り替える」

という、実務で不可欠なアジャイル思考を実践することができました。

🏁 次なる冒険:私だけの「オリジナル設計図」を描く

次なるステップとして、前職のヘルプデスク経験を活かし、

今回のCRUDと権限管理をさらに発展させた「Ticketing System(社内ヘルプデスク管理アプリ)」の開発

に着手したいと考えています。

実務経験からくる「こういう機能が必要だ」という生きた視点は、どんな教科書にも載っていない私だけのオリジナル設計図になると思います。

具体的には以下の技術に挑戦したいと考えています。

👥 高度な権限管理: 「ROLE_USER(一般)」と「ROLE_ADMIN(サポート)」で権限を分け、表示内容やアクセスURLを制御するSpring Securityの応用。

🖼️ 画像アップロード機能: トラブル解決の鍵となる「エラー画面のスクショ」を添付できる仕組み(MultipartFileの活用と、将来的なAWS S3連携)。

🔍 ステータス絞り込み検索: 必要な情報を瞬時に引き出すための、複雑なSQL(WHERE句の組み合わせ)を駆使した検索機能。

無機質になりがちな業務システムですが、

「機能的かつ、トラブルを抱えたユーザーの不安を和らげる優しい北欧ナチュラルデザインの社内システム」

を目指したいと思います。

まずは、

データをどう保存するかの「データベースのテーブル設計」

と、

ユーザーがどう操作するかの「画面構成(ワイヤーフレーム)」

から、次のアプリ開発の構想を練っていきたいと思います。

最後までお読みいただき、ありがとうございました🙇‍♂️


【プロフィール・作品置き場】

kenichikamoi.com


🎵 Youtube(楽曲一覧)はこちら

www.youtube.com