diff --git a/.dockerignore b/.dockerignore index b9cfaf9..c0e5dd2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,3 +10,4 @@ venv data/**/* !data/**/.gitignore fly.toml +.env* diff --git a/.gitignore b/.gitignore index b2b4b82..70a06dd 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ __pycache__/ *.log .DS_Store node_modules/ +.env* diff --git a/README.md b/README.md index 1a375c5..ed93c00 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,44 @@ ```bash python -m venv venv && \ . venv/bin/activate && \ - pip install pip-tools --upgrade && \ + pip install pip pip-tools --upgrade && \ pip-sync requirements/dev.txt && \ + npm install && \ python manage.py makemigrations && \ python manage.py migrate && \ python manage.py createsuperuser +``` + +## Run development server + +```bash +npm run dev +``` + +## Deploy + +### Launch fly.io app + +```bash +fly launch --ha=false --volume-initial-size=1 +``` -python manage.py runserver +### Set fly.io secrets + +```bash +cat .env.prod | xargs fly secrets set +``` + +### Build bundles + +```bash +npm run build +``` + +### Deploy changes when needed + +```bash +fly deploy ``` diff --git a/apps/site/templates/site/base.html b/apps/site/templates/site/base.html index e525f77..d363329 100644 --- a/apps/site/templates/site/base.html +++ b/apps/site/templates/site/base.html @@ -1,16 +1,51 @@ - - - {% block html %} - - {% block head %} - {% block title %}{% endblock title %} - {% block meta %} - {% endblock meta %} - {% endblock head %} - - - {% block body %} - {% endblock body %} - - {% endblock html %} - +{% extends 'site/layouts/stacked.html' %} +{% load static %} +{% block title %}Example{% endblock title %} +{% block meta %} +{% include 'site/partials/meta.html' %} +{% endblock meta %} +{% block nav %} +
+
+ + + logo + Example + +
+ +
+{% endblock nav %} +{% block header %} +
+ + + logo + Example + + +
+{% endblock header %} +{% block footer %} +
+

+ © {% now 'Y' %} Example. All rights reserved. +

+
+{% endblock footer %} diff --git a/apps/site/templates/site/home.html b/apps/site/templates/site/home.html index 01c64c8..92c7a2e 100644 --- a/apps/site/templates/site/home.html +++ b/apps/site/templates/site/home.html @@ -1,33 +1,9 @@ -{% extends 'site/layouts/stacked.html' %} +{% extends 'site/base.html' %} {% load static %} -{% block title %}Example{% endblock title %} -{% block meta %} -{% include 'site/partials/meta.html' %} -{% endblock meta %} {% block body %} {% include 'site/components/faq.html' %} {{ block.super }} {% endblock body %} -{% block nav %} -
-
- - - logo - Example - -
- -
-{% endblock nav %} {% block header %}
{% endblock main %} -{% block footer %} -
-

- © {% now 'Y' %} Example. All rights reserved. -

