Hirologue

年齢を理由にエンジニアになることを諦めないミドルの成長記録

EP 29: 50歳の挑戦(8ヶ月目を振り返る)

2024年3月1日にHappiness Chain(以下、HC) Euforia 2期生として入会してから早いもので8ヶ月が経過しようとしています。
本記事では、この一ヶ月間で学んだことをダイジェストで振り返りたいと思います。

50歳目前の私が入会を決意するまでの経緯を書いたポエムは👇こちら hirologue.hateblo.jp


10月の学習時間(期間:9/30 - 10/30)

10月の学習時間は 126 時間 / 31日 でした。
学習日数が31日ですので、一日あたりの学習時間は 244分(4時間4分)となりますね。

今月も学習時間の目安として、休日は8時間、平日は3時間を基本としました。
今月の目標学習時間は138時間の設定です。

目標学習時間には 12時間足りず目標達成率としては91%でした。
一日だけ疲労の蓄積により完全休養日を設けましたが、それ以外の日はきっちり学習できました。

さて、10月1日は世間では下半期のスタートとなっていましたが、わたしにとっては人生の下半期とも言える50歳の大節目を迎えた日でもありました。

そういったこともあり、今月の月報記事からタイトルは「50歳の挑戦」にバージョンアップしました。
果たして、この50歳はこの10月に何を学び、何を感じたのか返ってみましょう。


10月の学習内容

9月はDjangoのインプットを一通り終え、アウトプットとして架空のECサイト作成に着手したところで終わりましたので、10月はその続きです。

ECサイト(商品一覧と商品詳細機能の実装)

先月に時間をかけてしっかりインプットをしたお陰で、商品一覧と商品詳細機能は予想していたよりもすんなりコードを書き進めることができました。
自分のPC(ローカル環境)上で思うように商品一覧と商品詳細画面を表示することができました。

大成功です。

話は変わりますが、わたしの両親は「ぼたもち」を作って、近所の産直やスーパーに卸しています。
添加物なし、完全手作りな上に老夫婦二人だけで作っているため通販はできないのですが、「もし、両親のつくるぼたもちを通販するなら」ということを思い浮かべながらECサイトを作成しています。

そこで、思いました。

「誰かのためになるものを作るのは楽しいし、誰かの役に立ちたい」

そのためには、もっと技術がほしい。もっと頑張ろう。

デプロイに挑戦

ローカル環境で表示できてもWebアプリである以上、他の人に見てもらい使ってもらえなければ意味がありません。
そのためにはHerokuに代表されるような、アプリを実行できる環境(本番環境)でアプリを動作させる必要があります。
今回は本番環境としてHerokuを利用することにしました。
また、ローカル環境で作成したアプリを本番環境で利用できるようにすることをデプロイといいます。

Herokuにもこれまでと同様にチュートリアルが用意されていたので、まずはチュートリアルからスタートしました。

「ああ、なんだ、書いてあるとおりにやればデプロイ余裕じゃないか」

と思いきや、苦労の連続で、HC入会以来最も苦労したのではないかと思います。

エラーが出てログを読んで解決できることは稀でしたし、それではと、ググっても真贋のほどが定かでない情報であったり、古い情報であったりと調べれば調べるほど混乱する一方。

それならばと、ChatGPTを使ってみるも自分のプロンプトが不十分なのもありトンチンカンな回答であったりと、「無理かも・・・」が頭をよぎることもありました。

そんなときに頼りになったのは、他のHC生の投稿(times)でした。
そこからヒントを得て調べながらなんとかデプロイ完了です。
完了まで20日以上要しましたが、同じ目標に向かって進む仲間の存在が本当にありがたく、感謝しかありません。
いやぁ、本当に強敵でした。

苦労した原因を分析したところ、Herokuへのデプロイについて体系的な情報を見つけることができなかったからだろうという結論に至りました。

それなら、自分がまとめて記事にすればいい。

ということで、全5回のシリーズでHerokuへのデプロイについてブログ記事を作成しました。

ブログ記事を作りながら思いました。
「記事作るの面倒くさい。でも、記事を書くことでもっと理解できる!」

苦労して足止め食らったから、遅れを取り戻そうと先を急ぐのではなく、しっかりブログ記事などでアウトプットする。
この考えは本当に大事なことなんだなと、あらためて感じました。

今月はここまでとなります。


今月の感想

上述のとおり、Herokuへのデプロイが完了するまで20日以上を要しました。
エラーなどで躓く、調べる、少し進展するの繰り返しで、振り返ってみれば少しずつ前に進む日々でした。
全くのお手上げになることはなかったのですが、どこで質問をするべきか、そのタイミングが難しいなと思いました。

いつでも頼れる人に質問できる素晴らしい環境で学習できているのに、質問しないのは非常にもったいないので、

次月の目標はずばり
「質問する」
これで行きたいと思います。


11月のターゲット



Hirologue 第2章「50歳の挑戦」がはじまりました。

