App:https://flask-shorty.onrender.com/ ※1
App:https://pg-lab.ysnko.com/flask-shorty.cgi
GitHub:https://github.com/ynakao55/flask-shorty※1 サービスが停止している場合は、起動に50秒程かかります。
Flask と PostgreSQL、Render を使ってURL短縮サービスを作成・公開しました。
この記事では、アプリの説明/学んだ技術/主要ファイル/Renderでのデプロイ要点をまとめます。
これ一つで、Webアプリ開発の基本要素(ルーティング、DB、テンプレート、環境変数、デプロイ)が一通り体験できます。
目次
アプリの説明
何をするアプリ?
入力された URL を 6文字コードで短縮し、/<code> にアクセスすると元URLへリダイレクトします。
トップページには直近で作成された短縮URLの一覧とクリック数が表示され、削除ボタンで不要な短縮をDBから消せます。
主な機能
- URL短縮(6文字の英数字コードを自動生成)
- 既存URLの再利用(同じURLは重複作成しない)
- 短縮URLへのアクセス数(clicks)のカウント
- 最近作成した短縮一覧+削除ボタン(確認ダイアログ付き)
- 基本的なバリデーション(
http(s)://付与・形式チェック) - 404/500 の簡易エラーページ
/healthヘルスチェック
技術スタック
- Flask 3.x(ルーティング/テンプレート)
- SQLAlchemy / Flask-SQLAlchemy(ORM)
- PostgreSQL(RenderのマネージドDB)
- Jinja2(テンプレート)
- Bootstrap 5(UI)
- gunicorn(本番サーバ)
- python-dotenv(ローカル環境変数の読み込み)
- validators(URLチェック)
学んだ技術とハマりどころ
1) ルーティングとフォーム処理
GET /:入力フォーム表示、最近の短縮リンク一覧POST /shorten:短縮URL作成GET /<code>:元URLへ302リダイレクトPOST /links/<id>/delete:DBから削除(今回追加)
2) DBモデリングとORM
- Link テーブル
id, original_url, short_code(unique), clicks, created_at - 重複URLは既存レコードを再利用して無駄な増殖を防止。
- クリック数はアクセス時に
UPDATE clicks = clicks + 1。
3) 環境変数と接続文字列
- Renderの
DATABASE_URLはpostgres://形式のことがあるため、SQLAlchemyで扱えるpostgresql://に自動置換。 - さらにドライバ切り替え時は
postgresql+psycopg://を使う設計も視野に。
4) デプロイ時のPythonバージョンとDBドライバ
psycopg2-binaryは Python 3.13 と相性問題が出やすい。- Python 3.10〜3.12 に固定し、
psycopg2-binary==2.9.9を使うと安定。 - Render の Environment で
PYTHON_VERSIONを指定するとよい(例:3.10.11)。
主要なファイルの説明(抜粋)
flask-shorty/
app.py # ルート定義、DBモデル、短縮ロジック
requirements.txt # 依存パッケージ(Flask, SQLAlchemy, psycopg2-binary など)
Procfile # 本番起動コマンド(gunicorn)
.env.example # ローカル開発用の環境変数サンプル
templates/
base.html # レイアウト
index.html # フォーム+最近の短縮URL一覧(削除ボタン付き)
result.html # 作成後の表示(コピー用UI)
404.html / 500.html # 簡易エラーページ
static/ # 必要ならCSS/JS/画像など
app.py の要点
- Linkモデル(
short_codeに unique index) - コード生成:
secrets.choiceで6文字を生成(衝突時はリトライ) - URL正規化:スキーム補完(
example.com→http://example.com) - DB初期化:初回アクセス時に
db.create_all() - 削除ルート
Render デプロイの要点(チェックリスト)
1) リポジトリ準備
requirements.txt:Flask/Flask-SQLAlchemy/SQLAlchemypsycopg2-binary==2.9.9(Python 3.10〜3.12 推奨)gunicorn/python-dotenv/validators
Procfile:web: gunicorn app:app.envはコミットしない(.env.exampleは可)
2) Pythonバージョン固定
- Render ダッシュボード → Environment に
PYTHON_VERSIONを追加(例:3.10.11)
3) サービス作成
- PostgreSQL(Mananged DB)を先に作成 →
DATABASE_URLを取得 - Web Service を「Create」→ リポジトリを選択
- 環境変数:
DATABASE_URL(Renderの値。postgres://はアプリ側で自動置換)SECRET_KEY(本番用の十分長いランダム文字列)APP_BASE_URL(任意。外部公開URLを固定したい場合)
4) ビルド&起動
- Start は
Procfileを自動検出(web: gunicorn app:app) - DBマイグレーション不要(
create_all()で自動作成) - うまくいかない時は Clear build cache → Manual deploy を実行
5) 動作確認
/でフォーム表示 → 短縮 →/<code>でリダイレクト確認- 一覧にクリック数が増えるか、削除が効くかチェック
スクリーンショット
トップページ(フォーム+一覧)

短縮結果画面(コピーUI)


404/500 ページ

伸びしろ(次の一手)
- 認証(ログインユーザーだけ削除可能に)
- 短縮コードのカスタムエイリアス
- 有効期限の設定、パスワード付き短縮
- API化(
/api/shorten)と簡単なフロントSPA - CI(テスト1本でもOK)&自動デプロイ
まとめ
- 最小構成でも、DB連携→動くWeb→本番デプロイまで一気通貫で形にできたのが今回のポイント。
- Render上のPythonバージョンとDBドライバは実務でもハマりやすい箇所で、ここを自力で突破できたのは強い実績になります。
- 次は Rails / Django / Laravel でも同レベルのCRUDアプリを公開し、「複数フレームワークでデプロイまでやり切れる」ことを示していきます


コメント