-
-{% endblock footer %} diff --git a/apps/site/templates/site/layouts/base.html b/apps/site/templates/site/layouts/base.html new file mode 100644 index 0000000..e525f77 --- /dev/null +++ b/apps/site/templates/site/layouts/base.html @@ -0,0 +1,16 @@ + + + {% block html %} + + {% block head %} + {% block title %}{% endblock title %} + {% block meta %} + {% endblock meta %} + {% endblock head %} + + + {% block body %} + {% endblock body %} + + {% endblock html %} + diff --git a/apps/site/templates/site/layouts/stacked.html b/apps/site/templates/site/layouts/stacked.html index 13699d3..e846684 100644 --- a/apps/site/templates/site/layouts/stacked.html +++ b/apps/site/templates/site/layouts/stacked.html @@ -1,4 +1,4 @@ -{% extends 'site/base.html' %} +{% extends 'site/layouts/base.html' %} {% load static %} {% block head %} {{ block.super }} diff --git a/example/settings/base.py b/example/settings/base.py index 5dd9b73..9833f7b 100644 --- a/example/settings/base.py +++ b/example/settings/base.py @@ -176,6 +176,7 @@ "level": "ERROR", "filters": ["require_debug_false"], "class": "django.utils.log.AdminEmailHandler", + "include_html": True, }, "file": { "level": "DEBUG", diff --git a/example/settings/prod.py b/example/settings/prod.py index bb01c11..ca51cd6 100644 --- a/example/settings/prod.py +++ b/example/settings/prod.py @@ -6,4 +6,16 @@ ALLOWED_HOSTS = [ "example.fly.dev", + "example.com", ] + +EMAIL_BACKEND = "django_ses.SESBackend" + +AWS_SES_ACCESS_KEY_ID = os.environ.get("AWS_SES_ACCESS_KEY_ID", "") +AWS_SES_SECRET_ACCESS_KEY = os.environ.get("AWS_SES_SECRET_ACCESS_KEY", "") +AWS_SES_REGION_NAME = os.environ.get("AWS_SES_REGION_NAME", "") +AWS_SES_REGION_ENDPOINT = os.environ.get("AWS_SES_REGION_ENDPOINT", "") + +SERVER_EMAIL = "Example Server " +DEFAULT_FROM_EMAIL = "Admin from Example " +ADMINS = [("Admin", "admin@example.com")] diff --git a/fly.toml b/fly.toml index 9664e4a..a6ae806 100644 --- a/fly.toml +++ b/fly.toml @@ -1,10 +1,17 @@ app = 'example' +[build] + [env] DJANGO_SETTINGS_MODULE = 'example.settings.dev' PYTHONDONTWRITEBYTECODE = '1' PYTHONUNBUFFERED = '1' +[[mounts]] + source = 'example_data' + destination = '/app/data' + processes = ['app'] + [http_service] internal_port = 8000 force_https = true @@ -13,9 +20,7 @@ app = 'example' min_machines_running = 1 processes = ['app'] -[[http_service.checks]] - interval = '30s' - timeout = '5s' - grace_period = '5s' - method = 'GET' - path = '/' +[[vm]] + memory = '1gb' + cpu_kind = 'shared' + cpus = 1 diff --git a/requirements/base.ini b/requirements/base.ini index 84be6ac..8545879 100644 --- a/requirements/base.ini +++ b/requirements/base.ini @@ -3,3 +3,4 @@ celery ipython gunicorn whitenoise +django-ses diff --git a/requirements/base.txt b/requirements/base.txt index 3160371..5a8f2b8 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -12,6 +12,12 @@ asttokens==2.4.1 # via stack-data billiard==4.2.0 # via celery +boto3==1.34.61 + # via django-ses +botocore==1.34.61 + # via + # boto3 + # s3transfer celery==5.3.6 # via -r requirements/base.ini click==8.1.7 @@ -29,6 +35,10 @@ click-repl==0.3.0 decorator==5.1.1 # via ipython django==5.0.1 + # via + # -r requirements/base.ini + # django-ses +django-ses==3.5.2 # via -r requirements/base.ini executing==2.0.1 # via stack-data @@ -38,6 +48,10 @@ ipython==8.20.0 # via -r requirements/base.ini jedi==0.19.1 # via ipython +jmespath==1.0.1 + # via + # boto3 + # botocore kombu==5.3.5 # via celery matplotlib-inline==0.1.6 @@ -59,7 +73,13 @@ pure-eval==0.2.2 pygments==2.17.2 # via ipython python-dateutil==2.8.2 - # via celery + # via + # botocore + # celery +pytz==2024.1 + # via django-ses +s3transfer==0.10.0 + # via boto3 six==1.16.0 # via # asttokens @@ -74,6 +94,8 @@ traitlets==5.14.1 # matplotlib-inline tzdata==2023.4 # via celery +urllib3==2.0.7 + # via botocore vine==5.1.0 # via # amqp diff --git a/requirements/dev.txt b/requirements/dev.txt index 1b64f6e..735a548 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -22,6 +22,15 @@ billiard==4.2.0 # celery black==24.1.0 # via -r requirements/dev.ini +boto3==1.34.61 + # via + # -r requirements/base.txt + # django-ses +botocore==1.34.61 + # via + # -r requirements/base.txt + # boto3 + # s3transfer celery==5.3.6 # via -r requirements/base.txt click==8.1.7 @@ -51,7 +60,10 @@ decorator==5.1.1 django==5.0.1 # via # -r requirements/base.txt + # django-ses # model-bakery +django-ses==3.5.2 + # via -r requirements/base.txt executing==2.0.1 # via # -r requirements/base.txt @@ -64,6 +76,11 @@ jedi==0.19.1 # via # -r requirements/base.txt # ipython +jmespath==1.0.1 + # via + # -r requirements/base.txt + # boto3 + # botocore kombu==5.3.5 # via # -r requirements/base.txt @@ -113,7 +130,16 @@ pygments==2.17.2 python-dateutil==2.8.2 # via # -r requirements/base.txt + # botocore # celery +pytz==2024.1 + # via + # -r requirements/base.txt + # django-ses +s3transfer==0.10.0 + # via + # -r requirements/base.txt + # boto3 six==1.16.0 # via # -r requirements/base.txt @@ -136,6 +162,10 @@ tzdata==2023.4 # via # -r requirements/base.txt # celery +urllib3==2.0.7 + # via + # -r requirements/base.txt + # botocore vine==5.1.0 # via # -r requirements/base.txt