個人的には50歳を迎えたからといって、何か特別変わったわけでもないのですが、40代と50代ではその数字から受ける印象は全く違います。

年齢からくるハンディキャップは否めません。

しかし、わたしは若かりしに日に夢見たエンジニアになりたい!
父からの教えは「男だったら有言実行」

やると決めたらやる、そして家族を幸せにする使命がわたしにはある。

仲間からは、「マジで?その年で転職するの?失敗したらどうするの?」と言われることもあります。

そのたびにリアルタイムでTV視聴していた、この場面が脳内再生されます。

www.youtube.com

燃える闘魂!燃えろ俺

では、また来月🔥

EP 28: Herokuものがたり 〜 Cloudinary編

前回までのあらすじ

Djangoで作成したアプリをHerokuにデプロイするための準備を行い、静的ファイル処理(whitenoise)とデータベース(PostgreSQL)を取り扱うための設定をしました。



目次


クラウドストレージの利用

Herokuではアップロードされたファイルは一時的に保存されます。
しかし、アプリの再起動や新しいデプロイが行われるたびに、これらのファイルが消去されるため、長期保存には向いていません。
そのため、画像などのメディアデータはAmazon S3やCloudinaryといったクラウドストレージサービスを介して扱うのが一般的です。

今回は、無料プランが用意されている(2024年10月現在)Cloudinaryを用いて画像ファイルを保存し、読み込めるように設定します。

Cloudinaryの追加

Cloudinaryのプランの内容については、こちらからご確認ください。
プランは無料プランであるstarterを選択します。

では、ターミナルから次のコマンドを入力して、Cloudinaryのアドオンを追加します。

$ heroku addons:create cloudinary:starter


アドオンが正常に追加されているか確認するために、次のコマンドを入力します。

$ heroku addons


Cloudinaryが追加されていることを確認して次に進みましょう。

環境変数の確認と設定

Cloudinaryを追加した際に環境変数CLOUDINARY_URLが自動で設定されています。
まずは、次のコマンドを入力してHerokuに設定されている環境変数の一覧を表示させましょう。

$ heroku config


出力された環境変数の中にCLOUDINARY_URLが確認できると思います。

このCLOUDINARY_URLの値は以下のような構成となっています。

CLOUDINARY_URL:  cloudinary://<api_key>:<api_secret>@<cloud_name>


この中にあるapi_key, api_secret, cloud_name を使ってこの先の設定を進めます。

では、.envファイルにこれらの環境変数を定義しましょう。

CLOUD_NAME='<cloud_name>'
CLOUDINARY_API_KEY='<api_key>'
CLOUDINARY_API_SECRET='<api_secret>'

# シングルまたはダブルクォートで囲むのを忘れずに


次にHerokuの環境変数をHeroku CLIを使って設定します(Herokuダッシュボードから入力してもOKです)。

$ heroku config:set CLOUD_NAME=<cloud_name>

$ heroku config:set CLOUDINARY_API_KEY=<api_key>

$ heroku config:set CLOUDINARY_API_SECRET=<api_secret>

# シングルまたはダブルクォートは不要です

注)
ローカル環境と本番環境でアップロード先を同じにすることはお勧めできません(今回はCloudinaryの設定を解説するためにこのようにしています)。
ローカル環境のアップロード先はローカルのディレクトリにすることが望まれます。


base.pyの設定

共通する設定を記述したbase.pyにアプリの登録とストレージの設定を記述します。

アプリの登録

Cloudinaryを使用するためにINSTALLED_APPSのリストの中にcloudinary_storagecloudinaryを追加します。

INSTALLED_APPS = [
    'django.contrib.admin',
    (略)
    'django.contrib.staticfiles',
    'cloudinary_storage',  # 追加
    'cloudinary',  # 追加
]



ストレージの設定

静的ファイルの設定編で設定したSTORAGESに設定を追加します。
STORAGESに追記する内容は以下のとおりです。

'default': {"BACKEND": 'cloudinary_storage.storage.MediaCloudinaryStorage',}


追加後のSTORAGESはこのようになります。

STORAGES = {
    # 静的ファイル
    'staticfiles': {
        'BACKEND': 'whitenoise.storage.CompressedManifestStaticFilesStorage',
    },
    # 画像アップロード
    'default': {
        "BACKEND": 'cloudinary_storage.storage.MediaCloudinaryStorage',
    },
}




アップロード設定

今回はローカル環境と本番環境で同じアップロード先としていますので、local.pyproduction.pyに記述する内容は同じです。

ということで、次のコードをlocal.pyproduction.pyそれぞれのファイルの最後に付け足します。

CLOUDINARY_STORAGE  = {
    'CLOUD_NAME': env('CLOUD_NAME'),
    'API_KEY': env('CLOUDINARY_API_KEY'),
    'API_SECRET': env('CLOUDINARY_API_SECRET')
}


以上で設定は完了です。

最後にローカル環境、本番環境で画像をアップロードとアプリで読み込んで動作確認しましょう。



