【無料】WebアプリをRenderで公開する方法｜初心者でも簡単デプロイ

# はじめに
完全無料で自作のwebアプリを公開して、だれでもアクセスできるようにしたいと思い試行錯誤した結果、上手くいったものをここに残します。
webアプリのデプロイと言えば、AWSやGCP、Azureなどが思い浮かびますが、
>AWSは高そう...
>GCPは無料枠があるけど、天井付き...
>Azureはよくわからん...

というようなイメージが私にはありました。
完全無料で恒常的にアプリを公開したかったのでいろいろと調べた結果、Renderというサービスにたどり着きました。
RenderではGitHubのリポジトリを投げるだけで、自作のwebアプリを無料でデプロイすることができます。
今回はFlaskで開発したwebアプリを公開する方法を紹介します。

- [1. GitHubでリポジトリを用意する](#1-githubでリポジトリを用意する)
    - [ディレクトリ構成](#ディレクトリ構成)
    - [ソースコード](#ソースコード)
- [2. Renderにデプロイする](#2-renderにデプロイする)
- [3. 継続的にサイトに接続できるようにする](#3-継続的にサイトに接続できるようにする)

## 1. GitHubでリポジトリを用意する
### ディレクトリ構成
まず、以下のようなディレクトリ構成でプロジェクトを作成します。app ディレクトリの中にはFlaskアプリの本体を格納しておきます。それ以外のファイルはRenderにデプロイするために必要なソースコードです。

> app/
> 　├ templates/
> 　│　├ [base.html](#basehtml)
> 　│　└ [index.html](#indexhtml)
> 　├ [\_\_init\_\_.py](#__init__py)
> 　└ [routes.py](#routespy)
>[config.py](#configpy)
>[requirements.txtt](#requirementstxt)

### ソースコード

#### base.html
```html:base.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <style>
        /* ここにスタイルを書く */
    </style>
    {% block head %}{% endblock %}
</head>

<body>
    {% block body %}{% endblock %}
</body>

</html>
```

このHTMLファイルは、すべてのページのベースとなるテンプレートです。{% block head %} や {% block body %} のようにJinja2テンプレート構文を使っていて、他のページから内容を差し込めるようになっています。CSSの読み込みや基本レイアウトはここに定義しておきます。
##

#### index.html
```html:index.html
{% extends "base.html" %}

{% block body %}

<tbody>
    
    <h1>RenderDEMO</h1>
    
</tbody>


{% endblock %}
```

base.html を継承して表示するトップページです。{% block body %} の中に独自の内容を挿入しており、ここでは「RenderDEMO」という見出しが表示されるようになっています。
##

#### \_\_init\_\_.py
```python:\_\_init\_\_.py
import os
from flask import Flask
from .routes import main
from config import Config

def create_app():
    app = Flask(__name__)

    app.config.from_object(Config)
    app.register_blueprint(main)

    return app

app = create_app()

if __name__ == "__main__":
    app.run()
```

Flaskアプリのエントリーポイントを定義するファイルです。create_app() 関数を通してアプリケーションインスタンスを生成し、設定やルーティングを初期化しています。最後の if __name__ == "__main__": ブロックは、ローカル実行時に app.run() を呼び出すための記述です。
##

#### routes.py
```python:routes.py
from flask import Blueprint, redirect, url_for, Flask, jsonify, render_template, flash, render_template_string, request,g, session

main = Blueprint('main', __name__)

@main.route('/')
def index():
    
    return render_template('index.html')
```

実際のルーティング（URLと処理の紐づけ）を定義するファイルです。Blueprintを使うことでアプリをモジュール化し、複数の機能を分離して開発・管理しやすくしています。今回はルートパス / にアクセスしたときに index.html を返すだけのシンプルな実装です。
##

#### config.py
```python:config.py
import os

class Config:
    SECRET_KEY = os.getenv('SECRET_KEY')
```

Flaskの設定をまとめるクラスです。ここではセッションなどに必要な SECRET_KEY を環境変数から読み込んでいます。Renderでの環境変数の設定方法も後述します。
##

#### requirements.txt
```text:requirements.txt
Flask==2.2.2
gunicorn==22.0.0
psycopg2-binary
Werkzeug==2.2.2
```

アプリで使用するPythonライブラリを記載するファイルです。Renderはこのファイルをもとに、必要な依存パッケージを自動でインストールしてくれます。
##

## 2. Renderにデプロイする
まず[Render](https://dashboard.render.com/)にログインします。
そして Add new > Web Service を選択します。

![スクリーンショット (638).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4079836/d8cc3ab4-aa4f-49e5-89af-8b56bf7abbe1.png)

GitHubアカウントと連携して、対象リポジトリを選びます。
LanguageがPythonになっていることとブランチ名を確認して下さい。
必要に応じてStart Commandを以下のように変更してください。
```
gunicorn [Flaskアプリケーションインスタンスを保持しているファイル名]:[そのインスタンスの変数名]
```

今回は画像のままで大丈夫です。
料金は必ずFreeを選択するようにしましょう。
![スクリーンショット (644).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4079836/a54ecbe7-203a-4869-b51e-49556b38752d.png)

環境変数を設定する場合は、以下のようにKeyとValueを設定します。
![スクリーンショット (641).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4079836/4209560e-1424-452d-91a1-f5f908cfd9f0.png)

すべて設定したら「Deploy Web Service」を押せばデプロイが始まります。

「Your service is live」と表示され、GitHubのリポジトリ名の下に表示されているURLをクリックすると「RenderDEMO」と表示されるはずです。
![スクリーンショット (642).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4079836/7c949a04-e63e-40ae-9e06-e63c069916c1.png)

## 3. 継続的にサイトに接続できるようにする
RenderのFreeプランでは、15分間リクエストがないとスリープ状態になります。
これを回避するために、[Uptime Robot](https://dashboard.uptimerobot.com/monitors?ref=website-header) を使って定期的にアクセスさせましょう。

サインアップしてダッシュボードに移動したら、New monitorをクリックします。

![スクリーンショット (645).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4079836/b415f17e-c024-4717-b59d-5e648243ead7.png)

デプロイしたサービスのURLを入れて、他は特に変更せずにCreate monitorをクリックすれば完了です。
![スクリーンショット (646).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4079836/89a6545c-49a5-4de1-8445-40c6386655cd.png)

これで5分おきにアクセスが発生し、スリープ状態になるのを防げます。

# おわりに
今回は、完全無料でFlaskアプリをRenderにデプロイする方法を紹介しました。
AWSやGCPのような複雑な設定は不要で、GitHubにリポジトリを用意するだけで非常に簡単にWebアプリを公開できます。

個人開発のポートフォリオ公開や、小規模なアプリを継続的に公開したいときにとても便利なので、ぜひ活用してみてください。

## 参考

<iframe width="560" height="315" src="https://www.youtube.com/embed/IBfj_0Zf2Mo?si=y2icsGSzvpQJNxU4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

https://qiita.com/sykx_16g/items/40ae3015479fdfbfa10e

https://render.com/

https://uptimerobot.com/