magic-pocket 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. magic_pocket-0.1.0/.github/workflows/docs.yaml +28 -0
  2. magic_pocket-0.1.0/.gitignore +17 -0
  3. magic_pocket-0.1.0/.pre-commit-config.yaml +17 -0
  4. magic_pocket-0.1.0/.python-version +1 -0
  5. magic_pocket-0.1.0/CHANGELOG.md +66 -0
  6. magic_pocket-0.1.0/LICENSE +21 -0
  7. magic_pocket-0.1.0/PKG-INFO +47 -0
  8. magic_pocket-0.1.0/README.md +20 -0
  9. magic_pocket-0.1.0/docs/changelog.md +1 -0
  10. magic_pocket-0.1.0/docs/features/cli.md +85 -0
  11. magic_pocket-0.1.0/docs/features/outline.md +7 -0
  12. magic_pocket-0.1.0/docs/features/runtime.md +126 -0
  13. magic_pocket-0.1.0/docs/get_started.md +11 -0
  14. magic_pocket-0.1.0/docs/index.md +117 -0
  15. magic_pocket-0.1.0/docs/tutorial/simple.md +278 -0
  16. magic_pocket-0.1.0/mkdocs.yml +44 -0
  17. magic_pocket-0.1.0/pocket/__init__.py +3 -0
  18. magic_pocket-0.1.0/pocket/cli/__init__.py +0 -0
  19. magic_pocket-0.1.0/pocket/cli/awscontainer_cli.py +184 -0
  20. magic_pocket-0.1.0/pocket/cli/deploy_cli.py +72 -0
  21. magic_pocket-0.1.0/pocket/cli/main_cli.py +41 -0
  22. magic_pocket-0.1.0/pocket/cli/neon_cli.py +97 -0
  23. magic_pocket-0.1.0/pocket/cli/s3_cli.py +62 -0
  24. magic_pocket-0.1.0/pocket/cli/spa_cli.py +82 -0
  25. magic_pocket-0.1.0/pocket/cli/status_cli.py +58 -0
  26. magic_pocket-0.1.0/pocket/cli/vpc_cli.py +69 -0
  27. magic_pocket-0.1.0/pocket/context.py +306 -0
  28. magic_pocket-0.1.0/pocket/django/__init__.py +9 -0
  29. magic_pocket-0.1.0/pocket/django/context.py +70 -0
  30. magic_pocket-0.1.0/pocket/django/django_cli.py +170 -0
  31. magic_pocket-0.1.0/pocket/django/lambda_handlers.py +65 -0
  32. magic_pocket-0.1.0/pocket/django/runtime.py +53 -0
  33. magic_pocket-0.1.0/pocket/django/settings.py +50 -0
  34. magic_pocket-0.1.0/pocket/django/urls.py +50 -0
  35. magic_pocket-0.1.0/pocket/django/utils.py +132 -0
  36. magic_pocket-0.1.0/pocket/general_context.py +106 -0
  37. magic_pocket-0.1.0/pocket/general_settings.py +61 -0
  38. magic_pocket-0.1.0/pocket/mediator.py +118 -0
  39. magic_pocket-0.1.0/pocket/resources/__init__.py +0 -0
  40. magic_pocket-0.1.0/pocket/resources/aws/__init__.py +0 -0
  41. magic_pocket-0.1.0/pocket/resources/aws/cloudformation.py +214 -0
  42. magic_pocket-0.1.0/pocket/resources/aws/ecr.py +110 -0
  43. magic_pocket-0.1.0/pocket/resources/aws/efs.py +138 -0
  44. magic_pocket-0.1.0/pocket/resources/aws/lambdahandler.py +182 -0
  45. magic_pocket-0.1.0/pocket/resources/aws/secretsmanager.py +104 -0
  46. magic_pocket-0.1.0/pocket/resources/awscontainer.py +180 -0
  47. magic_pocket-0.1.0/pocket/resources/base.py +3 -0
  48. magic_pocket-0.1.0/pocket/resources/neon.py +316 -0
  49. magic_pocket-0.1.0/pocket/resources/s3.py +158 -0
  50. magic_pocket-0.1.0/pocket/resources/spa.py +309 -0
  51. magic_pocket-0.1.0/pocket/resources/vpc.py +55 -0
  52. magic_pocket-0.1.0/pocket/runtime.py +94 -0
  53. magic_pocket-0.1.0/pocket/settings.py +275 -0
  54. magic_pocket-0.1.0/pocket/templates/cloudformation/awscontainer.yaml +361 -0
  55. magic_pocket-0.1.0/pocket/templates/cloudformation/spa.yaml +86 -0
  56. magic_pocket-0.1.0/pocket/templates/cloudformation/vpc.yaml +213 -0
  57. magic_pocket-0.1.0/pocket/templates/init/django-dotenv.env +3 -0
  58. magic_pocket-0.1.0/pocket/templates/init/django-settings.py +140 -0
  59. magic_pocket-0.1.0/pocket/templates/init/pocket.Dockerfile +32 -0
  60. magic_pocket-0.1.0/pocket/templates/init/pocket_simple.toml +31 -0
  61. magic_pocket-0.1.0/pocket/utils.py +102 -0
  62. magic_pocket-0.1.0/pyproject.toml +57 -0
  63. magic_pocket-0.1.0/requirements-dev.lock +300 -0
  64. magic_pocket-0.1.0/requirements.lock +101 -0
  65. magic_pocket-0.1.0/tests/conftest.py +39 -0
  66. magic_pocket-0.1.0/tests/data/toml/awscontainer_pocket_secrets.toml +14 -0
  67. magic_pocket-0.1.0/tests/data/toml/default.toml +69 -0
  68. magic_pocket-0.1.0/tests/sampleprj/Dockerfile +24 -0
  69. magic_pocket-0.1.0/tests/sampleprj/manage.py +22 -0
  70. magic_pocket-0.1.0/tests/sampleprj/requirements.lock +7 -0
  71. magic_pocket-0.1.0/tests/sampleprj/sampleprj/__init__.py +0 -0
  72. magic_pocket-0.1.0/tests/sampleprj/sampleprj/asgi.py +16 -0
  73. magic_pocket-0.1.0/tests/sampleprj/sampleprj/settings.py +123 -0
  74. magic_pocket-0.1.0/tests/sampleprj/sampleprj/urls.py +22 -0
  75. magic_pocket-0.1.0/tests/sampleprj/sampleprj/wsgi.py +16 -0
  76. magic_pocket-0.1.0/tests/test_django.py +73 -0
  77. magic_pocket-0.1.0/tests/test_resources.py +96 -0
  78. magic_pocket-0.1.0/tests/test_runtime.py +23 -0
  79. magic_pocket-0.1.0/tests/test_settings.py +39 -0