大変お疲れ様でした!

全5回にわたってHerokuの設定について取り上げましたが、いかがだったでしょうか?

私自身、このような設定が本当に苦手で公式チュートリアルや生成AIなどあらゆるツールを使ってトライ・アンド・エラーを繰り返し設定を完了させました。
そこでの学びをアウトプットするという目的もあり本シリーズの記事を作成しました。
本シリーズがHerokuの設定で心が折れそうになっている方の助けになれば幸いです。

次の記事は10月の学習内容の振り返り記事になるかと思います。
では、また次の記事で!✋️

EP 27: Herokuものがたり 〜 PostgreSQL編

前回までのあらすじ

Djangoで作成したアプリをHerokuにデプロイするための準備を行い、whitenoiseを使って静的ファイルの処理を行えるようにしました。



目次


データベースの設定

Heroku Postgresの追加

HerokuではPostgreSQLを公式でサポートしていて、使うにはHeroku Postgresというアドオンが必要です。
ただし、このアドオンは無料で利用することができません。
最低でも月額$5〜の利用料金が発生します(2024年10月時点)。
利用にあたってのプランと料金はこちらからご確認ください。

では、ターミナルから次のコマンドを入力して、Heroku Postgresを追加します。

$ heroku addons:create heroku-postgresql:essential-0


アドオンが正常に追加されているか確認するために、次のコマンドを入力します。

$ heroku addons


Heroku Postgresが追加されていることを確認します。


ところで、こちらの記事の中で環境変数DATABASE_URLの設定を後回しにしていました。
こちらの環境変数は、Heroku Postgresを追加した時点で自動的に設定されます。

では、次のコマンドを入力して環境変数の一覧を確認しましょう。

$ heroku config


出力された環境変数の中にDATABASE_URLが確認できたら、次のステップに進みましょう。

Procfileに設定を追記

モデルの変更があった場合は、ローカルでmakemigrationsコマンドを実行することでマイグレーションファイルが作成され、gitによるバージョン管理の対象となっています。

しかし、$ git push heroku mainコマンドを実行してデプロイしてもmigrateコマンドは自動で実行されません。
これでは、ちょっと不便なので解決しましょう。

デプロイ時にmigrateコマンドを自動で実行するためには、Procfileに次の内容を追記する必要があります。

release: ./manage.py migrate --no-input


このコマンドは、Herokuにデプロイした際のreleaseフェーズでmigrateを自動的に実行してくれるものです。
--no-inputオプションは、コマンド実行時にユーザーの入力を求めずに処理を進めるための設定です。

この設定によって、デプロイのコマンドを実行するだけで自動でマイグレーションが行われることになりますので忘れずに設定しましょう。

参考: Heroku スターターガイド (Python) | Heroku Dev Center


psql

psqlは、PostgreSQLをターミナルから操作するためのツールで、データの確認や管理を行う上で必要不可欠なものです。
ローカル環境のみならず、本番環境のPostgreSQLデータベースにも簡単に接続できます。

Dockerコンテナで使う(ローカル環境)

今回のようにDockerを使って開発を行っている場合は、インストールは不要です。次の手順でpsqlを実行します。

次のコマンドを入力してコンテナのリストからPostgreSQLのコンテナ名を調べます。

$ docker ps

出力結果でIMAGES列がpostgresの行にあるNAME列がコンテナ名です。

docker-compose.ymlファイルでPOSTGRES_USERPOSTGRES_DBの値を確認します。

では、確認したところで、次のコマンドを入力してpsqlを実行します。

$ docker exec -it <コンテナ名> psql -U <POSTGRES_USERの値> -d <POSTGRES_DBの値>


以下に入力例を示します。

"""
例
コンテナ名: my_project-db-1
POSTGRES_USER: postgres
POSTGRES_DB: django_develop
"""

$ docker exec -it my_project-db-1 psql -U postgres -d django_develop

コマンドを実行するとローカル環境のPostgreSQLデータベースに接続されます。

しかしながら今回は、Dockerを使った開発環境にHeroku CLIを組み込んでいないため、このままでは本番環境のPostgreSQLデータベースに接続することができません。

本番環境のPostgreSQLデータベースに接続するためには、ローカルマシンでpsqlが実行できるようにする必要があります。

ローカルマシン上で使う(本番環境)

ローカルマシンでPostgreSQLのクライアントツールであるpsqlを実行するためには、libpqをインストールする必要があります。

Homebrewを使ったインストールは以下の手順で行います。

# Homebrewを最新にする
$ brew update

# libpqのインストール
$ brew install libpq

# シンボリックリンクの作成
$ brew link --force libpq

注意:シンボリックリンクを作成しないとパスが通らず、正常に動作しないのでご注意ください。

では、本番環境(Heroku)のPostgreSQLデータベースに接続します。

$ heroku pg:psql


PostgreSQLを操作するコマンドは、こちらの記事が参考になります。 qiita.com

本番環境の動作確認

