このコードはFlaskの機能を使っており、サーバーサイドスクリプトに該当します。
次のように動作するリダイレクト機能を実装する方法を、このページには書いていきます。
注意したい独自ドメイン設定手順とルールの続きとも言えますね。
このコードの構成を見ると、典型的なサーバーサイドスクリプトと言えます。
リクエストされたURLを動的に書き換え、新しいURLにリダイレクトする処理を行っていますし、実行はサーバー上で行われ、クライアント(ユーザーのブラウザ)にはリダイレクト先のURLだけが通知されます。
リダイレクト設定を自分で行うなら、自身のサイトの構造を知る必要があります。
このような構造は一般的に「プロジェクト構成」や「ディレクトリ構造」と呼ばれます。
私の場合、Google App Engineにデプロイされていて、動的Webサイト(Flask使用)と静的Webサイトが混在しているのが特徴となっています。
FEIN-SITES-DEV1
│ app.yaml # メインサービスの App Engine 設定ファイル(ランタイム・ルート定義など)
│ dispatch.yaml # サービス間のルーティング規則を定義するファイル
│ main.py # Flask アプリケーションのエントリポイント(ルートや動的機能の設定)
│ README.md # プロジェクトの概要や使い方を説明するドキュメント
│ requirements.txt # アプリで必要な Python パッケージ(依存関係)のリスト
├─redirect-service # リダイレクト専用サービスのディレクトリ
│ app.yaml # リダイレクト用サービスの App Engine 設定ファイル
│ redirect.py # リダイレクト処理を記述した Flask アプリケーション
│ requirements.txt # リダイレクト用サービスで必要な Python パッケージのリスト
├─static # 静的ファイルを保存するディレクトリ(CSS, JavaScript, 画像など)
│ ├─css # スタイルシート(デザイン)を格納
│ ├─js # JavaScript(インタラクションや動作制御)のスクリプトを格納
│ └─menu # メニュー関連のリソースを保存
├─templates # Flask 用の HTML テンプレートを保存
│ top.html # `/top` ルート用の動的コンテンツテンプレート
│
│ 【上側がFlaskフレームワーク。サーバーサイドスクリプトを活用した動的Webサイトです。】
│ 【下側が普通のホームぺージ。フロントエンド3言語による静的Webサイトです。】
│
└─www # 静的ウェブサイトのルートディレクトリ(主にフロントエンド用)
│ favicon.ico # ブラウザのタブに表示されるアイコン
│ index.html # 静的ウェブサイトのホームページ
│ manifest.json # PWA(Progressive Web App)の設定ファイル
│ robots.txt # 検索エンジンによるクローリング設定ファイル
│ service-worker.js # PWA 用のサービスワーカー(キャッシュ管理やオフライン対応)
├─contents # コンテンツ関連のファイルやデータを格納
├─css # 静的ウェブサイト専用のスタイルシートを保存
├─fish # 画像やリソース用ディレクトリ
├─script # フロントエンド用 JavaScript を格納
この構造は、「Webアプリケーションを動かすためのファイルやフォルダを整理した箱」と考えると分かりやすいです。
それぞれの部分に役割があり、全体が一緒になって動きます。
この部分は、サーバー側(バックエンド)で動く頭脳のようなものです。
サーバーが「お客さん(訪問者)のリクエスト」を受け取ったり、必要な情報を探して返す役割を持ちます。
このセクションで集中的に見ていくエリアです。
リダイレクトとは、「訪問者を自動で別のページに連れて行く」仕組みです。
例えば、「古いページに来た人を新しいページに案内」するときなどに使います。
私の場合、他のエリアと同じようにPythonで書かれた小さな追加サービスとなっています。
別のサーバーでも動かせるよう、ファイルが独立しています。
静的ファイルは、「サーバー側で処理がいらない見た目のページや素材」の集まりです。単純にブラウザで読まれるだけの部分ですよね。
何かしらの紹介ページ(HTMLファイル)や、デザインの色や形を決めるCSSファイル、ボタンの動きを制御するJavaScriptファイルなどがあります。
この構造の強みは、「動的な処理」と「静的な素材」をうまく組み合わせて使える点です。
簡単にいうと、「頭を使って動く部分」(サーバー処理)と、「見た目を支える部分」(静的ファイル)が一緒に整理されていて、効率よく作業できるようになっています。
では、リダイレクト設定を行うソースコードを見ていきます。
リダイレクト設定を行うredirect.py
import os
from flask import Flask, request, redirect
app = Flask(__name__)
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def redirect_all(path):
# クエリ文字列も含めた完全な URL を作成
new_url = request.url.replace(request.host, 'feinatelier.org', 1)
return redirect(new_url, code=301)
if __name__ == '__main__':
port = int(os.environ.get('PORT', 8080))
debug_mode = os.getenv('FLASK_DEBUG', 'False').lower() == 'true' # デバッグモードを環境変数で制御
app.run(host='0.0.0.0', port=port, debug=debug_mode)
このコードを動かすと、例えば「http://example.com/some-page」にアクセスした人を自動的に「http://feinatelier.org/some-page」に転送してくれる、という仕組みです。
コードの部分ごとの説明をしていきます。
ライブラリの読み込み
import os
from flask import Flask, request, redirect
Flaskアプリの初期化
app = Flask(__name__)
リダイレクトのルート設定
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def redirect_all(path):
関数の中身
new_url = request.url.replace(request.host, 'feinatelier.org', 1)
return redirect(new_url, code=301)
アプリの起動
if __name__ == '__main__':
port = int(os.environ.get('PORT', 8080))
debug_mode = os.getenv('FLASK_DEBUG', 'False').lower() == 'true'
app.run(host='0.0.0.0', port=port, debug=debug_mode)
私のプロジェクト構成の場合、次の2つの変更方法が考えられました。
どちらも「default URL → 独自ドメイン」へのリダイレクトを実現できます。
こういうときどちらの方法をとるかは、運用のしやすさで考えたほうが良いと思うんですよね。
どちらの方法でも「default URL から独自ドメインへの恒久リダイレクト (HTTP 301)」が実現できますが…
私は2.の静的ハンドラもそのまま活かす方を選択しています。
なぜ2.を選んだのかは、追って説明していきます。
リダイレクト設定を行うdispatch.yaml
dispatch:
- url: "fein-sites-dev1.ew.r.appspot.com/*"
service: redirect-service
このファイルは、Google App Engineでアプリケーション内のトラフィックルーティングを設定するために使います。
「どのリクエスト(URL)をどのサービスに送るか」を決めるルールを書いているってことです。
1. dispatch:
このファイルで「どのリクエストをどのサービスに送るか」という指示を開始します。
2. - url: "fein-sites-dev1.ew.r.appspot.com/*"
ここでは、「すべてのURL(例: /about や /contact)」が含まれるこのドメイン(fein-sites-dev1.ew.r.appspot.com)に対するリクエストをキャッチします。
3. service: redirect-service
上記のURLリクエストを redirect-service に送ります。
これはGoogle App Engine内で動作するサービスの名前で、リダイレクト処理を行うサービスを指します。
このファイルは、Google App Engineの中でどの機能をどのリクエストに対応させるかを分ける「交通整理」の役割を持っています。
エラーが出るとすべてのリクエストが止まる可能性があるため、修正する際には注意が必要です。
App Engine では、複数のサービスを持つ場合、各サービスごとに独自の app.yaml を配置します。
つまりこのプロジェクト内に複数の app.yaml が存在する形になりますが、これは正常な構成です。
メインサービス用とリダイレクト専用のサービス用、2つの app.yaml が存在するわけです。
また、プロジェクトルートに配置する dispatch.yaml によって、 https://fein-sites-dev1.ew.r.appspot.com/ へのリクエストがリダイレクト用サービスに転送されるので、メインサービスの app.yaml に手を加える必要がないのです。
リダイレクト設定に使うrequirements.txt
Flask==2.3.2
gunicorn==20.1.0
このファイルは、Pythonで作られたアプリケーションに必要なライブラリやツールの一覧を記載したものです。
アプリケーションを動かす際に、「どのバージョンのライブラリが必要なのか」を指定します。
ここではPythonのWebフレームワークのFlask==2.3.2を使うよう指定しています。
FlaskはWebアプリを作るためのツールセットです。
例えば、リクエストを受け取ってレスポンスを返す機能や、HTMLを動的に作る機能を提供します。
同様に、ここではPythonのHTTPサーバーのgunicorn==20.1.0を使います。
GunicornはPythonのアプリケーションをサーバーとして動かすためのツール。
Flask単体よりも安定して、同時に多くのリクエストを処理できるようになります。
equirements.txt について特記するなら、各サービスは独立した環境としてデプロイされるため、同じ内容の requirements.txt をそれぞれのサービスのディレクトリに配置しても全く問題ありません。
App Engine
はサービスごとに依存パッケージをインストールするので、メインサービスと redirect-service で同じライブラリ(Flask や gunicorn)を使っていても干渉しません。
もし、コードや設定が共通している部分が多い場合、プロジェクト全体で管理する方法を工夫することも可能ですが…
シンプルな構成の場合は、各サービスディレクトリに同じ requirements.txt
を用意するのが手間も少なく、一般的なアプローチだと思います。
リダイレクト設定を行うapp.yaml
runtime: python312
service: redirect-service
instance_class: F1
env: standard
automatic_scaling:
min_idle_instances: 0
max_idle_instances: 2
max_concurrent_requests: 200
handlers:
- url: /(.*)
script: auto
entrypoint: gunicorn -b :$PORT redirect:app
app.yaml は、Google App Engine (GAE) にアプリケーションをデプロイする際に必要な設定ファイルです。
このファイルには、アプリケーションの基本的な動作方法(ランタイムの種類、スケール方法、リクエスト処理の仕組みなど)が記述されています。
ただし、この設定は駆け出しサイト用です。
ある程度の規模になってくるとこれではアクセスを捌ききれないので、注意してください。
1. ランタイムとサービス名の設定
runtime: python312
service: redirect-service
2. インスタンスの設定
instance_class: F1
env: standard
3. 自動スケーリングの設定
automatic_scaling:
min_idle_instances: 0
max_idle_instances: 2
max_concurrent_requests: 200
4. ハンドラー(リクエストのルール)
handlers:
- url: /(.*)
script: auto
5. 実行エントリポイントの設定
entrypoint: gunicorn -b :$PORT redirect:app
このファイルは、アプリの「設定表」や「設計図」のようなものですよね。
間違った設定をするとアプリが正常に動かないこともあるため、細かい部分まで慎重に作成する必要があります。
リダイレクト設定を一つの app.yaml に書き足すだけで済むケースだってあります。
app.yaml は、App Engineサービス全体の設定ファイルであり、アプリケーションの動作環境、すなわちランタイムやエントリポイント、URLマッピングを定義します。
ここでリダイレクト設定を app.yaml の一部に統合しようとすると、メインアプリ(静的ウェブサイトやFlaskアプリ)の動作と混ざり合ってしまって、平たく言うとややこしいんですよ…
リダイレクト設定があると、/ やその他のルートへのリクエストをリダイレクト用のロジックが処理してしまい、メインのアプリケーションに到達できなくなる可能性があります。
https://feinatelier.org/top のアクセスがリダイレクト設定に奪われるとか。
こういうのを、URLパスの競合と言います。
そもそもリダイレクトは独自の振る舞いが求められるケースが多く、例えば301リダイレクトのHTTPステータスを正確に返す必要があります。
リダイレクトの独立性を損なうようなプロジェクト構成の設計は、望ましくないです。
一方、メインアプリではHTMLや動的コンテンツの提供が優先されるため、同じ app.yaml 内でロジックが混在すると管理が煩雑になります。
現在のように、redirect.pyをredirect-serviceディレクトリに独立させて別のサービスとしてデプロイするアプローチは、App Engineのマイクロサービス設計に適合しています。
App Engineでは、複数のサービスをdispatch.yamlでルーティングできます。
すると、次のように役割を完全に分離した設計が可能になるんです。
こうすることで、互いの振る舞いが影響を与えることなく、独立して動作させることができます。
リダイレクト設定を一つの app.yaml に書き足すだけで済むケースというのは、ルート数が少なく、振る舞いが単純な場合ですよね。
特定のページだけ別のURLへ飛ばすとか。
でも今回のようにプロジェクト構成へ丸ごと独自ドメインを適用するようなケースでは、あまり適切とは言えないでしょう。
現在のアプローチが優れている理由としては、次の3点が挙げられます。
つまり、今後を見据えた柔軟性と保守性を重視して、この設計にしているわけです。
さて、ここまで書けたら、App Engineへのデプロイしましょう。
リダイレクト専用サービスのフォルダ redirect-service へ移動してデプロイしてください。
$ gcloud app deploy app.yaml
次はプロジェクトのルートへ移動してから、そこに配置した dispatch.yaml をデプロイします。
$ gcloud app deploy dispatch.yaml
メインサービスはこれまで通り、プロジェクトルートでgcloud app deployをするのみです。
プロジェクトルートで普通にWebサイトを更新する時には、gcloud app deployコマンドに「app.yaml」をつけなくても良いのですよ?
プロジェクトルートにあるapp.yamlを暗黙的に使うため、明示的にファイル名を書く必要がないからです。
gcloud app deployコマンドは、現在のディレクトリにapp.yamlが存在する場合、自動的にそのファイルを認識して使用します。
つまり、プロジェクトのルートにapp.yamlが配置されている状態でgcloud app
deployとだけ入力すれば、明示的にファイル名を指定しなくてもデプロイが実行されます。
一方で、リダイレクト専用サービスの場合は、フォルダredirect-service内のapp.yamlをデプロイするため、フォルダに移動するか明示的にファイルパスを指定する必要があります。
そのため、次のような手順となっているのです。
このサイトでは現在、app.yaml 内で静的ハンドラとして www/ 以下のコンテンツを配信していますが、デフォルト URL でのアクセスは本ディスパッチ設定によりリダイレクト対象になるため、静的ファイルも自動的に独自ドメインに誘導されるのですよ。
以上が、このサイトに合わせた「App Engine のサービス/ディスパッチ設定でリダイレクトする方法」のソースコード解説になります。
これで https://fein-sites-dev1.ew.r.appspot.com/ へアクセスしたユーザーは自動的に https://feinatelier.org/ へリダイレクトされるってことですね。
Twitterなどでフォロワーさんに「古いURLでアクセスしてみて!」などと、負荷をかけるようなことをしてはいけません。
デプロイ後は、ログなどでリダイレクトが正しく実施されているかを自分で確認しましょう。
$ gcloud app services list
SERVICE NUM_VERSIONS
default 167
redirect-service 1
これが私の検証だとするなら、redirect-service は正常にデプロイされていて、ルーティング設定(dispatch.yaml)によって https://fein-sites-dev1.ew.r.appspot.com/
へのアクセスがこのサービスに振り分けられているのです。
設定は正しく反映されていると考えて良いでしょう。
仮に、ここで「Service Unavailable」などのエラーがブラウザに表示される場合は、リダイレクトサービスのログを確認して、エラーが発生していないかチェックする必要があります。
例えば、以下のコマンドでリアルタイムのログを確認できます。
$ gcloud app logs tail -s redirect-service
redirect-service のエラー内容や動作状況を詳しく把握して、調べてみましょう。
また、次のようにコマンドラインでも、リダイレクトが正しく機能しているか検証できます。
cURL(カール)は、データをURL経由でやり取りするためのコマンドラインツールです。
主にWeb開発やネットワーク管理で使用され、HTTPやHTTPSなどのプロトコルを通じてリクエストを送信し、その応答を確認することができます。
たとえば、「ヘッダーを確認する」という場合、cURLを使うと簡単にHTTPリクエストやレスポンスのヘッダー情報を取得できます。
ここで、あるURL https://example.com のヘッダー情報を取得してみましょう。
$ curl -I https://example.com
このコマンドの結果として、レスポンスのヘッダー情報(例:HTTPステータス、サーバー情報、コンテンツタイプなど)が表示されます。
これを独自ドメインのリダイレクト設定チェックに使うなら、次のようにターミナルやコマンドプロンプトから以下のコマンドを実行します。
$ curl -I https://fein-sites-dev1.ew.r.appspot.com/
HTTP/1.1 301 Moved Permanently
Location: https://feinatelier.org/
HTTP レスポンスのヘッダー情報だけが表示されます。─ 実際にはもっといろいろ出ますよ? ─
このように、Location ヘッダーにリダイレクト先の URL が記載されていること、また 301 ステータスが返っていることを確認してください。
この方法でリダイレクトが正しく設定され、https://fein-sites-dev1.ew.r.appspot.com/ から https://feinatelier.org/ に転送されていることを確かめることができます。
全ページをリスト化したサイトマップも用意していますが、けっこうなページ数があります。
下記の「カテゴリー分けサイトマップ」のほうが使いやすいでしょう。
アナザーエデンの強敵戦やストーリーコンテンツのリスト、お勧めバッジなどを掲載したコーナーです。
期間限定のない普通のRPGですので、初心者でも安心して続けていけるゲームとなっています。
もっとも重要なグラスタについては、場所別に網羅した表があります。
個人でウェブサイトを作るにはどうすればいいか。
HTML・CSS・JavaScriptの書き方はもちろん、無料かつ広告なしでホームページを作る方法を掲載したコーナーです。
Webデザインやレイアウトについても書いてあります。
ゲームとパソコンだけじゃなく、アウトドアも趣味なんです。
このコーナーでは魚釣りの記録とか、魚料理のレシピ、はたまたサイクリングなどなど。
アウトドアに関連するコンテンツが詰め込まれています。