@@ -0,0 +1,28 @@
1
+ name: docs
2
+ on:
3
+ push:
4
+ branches:
5
+ - main
6
+ permissions:
7
+ contents: write
8
+ jobs:
9
+ deploy:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - name: Configure Git Credentials
14
+ run: |
15
+ git config user.name github-actions[bot]
16
+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: 3.x
20
+ - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
21
+ - uses: actions/cache@v4
22
+ with:
23
+ key: mkdocs-material-${{ env.cache_id }}
24
+ path: .cache
25
+ restore-keys: |
26
+ mkdocs-material-
27
+ - run: pip install mkdocs-material
28
+ - run: mkdocs gh-deploy --force
@@ -0,0 +1,17 @@
1
+ # python generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # venv
10
+ .venv
11
+
12
+ # editors
13
+ .vscode/
14
+
15
+ # local env
16
+ .envrc
17
+ .env
@@ -0,0 +1,17 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v3.2.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ exclude: ".*\\.css\\.map|.*\\.svg"
8
+ - id: check-yaml
9
+ exclude: "mkdocs.yml"
10
+ - id: check-added-large-files
11
+ - repo: https://github.com/astral-sh/ruff-pre-commit
12
+ rev: v0.4.2
13
+ hooks:
14
+ - id: ruff
15
+ args: [--select, I, --fix]
16
+ - id: ruff-format
17
+ exclude: "pocket/templates/init/django-settings.py"
@@ -0,0 +1 @@
1
+ 3.10.11
@@ -0,0 +1,66 @@
1
+ # Changelog
2
+ 全ての重要な変更はこのファイルに記録されます。
3
+
4
+ 書き方は[Keep a Changelog](http://keepachangelog.com/en/1.0.0/)に基づきます。<br>
5
+ バージョンは[Semantic Versioning](http://semver.org/spec/v2.0.0.html)に従います。
6
+
7
+ ## [?.?.?](https://github.com/worgue/magic-pocket/releases/tag/0.1.0) - unreleased
8
+ ### Features
9
+ - :material-console: `pocket django deploy`でデプロイ + マイグレーションなどの管理コマンド実行。実行内容が決まらないためUnreleases。
10
+ - Neon接続時のIP制限
11
+ - RDSの利用
12
+ - 環境ごとに異なるファイルを返すurlsの作成(`robots.txt`と`favicon.ico`用)
13
+ - :material-console: `pocket deploy`でデプロイ(以下全て`pocket.toml`に設定がある場合のみ)
14
+ - EFSの作成
15
+ - Lambdaに関わるCloudFormation作成
16
+ - SecurityGroupIngress(LambdaからEFSへのアクセス権限)の作成
17
+ - SQSを利用したdjango managementコマンドのバッチ処理
18
+ - Queue, Dead letter queue, EventSourceMappingの作成
19
+ - :material-console: `pocket remove`でデプロイした環境を出来る限り削除し、削除できないものは表示
20
+
21
+ ## [0.1.0](https://github.com/worgue/magic-pocket/releases/tag/0.1.0) - 2024-10-11
22
+
23
+ ### Dependencies
24
+ - click>=8.1.7
25
+ - tomli>=1.1.0 ; python_version < '3.11'
26
+ - mergedeep>=1.3.4
27
+ - pydantic>=2.5.3
28
+ - pydantic-settings>=2.1.0
29
+ - boto3>=1.34.28
30
+ - rich>=13.7.0
31
+ - deepdiff>=6.7.1
32
+ - pyyaml>=6.0.1
33
+ - python-on-whales>=0.68.0
34
+ - jinja2>=3.1.3
35
+ - awslambdaric>=2.0.10
36
+ - apig_wsgi>=2.18.0
37
+ - django-storages>=1.14.2,!=1.14.3
38
+
39
+ ### Features
40
+ - :material-console: `pocket status`で環境の作成状況を確認
41
+ - :material-console: `pocket deploy`でデプロイ
42
+ - :material-database: NeonへのDB作成
43
+ - :simple-awssecretsmanager: SecretsManagerへのNeon DBの接続情報登録
44
+ - :simple-amazons3: ストレージ用にS3を作成し権限を設定
45
+ - :simple-docker: コンテナイメージを作成しECRへアップロード
46
+ - :material-language-javascript: フロントエンドSPAのビルドデータをアップロードするS3を作成
47
+ - CF: Lambdaに関わるCloudFormationを登録・更新
48
+ - LambdaのIAM Role, SecurityGroup, Function
49
+ - API Gateway の LogGroup, Api, ApiGatewayManagedOverrides, Route, Integration, lambda Permission, Certificate, DomainName, RecordSet, ApiMapping
50
+ - API Gatewayのhost名のoutput
51
+ - CF: SPAに関わるCloudFormationを登録・更新
52
+ - CloudFrontのOriginAccessControl, Certificate, CloudFrontFunction, Distribution, RecordSet
53
+ - :material-language-python: `settings.py`での情報取得
54
+ - :simple-awssecretsmanager: AWS SecretsManagerから情報を取得(1)
55
+ - :simple-toml: `pocket.toml`からdjangoの`STORAGES`, `CACHES`を取得
56
+ - CF: CloudFormationのoutputからdjangoの`ALLOWED_HOSTS`を取得
57
+ - :simple-toml: デプロイ環境ごとのdjango settings登録
58
+ - :material-console: `pocket django manage COMMAND ARGS` で管理コマンドを実行
59
+ - :material-console: `pocket django storage upload STORAGE` でローカルのFileSystemStorageから対象ステージのS3Boto3Storageへデータをsync
60
+ - :material-console: `pocket resource awscontainer status`でLambdaの作成状況を確認
61
+ - :material-console: `pocket resource awscontainer secretsmanager list`でSecretsManagerの値を確認
62
+ - :material-console: `pocket resource awscontainer yaml`でCloudFormation用のyaml ファイルを確認
63
+ - :material-console: `pocket resource awscontainer yaml-diff`でCloudFormation用のyamlファイルの差分を確認
64
+ - :material-console: `pocket resource neon status`でNeonの作成状況を確認
65
+ - :material-console: `pocket resource s3 status`でS3バケットの作成状況を確認
66
+ - :material-console: `pocket resource spa status`でspaアップロード先S3バケットの作成状況を確認
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Masaaki Yasui
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ Metadata-Version: 2.1
2
+ Name: magic-pocket
3
+ Version: 0.1.0
4
+ Summary: Deploy system for Django projects.
5
+ Author-email: Masaaki Yasui <yasu@worgue.com>
6
+ Description-Content-Type: text/markdown
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Requires-Dist: click>=8.1.7
9
+ Requires-Dist: tomli>=1.1.0 ; python_version < '3.11'
10
+ Requires-Dist: mergedeep>=1.3.4
11
+ Requires-Dist: pydantic>=2.5.3
12
+ Requires-Dist: pydantic-settings>=2.1.0
13
+ Requires-Dist: boto3>=1.34.28
14
+ Requires-Dist: rich>=13.7.0
15
+ Requires-Dist: deepdiff>=6.7.1
16
+ Requires-Dist: pyyaml>=6.0.1
17
+ Requires-Dist: python-on-whales>=0.68.0
18
+ Requires-Dist: jinja2>=3.1.3
19
+ Requires-Dist: awslambdaric>=2.0.10
20
+ Requires-Dist: apig_wsgi>=2.18.0
21
+ Requires-Dist: django-storages>=1.14.2,!=1.14.3
22
+ Requires-Dist: django>=4.2.0 ; extra == "django"
23
+ Project-URL: Documentation, https://worgue.github.io/magic-pocket/
24
+ Project-URL: Source, https://github.com/worgue/magic-pocket
25
+ Provides-Extra: django
26
+
27
+ # Magic Pocket - Django Serverless Deployment
28
+
29
+ ドキュメントはこちら
30
+ https://worgue.github.io/magic-pocket/
31
+
32
+
33
+ magic-pocket の目標は、サーバレスDjangoです。Djangoを以下の環境にデプロイします。
34
+
35
+ - AWS Lambda
36
+ - Neon Postgres
37
+ - S3 storages
38
+
39
+ ## Motivation
40
+
41
+ 小規模な個人プロジェクトを、1人で複数同時に運用するため開発されたライブラリです。
42
+ 気軽に作り、飽きたら放っておく、というスタイルで運用するため、以下の要件が最終目標になっています。
43
+
44
+ - サーバーの保守が不要
45
+ - 使わない間のコストが不要
46
+ - 環境を作る時にやる気を出す必要なし
47
+
@@ -0,0 +1,20 @@
1
+ # Magic Pocket - Django Serverless Deployment
2
+
3
+ ドキュメントはこちら
4
+ https://worgue.github.io/magic-pocket/
5
+
6
+
7
+ magic-pocket の目標は、サーバレスDjangoです。Djangoを以下の環境にデプロイします。
8
+
9
+ - AWS Lambda
10
+ - Neon Postgres
11
+ - S3 storages
12
+
13
+ ## Motivation
14
+
15
+ 小規模な個人プロジェクトを、1人で複数同時に運用するため開発されたライブラリです。
16
+ 気軽に作り、飽きたら放っておく、というスタイルで運用するため、以下の要件が最終目標になっています。
17
+
18
+ - サーバーの保守が不要
19
+ - 使わない間のコストが不要
20
+ - 環境を作る時にやる気を出す必要なし
@@ -0,0 +1 @@
1
+ --8<-- "CHANGELOG.md"
@@ -0,0 +1,85 @@
1
+ # コマンドライン
2
+
3
+ magic-pocketには、pocketで始まるCLIが用意されています。
4
+ 全てのコマンドは、`--stage`オプションで対象となるデプロイ環境を指定できます。
5
+
6
+ 以下のコード例は、dev環境を操作する場合です。
7
+
8
+ ## pocket status
9
+ ```bash
10
+ pocket status --stage=dev
11
+ ```
12
+ 環境の作成状況を確認します。
13
+
14
+ ## pocket deploy
15
+ ```bash
16
+ pocket deploy --stage=dev
17
+ ```
18
+ デプロイします。具体的には、`pocket.toml`に記述がある場合、以下の作業を行います。記述がない場合、何もしません。
19
+
20
+ - :material-database: NeonへのDB作成
21
+ - :simple-awssecretsmanager: SecretsManagerへのNeon DBの接続情報登録
22
+ - :simple-amazons3: ストレージ用にS3を作成し権限を設定
23
+ - :simple-docker: コンテナイメージを作成しECRへアップロード
24
+ - :material-language-javascript: フロントエンドSPAのビルドデータをアップロードするS3を作成
25
+ - CF: Lambdaに関わるCloudFormationを登録・更新
26
+ - LambdaのIAM Role, SecurityGroup, Function
27
+ - API Gateway の LogGroup, Api, ApiGatewayManagedOverrides, Route, Integration, lambda Permission, Certificate, DomainName, RecordSet, ApiMapping
28
+ - API Gatewayのhost名のoutput
29
+ - CF: SPAに関わるCloudFormationを登録・更新
30
+ - CloudFrontのOriginAccessControl, Certificate, CloudFrontFunction, Distribution, RecordSet
31
+
32
+ ## pocket django manage `COMMAND` `ARGS`
33
+ ```bash
34
+ pocket django manage collectstatic --noinput --stage=dev
35
+ ```
36
+ django management commandを実行
37
+
38
+ ## pocket django storage upload `STORAGE`
39
+ ```bash
40
+ pocket django storage upload static --stage=dev
41
+ ```
42
+ ローカルのFileSystemStorageから対象ステージのS3Boto3Storageへデータをsync。STORAGEはsettings.pyのSTORAGESのキー名です。
43
+
44
+
45
+ ## pocket resource awscontainer status
46
+ ```bash
47
+ pocket resource awscontainer status --stage=dev
48
+ ```
49
+ Lambdaの作成状況を確認
50
+
51
+ ## pocket resource awscontainer secretsmanager list
52
+ ```bash
53
+ pocket resource awscontainer secretsmanager list --stage=dev
54
+ ```
55
+ SecretsManagerの値を確認
56
+
57
+ ## pocket resource awscontainer yaml
58
+ ```bash
59
+ pocket resource awscontainer yaml --stage=dev
60
+ ```
61
+ CloudFormation用のyamlファイルを確認
62
+
63
+ ## pocket resource awscontainer yaml-diff
64
+ ```bash
65
+ pocket resource awscontainer yaml-diff --stage=dev
66
+ ```
67
+ CloudFormation用のyamlファイルの差分を確認
68
+
69
+ ## pocket resource neon status
70
+ ```bash
71
+ pocket resource neon status --stage=dev
72
+ ```
73
+ Neonの作成状況を確認
74
+
75
+ ## pocket resource s3 status
76
+ ```bash
77
+ pocket resource s3 status --stage=dev
78
+ ```
79
+ S3バケットの作成状況を確認
80
+
81
+ ## pocket resource spa status
82
+ ```bash
83
+ pocket resource spa status --stage=dev
84
+ ```
85
+ SPAアップロード先S3バケットの作成状況を確認
@@ -0,0 +1,7 @@
1
+ # 概要
2
+
3
+ 基本的な機能は以下の通りです。
4
+
5
+ 1. Django実行環境を設定ファイル`pocket.toml`で定義します。
6
+ 2. CLIコマンドで、実行環境の作成や確認、デプロイを行います。
7
+ 3. デプロイした実行環境では、`pocket.django.runtime`モジュールを用いて、`pocket.toml`やSecretsManagerから情報を取得します。
@@ -0,0 +1,126 @@
1
+ # 実行環境
2
+
3
+ 実行環境内で、リソース情報を取得することが出来ます。
4
+ 大きく分けて、以下の2つの方法があります。
5
+
6
+ - pocket.tomlから取得
7
+ - 環境変数へのデータ登録
8
+
9
+ ## pocket.tomlから取得
10
+ 一部の情報は、pocket.tomlから直接取得します。
11
+
12
+ ### STORAGESとCACHES
13
+ この2つの設定は、`settings.py`に指定するのとは異なるmagic-pocket独自表記が必要です。(1)
14
+ {.annotate}
15
+
16
+ 1. settings.pyの自由度が高いが、magic-pocketでは一部の機能しか使わないため。
17
+
18
+ ```python
19
+ from pocket.django.utils import get_caches, get_storages
20
+
21
+ STORAGES = get_storages()
22
+ CACHES = get_caches()
23
+ ```
24
+
25
+ ??? info "値が設定されていない場合はdjangoのデフォルト値が返されます"
26
+ **STORAGES**
27
+
28
+ ```json
29
+ {
30
+ 'default': {'BACKEND': 'django.core.files.storage.FileSystemStorage'},
31
+ 'staticfiles': {'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage'}
32
+ }
33
+ ```
34
+
35
+ **CACHES**
36
+
37
+ ```json
38
+ {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
39
+ ```
40
+
41
+ !!! warning "ローカルなど、magic-pocketデプロイ環境以外の挙動"
42
+ ローカルなどで、これらの関数が呼ばれた場合、`pocket.toml`の`[general.django_fallback.storages]`という設定が使われます。
43
+ 何も書かない場合の設定は、以下と同じです。
44
+
45
+ ```toml
46
+ [general.django_fallback.storages]
47
+ default = { store = "filesystem" }
48
+ staticfiles = { store = "filesystem", static = true }
49
+ [general.django_fallback.caches]
50
+ default = { store = 'locmem' }
51
+ ```
52
+
53
+ デプロイされた環境は、`POCKET_STAGE`という環境変数を見ることで判定します。
54
+
55
+ `POCKET_STAGE`を変えてしまうと影響が大きいため、ローカルでS3ストレージなどを使う場合は、`pocket.toml`の`general.django_fallback`で対応するのが良いでしょう。
56
+
57
+ ### pocket.tomlへdjango settingsを直接設定
58
+ settings.pyから、直接tomlの設定を読み込ませることも可能です。
59
+ 以下は、`DEFAULT_FROM_EMAIL`と`CORS_ALLOWED_ORIGINS`を設定する例です。
60
+
61
+ ```toml
62
+ # local
63
+ [general.django_fallback.settings]
64
+ CORS_ALLOWED_ORIGINS = [
65
+ "http://localhost:5173",
66
+ "http://localhost:4173",
67
+ ]
68
+
69
+ # dev
70
+ [dev.awscontainer.django.settings]
71
+ DEFAULT_FROM_EMAIL = '"Magic Pocket Test Version" <magic-pocket-test@example.com>'
72
+ CORS_ALLOWED_ORIGINS = ["https://dev.example.com"]
73
+
74
+ # prd
75
+ [prd.awscontainer.django.settings]
76
+ DEFAULT_FROM_EMAIL = '"Magic Pocket" <noreply@example.com>'
77
+ CORS_ALLOWED_ORIGINS = ["https://www.example.com"]
78
+ ```
79
+
80
+ これを`settings.py`で、以下の様に読み込めます。
81
+ ```python
82
+ from pocket.django.runtime import get_django_settings
83
+
84
+ vars().update(get_django_settings().items())
85
+ ```
86
+
87
+ ??? question "環境変数とenvファイルで良いのでは?"
88
+ 機密性の低い情報では、env.devやenv.prdなどのenvファイルをコミットして、devやprdのみ環境変数としても構いません。
89
+ それでも、この機能を実装した理由は、以下2点です。
90
+
91
+ 1. 全ての環境差分を`pocket.toml`で管理することができる
92
+ 2. ネストした辞書形式のsettingsを読み込む際に便利
93
+
94
+
95
+ ## 環境変数へのデータ登録
96
+ 以下のコマンドはデプロイ情報を環境変数に設定します。
97
+
98
+ ```python
99
+ from pocket.django.runtime import set_envs
100
+
101
+ set_envs()
102
+
103
+ # Read enviroment variables here
104
+ # SECRET_KEY = os.environ.get("SECRET_KEY")
105
+ # etc...
106
+ ```
107
+
108
+ 読み込む情報は以下の通りです。
109
+
110
+ <div class="annotate" markdown>
111
+ - :simple-awssecretsmanager: AWS SecretsManagerから情報を取得(1)
112
+ - CF: CloudFormationのoutputからdjangoのALLOWED_HOSTSを取得
113
+ </div>
114
+ 1. `pocket.toml`の`[awscontainer.secretsmanager.pocket_secrets]`で設定され、自動生成されたパスワードや、Neonから取得したDB接続情報などを、管理します。
115
+
116
+ また、`[awscontainer.secretsmanager.secrets]`には、SecretsManagerのarnを利用して、任意の情報を取得することも可能です。
117
+
118
+ いずれの場合も、パーミッションはクラウドフォーメーション経由で自動的に設定されます。
119
+
120
+ !!! warning "環境変数からsettings.pyに読み込むのを忘れないでください"
121
+ どの様な方法でも構いませんが、`settings.py`の中で値を登録することを忘れないでください。
122
+
123
+ また、環境変数には型がありません。
124
+ DEBUG=os.environ.get("DEBUG")として、DEBUG=Falseを設定すると、デバッグモードになってしまいます。気をつけましょう。
125
+
126
+ 作者はdjagno-environを利用することをお勧めします。
@@ -0,0 +1,11 @@
1
+ # Get Started
2
+
3
+ 基本的な使い方は以下の通りです。
4
+
5
+ 1. magic-pocketをインストールします。
6
+ 2. `pocket.toml`を作成します。
7
+ 3. `pocket.toml`で指定したパスに、Dockerfileを作成します。
8
+ 4. `settings.py`を修正します。
9
+ 5. `pocket deploy`でデプロイします。
10
+
11
+ 実際に動くサンプルを作るのが分かりやすいので、チュートリアルを参照してください。
@@ -0,0 +1,117 @@
1
+ # Magic Pocket - Django Serverless Deployment
2
+
3
+ magic-pocket の目標は、サーバレスDjangoです。Djangoを以下の環境にデプロイします。
4
+
5
+ - AWS Lambda
6
+ - Neon Postgres
7
+ - S3 storages
8
+
9
+ !!! info "ライブラリ作るほどじゃない?英語が読めたらそうかも。"
10
+ このライブラリを作った理由として、英語ドキュメントへの苦労というのがあります。
11
+ 作者は日本人で英語が出来ません。
12
+ 日本語への機会翻訳は、ドキュメントを読む助けにはなりません。
13
+ AWSインフラをコードに落とし込もうとすると、多くのドキュメントを読む必要がありました。
14
+ もはや、プログラミングをしているのか、英語の勉強をしているのか分からない状況でした。
15
+
16
+ 「英語勉強すれば?」というのは、怠惰じゃないにも程がありますし、他の苦しむ人たちの助けにもならない。
17
+ そもそもコマンド1つ叩いて環境が出来れば、日本語すら読めなくて良くて最高かなと。
18
+
19
+ ??? question "とはいえ英語ぐらい勉強しようよ。"
20
+ おっしゃる通りです。
21
+ が、どうやっても勉強できなかったです。
22
+
23
+ - 3歳児でもできることを、何年もかけて学ぶの、ばからしい。
24
+ - 良い大人が、1年勉強して身に付かないとか、意味不明。
25
+ - もっと簡単なはず、教え方が悪い。
26
+
27
+ そう思って、自分が使いたい英語学習のサイトを作る事にしました。
28
+ このライブラリは、そのためのライブラリでもあります。
29
+
30
+ !!! success "リソースの理解について"
31
+ AWSリソースの多くはクラウドフォーメーションで作成されます。
32
+ 私は、コンソールからリソースを作ってしまい、訳が分からなくなった事が何度もあり、作ったリソースの把握も重要な要件になりました。
33
+
34
+ 例外として、データ保存を行う以下のリソースは、 APIから直接作成されます。
35
+
36
+ - S3バケット
37
+ - ECRレポジトリ
38
+ - route53レコード
39
+ - SecretsManagerシークレット
40
+
41
+ ## Motivation
42
+
43
+ 小規模な個人プロジェクトを、1人で複数同時に運用するため開発されたライブラリです。
44
+ 気軽に作り、飽きたら放っておく、というスタイルで運用するため、以下の要件が最終目標になっています。
45
+
46
+ - サーバーの保守が不要
47
+ - 使わない間のコストが不要
48
+ - 環境を作る時にやる気を出す必要なし
49
+
50
+ ??? question "やる気ってなに?"
51
+ 作者の場合、環境を作るステップ毎に1時間の休憩が必要です。このステップは、コマンドを1つ打つだけでもカウントされるため、5ステップもあると1日が終わります。
52
+ コマンド1つなら1時間、2つだと2時間になるので、コマンドを1つまとめるだけで大違いです。
53
+
54
+ さらに、この精神的負荷は、環境を作るとお金がかかる、消すのが手間、ということから来ている部分も多く、100個作っても平気で消すのも簡単となると、1時間以下で作れるようになるのではないかと考えています。
55
+
56
+ ## Background
57
+
58
+ 小規模プロジェクトを運用する際、課題が2つありました。
59
+
60
+ - **サーバーセキュリティ**: サーバーがあるから悩む => サーバーレス
61
+ - **開発環境のコスト**: 利用していない時に止めたい => サーバーレス
62
+
63
+ とりあえず、クラウドフォーメーションのテンプレートを使いまわしていたのですが、様々な問題(1)に直面し、なかなか簡単な環境作成とはなりませんでした。
64
+ {.annotate}
65
+
66
+ 1. !!! failure "様々な問題"
67
+ - Django側に同じ設定を書く必要がある
68
+ - コピペを間違える(yamlがややこしすぎる)
69
+ - クラウドフォーメーションを削除しても一部リソースが残る(S3バケットとか)
70
+ - 依存関係がややこしく、作成順を間違える
71
+
72
+ ??? question "自分が悪くない?"
73
+ いや、間違えさせる仕組みが悪い:angry:
74
+
75
+
76
+ そうしている中で、「そもそも、やりたいことってこんな複雑なんだっけ?」という疑問が湧き、設定したい内容を tomlで書いてみました。
77
+
78
+ 5行ぐらいでした。
79
+
80
+ そのtomlを読み込んでインフラ構築を行うライブラリを作成した結果が、magic-pocket です。
81
+
82
+ 途中、tomlが複雑になりすぎ(1)、yamlに変更しようかとも思いましたが、それならクラウドフォーメーションでいいじゃん、ということで複雑な機能を開発するのは止めて、設定ファイルはtomlになっています。
83
+ {.annotate}
84
+
85
+ 1. 実際に設定したい情報は少なくても、ある程度AWSのリソースと対応させた方が分かりやすかったため。寄せすぎて、劣化クラウドフォーメーションになりそうでした。
86
+
87
+ ??? question "なぜFargateでなくLambda?"
88
+ 最初は順当に Fargate を使いましたが、私が個人で保守するのは厳しいと感じました。
89
+
90
+ `設定が分からない`
91
+ : 特にヘルスチェック周りの設定が理解できませんでした。最初にDBに接続してmigrationを行いたいのに、ヘルスチェックが通らず詰みました。
92
+
93
+ `インスタンスが立ち上がるのが遅い`
94
+ : 20分待ってやっと設定エラーで動かない事が分かる、という地獄に何度も会いました。
95
+ また、せっかくサーバーレスなのに、アクセスにスパイクがあるとレスポンスが出来ない、というのは残念です。
96
+ 当然出来ると思い立ち上げたら、いきなり落ちて愕然としました。
97
+
98
+
99
+ !!! warning annotate "固定費は必要"
100
+ 以下は、無視できない固定費として必要です。
101
+
102
+ `NAT gateway`
103
+ : EFS(cache)、Neonに接続可能なIP制限、RDSなどで必要。
104
+ dev環境を大量に作るなら、共通化するか、そもそも作らないか検討が必須。
105
+
106
+ magic-pocketでは、同プロジェクト内であれば、別環境でも共有する設定が可能。
107
+
108
+ `SecretsManager`
109
+ : 個数に対する従量課金ではあるが、気軽に作りすぎると無視できないコストになる。
110
+ 可能な場合に保存場所を共通化すれば良い。
111
+
112
+ magic-pocketでは、同プロジェクト内であれば、別環境でも共有する設定が可能。(1)
113
+
114
+ `Neon`
115
+ : 月額サブスク料金。1アカウントで複数プロジェクト使えるので、RDSと比較すれば十分安い。
116
+
117
+ 1. 当然、利用する値は環境ごとに異なります。ただし、レコードを共有するため、値を取得する権限は共有されます。