設定が完了したので、本番環境にデプロイしましょう!
ただし、この状態ではローカル環境で作成したデータは反映されていないので、本番用のデータを作成します。

そのためには、次のコマンドを入力してスーパーユーザーを作成します。

$ heroku python manage.py createsuperuser


このあとの操作はチュートリアルと同じ操作になりますので割愛しますが、本番用のデータを登録して表示されるか確認して終了となります。



おつかれさまでした!

データは無事に本番環境へ反映されたでしょうか?

今回を含めて4回にわたってHerokuの設定について取り上げてきましたが、次回いよいよ最終回となります。

最終回は画像アップロードについて解説しますので、お楽しみに

では、また次の記事で!✋️

EP 26: Herokuものがたり 〜 静的ファイル設定編

前回までのあらすじ

Djangoで作成したアプリをHerokuにデプロイするための基本的な設定を行い、実行環境によって読み込むファイルを切り替える設定を行いました。



目次



動作確認

ローカル環境

本番にデプロイできる準備が完了したので、本番環境へデプロイと行きたいところですが、その前にローカル環境できちんと動作するか確認しましょう。

Dockerを使っているので入力するコマンドは、お決まりのコマンドです。

$ docker compose up

settings.pyを分割する前と変わらずアプリが表示されたら、ローカル環境の設定はクリアです。
エラーが出る場合は、どこかに打ち間違いがないか十分確認しましょう。

本番環境

では、いよいよHerokuにデプロイです。
Herokuにデプロイするためのコマンドは、ブランチを切っているかどうかで書き方が違うので、注意が必要です。

  • mainブランチをデプロイする場合
$ git push heroku main


  • ブランチを切った状態でデプロイする場合
$ git push heroku <ブランチ名>:main


例えばブランチ名が、 feature の場合は次のように入力します。

$ git push heroku feature:main


git pushコマンドを使うので、実行前にgit commitコマンドを忘れずに実行しましょう。

デプロイするとログがたくさん流れますが、プロジェクト内に静的ファイルがある場合は、ビルド中にエラーが出ると思います。
出力結果を遡ると、次のように書いてあるはずです。

remote: -----> $ python manage.py collectstatic --noinput
remote:        Traceback (most recent call last):
remote:          File "/app/.heroku/python/lib/python3.12/site-packages/environ/environ.py", line 388, in get_value
...

どうやら、Herokuにデプロイする際に
$ python manage.py collectstatic --noinput​が自動的に実行されることが原因のようです(参考: Django と静的アセット | Heroku Dev Center)。

これを回避するため、デプロイ時に自動で実行しないように設定を変更する必要があります。
ターミナルから次のコマンドを入力しましょう。

$ heroku config:set DISABLE_COLLECTSTATIC=1

このコマンドで一時的にcollecstaticを無効にしますが、後ほど元に戻します。

これでもう一度デプロイするとビルドが成功して、ログを少しだけ遡るとこのようなログが確認できると思います。

...
remote:        https://<アプリの名前>.herokuapp.com/ deployed to Heroku
...

このhttps://<アプリの名前>.herokuapp.com/が、デプロイ先のURLです。
しかし、まだアプリは正常に表示されません。

なかなか一筋縄ではいきませんが、一つずつ確実にクリアしていきますのでご安心ください。



whitenoise

ここでローカル環境では上手く表示できたのに、なぜ本番環境では正常に表示されないのか疑問に思った方もいるかと思います。
公式ドキュメントには次のように理由が記述されています。

Django では、本番環境での静的ファイルの処理がサポートされていません。

つまり、追加で何かしらの設定をしないと静的ファイルは処理されないということです。

ということで、この問題を解決するのがwhitenoiseです。

whitenoiseの設定(その1)

whitenoiseの設定はローカル環境と本番環境で共通にします。
したがって、base.pyに必要な設定を記述します。

まずは、MIDDLEWAREの中にwhitenoiseを追記します。

(略)
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # この位置に追記
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
(略)

このwhitenoiseの記述位置については罠がありまして・・・
whitenoiseドキュメントにひっそりと次のように書いてあります。

settings.py ファイルを編集し、 MIDDLEWARE リストに WhiteNoise を追加してください。
WhiteNoise ミドルウェアDjango SecurityMiddleware (もし使っているなら) の直後で、他の全てのミドルウェアの前に置く必要があります。


「俺でなきゃ見逃してるね」

whitenoiseの設定(その2)

続いて、STATIC_URLSTATICFILES_DIRSSTATIC_ROOTSTORAGEの設定を行います。

base.pyに次のように記述します。

STATIC_URL = 'static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
STATIC_ROOT = BASE_DIR / 'staticfiles'

STORAGES = {
    'staticfiles': {
        'BACKEND': 'whitenoise.storage.CompressedManifestStaticFilesStorage',
    },
}


サイトによってはSTORAGESの部分の書き方が次のようになっているものもあります。

STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"

Django4.2からはこの書き方ではなくなったようですので、ご注意ください。

ローカル環境でもwhitenoiseを使う設定

ローカルでは静的ファイルをサポートしているので、ローカル環境でwhitenoiseを使う必要はないとも思えますが、whitenoiseドキュメントには、このように書いてあります。

開発環境では、Django の runserver が自動的に静的ファイルの処理を引き継ぎます。 たいていの場合、これは問題ありませんが、WhiteNoise が静的ファイルハンドリングに施した改良のいくつかが開発環境では利用できなくなり、開発環境と本番環境で動作が異なる可能性が出てきます。
Runserver コマンドに --nostatic オプションを渡すだけで、 Django の静的ファイルハンドリングを無効にして WhiteNoise に引き継がせることができますが、runserver を呼び出すたびにこのオプションを追加するのを忘れないようにする必要があります。
もっと簡単な方法は、 settings.py ファイルを編集して、 whitenoise.runserver_nostatic を INSTALLED_APPS リストの先頭に追加することです

要するにこうです。
ローカルと本番の環境を統一した方がいいので、local.pyINSTALLED_APPSのリストの先頭にwhitenoise.runserver _nostaticを追加しましょう。


では、local.pyに設定を追加しましょう。

# config/settings/local.pyの末尾に以下のコードを追記
(略)
INSTALLED_APPS.insert(0, 'whitenoise.runserver_nostatic')



静的ファイルに関する動作確認

静的ファイル関係の設定が上手くいったのか確認する前に、htmlファイルの内容を見直しましょう。
もし、ファイル内にデータベースからデータを持ってくるような記述があるようなら、その部分はコメントアウトします。

確認が済んだら、デプロイする前に本番環境の環境変数DISABLE_COLLECTSTATICを元に戻しましょう。
ターミナルから次のコマンドを入力します(Herokuダッシュボードを使用して削除しても可)。

$ heroku config:unset DISABLE_COLLECTSTATIC


では、DISABLE_COLLECTSTATICの設定を削除したところで、ローカルで動作確認→本番環境にデプロイの順で進めましょう。



動作確認は無事にできたでしょうか?

もし、エラーが出た場合は、タイプミスを疑いましょう。
わたしもカンマ( , )が抜けてただけといったタイプミスに気づくことができずにかなりの時間を溶かしました!

今の時代、自分で解決できないことって生成AIがサクッと解決してくれたりしますので、数分悩んだら時間を無駄にしないためにも積極的に利用しましょう。

次回は、PostgreSQLの設定について解説する予定です

では、また次の記事で!✋️

EP 25: Herokuものがたり 〜 settings.py分割編

前回までのあらすじ

Djangoで作成したアプリをHerokuにデプロイするための基本的な設定を行いました。

hirologue.hateblo.jp



環境で設定を使い分ける

settings.pyの例えば環境変数 DEBUGのように、ローカル環境ならTrue、本番環境ではFalseと環境に応じて異なる値をセットする必要があります。

それならと、settings.pyの中でif文を使って条件分岐する方法もあるようですが、よく考えてみてください。
ローカル環境で DEBUG = True、本番環境で DEBUG = Falseと必ず設定されているだろうか?

そのように設定されているかもしれないが、設定されていないかもしれないというのが実際のところだと思います。
そうなると、どうやら一つのファイルで設定方法を分岐させるのは、ベストプラクティスではなさそうです。

それでは、どのようにして分けるべきか?

ローカル環境と本番環境でファイルを分けるという方法がベストプラクティスと言われています。
設定ファイルを分けることで、環境に応じた設定変更が簡単にできたり、設定ミスの低減といったメリットを享受することができます。

本記事では、設定ファイルのsettings.pyをローカル環境と本番環境で切り替えて使用する方法について解説します。

ディレクトリ構成

初めにconfigディレクトリ直下にsettingsディレクトリを作成します。
このディレクトリの中に設定ファイルを格納することになります。

次に__init__.pyファイルを作成します(ファイルの中身は空でOKです)。
また、既存のsettings.pyをこのディレクトリの中に移動させて、ファイル名をbase.pyに変更します。

このリネームしたbase.pyにローカル環境と本番環境で共通する設定を記述します。
文字通りbaseとなるセッティングファイルです。

そして、ローカル環境と本番環境それぞれに対応する設定を記述するファイルとして、local.pyproduction.pyを新規作成します。

configディレクトリの構成は下図のようになります。

configディレクトリの構成


base.pyのBASE_DIRを修正

ディレクトリ構成が変更になったことに伴い、base.py内で定義しているBASE_DIRのパスを修正する必要があります。

settingsディレクトリを追加して階層が一つ増えたので、その部分を次のように修正します。

# 末尾に.parentを追加
BASE_DIR = Path(__file__).resolve().parent.parent.parent



local.pyにローカル環境用の設定を書き込む

では、ローカル環境用の設定をlocal.pyに書いていきます。
初めに書くべきは、共通設定が記述されているbase.pyのインポートです。

from .base import *

あれ?
import *って書き方は推奨されていないんじゃなかったっけ?
と思われた方もいるかと思いますが、この場合は例外となります。
base.pyで設定されていないものをlocal.pyで追記するので、このような書き方となります。

では、ここからローカル環境独自の設定を書き込んでいきます。
現時点で必要なものは、以下のとおりです。

  • environ.Env.read_env()
  • SECRET_KEY
  • DEBUG
  • ALLOWED_HOSTS
  • DATABASES

こちらについては、base.pyの内容をそのままコピペします。
また、base.pyにあるこれらの設定は削除しましょう。

この段階でlocal.pyの内容はこのようになります。

"""
ローカル環境で適用される設定内容
"""
from .base import *


environ.Env.read_env(env_file=str(BASE_DIR) + "/.env")

SECRET_KEY = env("SECRET_KEY")

DEBUG = True

ALLOWED_HOSTS = ['*']   # '*' に変更します

DATABASES = {
    "default": env.db(),
}

ひとまずlocal.pyの完成です。

HerokuダッシュボードでSECRET_KEYを設定

さて、ローカル環境の設定がおわったところで、次は本番環境の設定です。
ローカル環境では.envファイルを作成して、公開したくない環境変数を記述していました。
公開したくないものですので、.envファイルは当然gitignoreの対象となっています。

したがって、本番環境で使う環境変数Herokuダッシュボードから入力する、または、Heroku CLIで入力する必要があります。

Herokuダッシュボードから作成したアプリを選択して、settingsタブからConfig Varsを編集します。
ここで設定するのは、本番環境用のSECRET_KEYだけでOKです。
DATABASE_URLは後ほど設定します。

では、KEYにSECRET_KEYVALUEに使用するSECRET_KEYの値を入力しましょう。
なお、本番環境用のSECRET_KEYの値はローカル環境と別にすることが望ましいです。

SECRET_KEYの再生成については、こちらの記事を参考に行います。

Heroku CLIを使う場合は、ターミナルから次のように入力します。

$ heroku config:set SECRET_KEY="<本番環境用に取得した値が望ましい>"



DJANGO_SETTINGS_MODULEを設定

これまでは、config配下のsettings.pyファイルを自動で読み込んでくれていました。
しかし、今回のように設定ファイルを環境に応じて分けた場合、そのままの設定では上手く動作しません。
読み込む設定ファイルを環境変数DJANGO_SETTINGS_MODULEを使って指定する必要があります。

まずは、本番環境の設定から行います。
前述のHerokuダッシュボードでSECRET_KEYの設定と同様に操作します。
KEYにDJANGO_SETTINGS_MODULEVALUEにはconfig.settings.productionと入力すればOKです。
要するに、config配下のsetthingsディレクトリにあるproduction.pyを指定しているのです。

なお、こちらもHeroku CLIを使ってターミナルから次のように入力してもOKです。

$ heroku config:set DJANGO_SETTINGS_MODULE='config.settings.production'

ならば、ローカル環境も.envファイルにそう書けばいいと思ってしまいますが、.envDjangoのプロジェクト内に存在するファイルなので、そこに書いては上手く動作しません。
もっと前の段階、そう、docker-compose.yml内で環境変数を設定するのです。

本番環境の設定と同じように環境変数を設定するには、docker-compose.ymlへ次のようにコードを追記します。

services:
  web:
    build: .
    (略)

    # この部分を追記
    environment:
      - DJANGO_SETTINGS_MODULE=config.settings.local  

    (略)



production.pyに本番環境用の設定を書き込む

最後に本番環境の設定をproduction.pyに書いていきます。
とはいっても、内容はlocal.pyで記述した値を本番環境向けに修正するくらいです。

では、local.pyの内容をproduction.pyへ丸ごとコピペしましょう。

environ.Env.read_env()の行は使用しないので、ここでは削除します。
ここで、変更するべきは、DEBUGALLOWED_HOSTSの値です。

修正後のコードはこのようになります。

"""
本番環境(Heroku)で適用される設定内容
"""
from .base import *


SECRET_KEY = env("SECRET_KEY")

DEBUG = False

ALLOWED_HOSTS = ['.herokuapp.com']

DATABASES = {
    "default": env.db(),
}

production.pyもこれでひとまず完成です。



おつかれさまでした!

これで、元々あったsettings.pyをローカル環境と本番環境用で分割して、環境に応じた設定を反映させる準備が整いました。

文字にすると工程が長く感じるかもしれませんが、この手順にしたがって設定すると思っているよりもサクッと終わると思います。
できるようになると非常に便利ですので、是非ともファイルの分割に挑戦してみてください。

この記事が環境に応じた設定をどうやって分けたらいいかわからず、困っている方の一助になれば幸いです。

次回は、動作確認と静的ファイル関係の設定について解説する予定です。

では、また次の記事で!✋️

EP 24: Herokuものがたり 〜 準備編

はじめに

Djangoを使ってWebアプリを作ったなら、公開しない手はないです。
公開する方法として、Herokuが広く知られています。

Herokuを使ってアプリを公開(デプロイ)するためのチュートリアルも用意されているので、基本的なことは理解できました。
しかし、設定を進めるとつまづくポイントがいくつかありました。
そして、つまづいたポイントについてググると新しいものから古いものまで様々な情報があらわれます。
どれが正しいのかトライ・アンド・エラーを繰り返し、情報の取捨選択に多くの時間を割きました。

ということで、本記事から数回にわたってHerokuの設定を私なりにまとることにしました。

なお、ローカル環境で開発したアプリがあることが前提で、ローカル環境は以前書いたこちらの内容を踏襲しています。 hirologue.hateblo.jp


注意事項

※ Herokuの無料枠は2022年11月に廃止されています(利用の際には、最低でも$5/月の料金が発生します)。

本シリーズ(Herokuものがたり)ではアドオンのHeroku Postgres($5/月)を使用しているので、月額$10となります。


デプロイのための準備

まずは、こちらを参考にHerokuアカウントの作成とHeroku CLIをインストールします。

では、作成したDjangoプロジェクトのディレクトリに移動しましょう。



 

基本的な設定

Prockfileの準備

はじめに行うのは、Procfileという名前のファイルの作成です。
ターミナルで次のコマンドを入力すると目的のファイルが作成されます。

$  touch Prockfile


作成したProckfileを開き、次の内容を入力して保存します。

web: gunicorn config.wsgi

参考: Heroku のための Django アプリの設定 | Heroku Dev Center


runtime.txtの作成

Pythonのバージョンをローカル環境と本番環境で統一するためにruntime.txtを作成します。
先程と同様にターミナルでコマンドを入力してファイルを作成します。

$ touch runtime.txt


次に使用しているPythonのバージョンを出力してみましょう。
こちらもターミナルで操作します。

$ python --version


実行すると、次のようにバージョンが出力されます。

Python 3.12.7


これをruntime.txtにそのままコピペするとエラーになりますので、注意してください。
runtime.txtを開き、次のように記述して保存します。

# 使用するバージョンに合わせてください
python-3.12.7

注意すべき点は3つあります。

  • python は小文字
  • pythonのあとに空白を入れずに、 -(ハイフン)でつなげる
  • バージョン番号は3つ(メジャー、マイナー、パッチ)すべて指定する

参考: Python ランタイムの指定 | Heroku Dev Center


requirements.txtに必要なパッケージを追記

dockerで環境構築をした際に作成したrequirements.txtには、Djangoのバージョンやdjango-environ、psycopgが記述されています。
ここに必要なパッケージを追記して保存します。

gunicorn==23.0.0

# 静的ファイルを取り扱う場合に必要
whitenoise==6.7.0

# 画像を扱う場合に必要
pillow==10.4.0

#画像をアップロードする場合に必要
django-cloudinary-storage==0.3.0

参考: Heroku での Python および Django アプリのデプロイ | Heroku Dev Center


アプリの作成

Herokuでソースコードを受け取るために次のコマンドを入力して、アプリを作成します。

$ heroku create


実行すると、このような感じで出力されます。

$ heroku create
Creating app... done, ⬢ serene-caverns-82714
https://serene-caverns-82714.herokuapp.com/ | https://git.heroku.com/serene-caverns-82714.git


このserene-caverns-82714というのが、Herokuで作成されたランダムな名前のアプリ名です。
アプリの作成とともに、herokuという名前のGitのリモートリポジトリも作成されます。
つまり、このリモートリポジトリにプッシュすることで、Herokuにデプロイしているのです。

では、さっそくgit push heroku mainとコマンドを入力してデプロイ!

と行きたいところですが、はやる気持ちをぐっと堪えましょう。

必要な設定はこんなもんじゃありません。
この続きは次回の記事で説明します。



いかがだったでしょうか?
今回から数回にわたって、Herokuの設定について取り扱います。
わたしがこの記事を作成しようと思ったのは、備忘録的な意味合いもありますが、同じような苦労をしている方の一助になればという思いもあります。

ぜひとも次の記事をお楽しみに!
では✋️

EP 23: 49歳の挑戦 - 最終回(7ヶ月目を振り返る)

2024年3月1日にHappiness Chain(以下、HC) Euforia 2期生として入会してから早いもので7ヶ月が経過しようとしています。
本記事では、この1ヶ月間で学んだことをダイジェストで振り返りたいと思います。

50歳目前の私が入会を決意するまでの経緯を書いたポエムは👇こちら hirologue.hateblo.jp


9月の学習時間(期間:8/31 - 9/29)

9月の学習時間は 126 時間 / 30日 でした。
学習日数が30日ですので、一日あたりの学習時間は 252分(4時間12分)となりますね。

今月も学習時間の目安として、休日は8時間、平日は3時間を基本としました。
今月はシルバーウィークもありましたので、目標学習時間は150時間の設定です。

目標学習時間には 24時間足りませんでした。

先月の振り返りで「何かに集中して取り組むためには、シッカリ休みを取る」ことの重要性に気づきました。
8/31と9/1の2日間を二女と実家へ帰省して、幸せなひとときを過ごせたことは、学習時間の確保に終われていた過去の自分から変わることができた証だと思います。
また、勤務時間が不規則な日もあり、その前日は睡眠時間の確保を優先して目標学習時間を達成するよりも毎日少しでも学習を続けることを意識しました。

さて、先月の振り返りで意識しようと心がけた👇️このことは、できたのでしょうか?

今後の課題は、学習と休みのバランスを良好に保って、学習時間に対して学習内容を濃くする、濃度を意識していこうと思います。

早速、振り返ってみましょう


9月の学習内容

8月はDjangoの学習に着手したところで終わりましたので、9月はその続きです。

Djangoの学習では、Djangoの概要(全体像)を知る」、「Djangoのしくみを理解する(わかる)」、「Djangoを使ってWebアプリを開発できる」を意識して学習に望むことにしました。

Djangoの概要(全体像)を知る

独学時にDjangoの学習をしたことはあります。
が、HCでDjangoの学習をスタートしたときに「ほぼ100%忘れている」自分に気づきました。
確かに独学時にDjangoを学んだときは、ただひたすら写経でしたから知識として定着するわけもありません。

ということで、Djangoという言葉だけは知っている程度の状態からHC指定の動画教材をつかって学習を始めました。
ここでは、「Djangoとは何か」、「Djangoを使った開発手順」といったような概要(全体像)を把握することを意識しました。

動画教材ですので、視聴しながら一緒に手を動かして難なく終了です。

Djangoのしくみを理解する(わかる)

Djangoの全体像を把握したところで、次は公式チュートリアルを使って、そのしくみを理解することです。

公式チュートリアルに取り掛かる前に、以前学習したDockerで自分なりに環境構築を行ってみました。 hirologue.hateblo.jp

Dockerで無事にDjangoの開発環境が整ったところで、公式チュートリアルにチャレンジです。

コードをトレースするだけなら簡単、しかし、その内容からしくみを理解しようとするなら読み解くのが難しい。というのが率直な感想です。
これは、ほとんどの公式ドキュメント・チュートリアルに言えることなのでしょうけど・・・

どういう意味なのかと頭を悩ましているときに、以前Djangoを学習していた際に気になっていた書籍の存在を思い出しました。
それが、現場で使えるDjangoの教科書《基礎編》[4.2 LTS 対応版]です。

この本がわたしのDjangoの理解度を爆上げしてくれました!

公式チュートリアルを終えた感想を記事にしました。

hirologue.hateblo.jp



Djangoを使ってWebアプリを開発できる

全体像を把握し、しくみをある程度理解したところで次は、Djangoを使ってWebアプリの開発に挑戦です。

作成するのは、架空のECショップです。
いよいよ本格的なチャレンジに突入って感じです。正直ワクワクします。
まだ商品一覧ページの作成中ですが、自分なりに調べながら少しずつ前進しています。

今月はここまでとなります。


今月の感想

9月21日、22日とHCの開発合宿に参加してきました。
HCの方々とオフラインで会うのは初めてでしたが、いい人ばかりで楽しい時を過ごせました。
また、機会があったら是非参加したいと思います。

さて、今月は学習と休みのバランスを良好に保ち、学習内容を濃くすることを意識して取り組みました。
学習と休みのバランスは取れたと思います。

一方で、学習時間に対する学習内容はどうだったか?
一月終えてみて、先月とさほど変わらないというのが、正直な感想です。

それはなぜか、自身のマインドについて分析してみました。
一番の原因を見つけました。

それは、「完璧を追い求めすぎ」 これに尽きると思います。

失敗(エラーがでること)を嫌い、初めからきれいなコードを書こうなんて考えているから。
だから学習時間の割に前に進めていないんだろうな。きっとこれだ。
「レビューしてくれる方の手を煩わせたくない」、「この程度のことを質問してはダメだ」などと、まるで独学しているかのような状態で学習を進めていることは、改善しなければいけないなと感じました。

このことに気づけたのは、開発合宿でエンジニア同士(HC卒業生とCTO)のやりとりを直接見ることができたからです。
今思うと、この気付きを得られたことが合宿に参加した一番の収穫かもしれません。

ということで、来月は「完璧を追い求めすぎない」を意識していきたいと思います。




10月のターゲット



本記事のタイトルに「最終回」とあったので驚いた方もいるかもしれませんが、エンジニアになる夢を諦めたわけではありません。

49歳の挑戦が終わり、10月1日より第2章「50歳の挑戦」のはじまりです!

「人間五十年、下天の内をくらぶれば夢幻の如くなり」

50年なんて儚く、今思えばあっという間でした。

人生は有限であるし、時間も有限

エンジニアになる夢は必ず叶えたい!
そのためには、失敗にビビってなんかいられない
やってみせる

では、また来月👍️