Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 33 additions & 21 deletions app/Dockerfile-aws
Original file line number Diff line number Diff line change
@@ -1,44 +1,56 @@
# pull official base image
FROM python:3.10-alpine
# Stage 1: build dependencies and collect static files
FROM python:3.10-alpine AS builder

# set work directory
WORKDIR /usr/src/app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PYTHONPYCACHEPREFIX=/root/.cache/pycache/
ENV DJANGO_SETTINGS_MODULE=peopledepot.settings_aws

COPY ./requirements-aws.txt .
# hadolint ignore=DL3042
RUN \
--mount=type=cache,target=/root/.cache \
pip install uv==0.1.15 \
&& uv pip install --system -r requirements-aws.txt

COPY . .
RUN python manage.py collectstatic --noinput


# Stage 2: runtime image
FROM python:3.10-alpine AS runtime

WORKDIR /usr/src/app

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PYTHONPYCACHEPREFIX=/root/.cache/pycache/
ENV DJANGO_SETTINGS_MODULE=peopledepot.settings_aws

# install system dependencies
RUN \
--mount=type=cache,target=/var/cache/apk \
--mount=type=cache,target=/etc/apk/cache \
apk add \
'graphviz=~12'

# install font for graphviz
COPY Roboto-Regular.ttf /root/.fonts/
RUN fc-cache -f

# install dependencies
COPY ./requirements.txt .
# hadolint ignore=DL3042
RUN \
pip install uv==0.1.15 \
&& uv pip install --system -r requirements.txt

# copy installed Python packages and executables from builder
COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages
COPY --from=builder /usr/local/bin/gunicorn /usr/local/bin/gunicorn

# copy project
COPY . .
# copy application code and collected static files from builder
COPY --from=builder /usr/src/app .

# copy entrypoint-aws.sh
COPY ./entrypoint-aws.sh .
# configure entrypoint
RUN sed -i 's/\r$//g' /usr/src/app/entrypoint-aws.sh \
&& chmod +x /usr/src/app/entrypoint-aws.sh

# Expose the Django port
EXPOSE 8000


# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint-aws.sh"]

# Run Django’s development server
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
4 changes: 2 additions & 2 deletions app/entrypoint-aws.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/sh

python manage.py migrate
python manage.py migrate --noinput

exec "$@"
exec gunicorn peopledepot.wsgi:application --bind 0.0.0.0:8000
2 changes: 1 addition & 1 deletion app/peopledepot/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

# 'DJANGO_ALLOWED_HOSTS' should be a single string of hosts with a space between each.
# For example: 'DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]'
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(",")
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost").split(",")


SECURE_HSTS_SECONDS = int(os.getenv("SECURE_HSTS_SECONDS", "0"))
Expand Down
37 changes: 37 additions & 0 deletions app/peopledepot/settings_aws.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from .settings import * # noqa: F401, F403
Comment thread
drakeredwind01 marked this conversation as resolved.
Dismissed

ROOT_URLCONF = "peopledepot.urls_aws"

STATIC_ROOT = BASE_DIR / "staticfiles"
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
}

INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
# 3rd party
"django_extensions",
"rest_framework",
"phonenumber_field",
"timezone_field",
# Local
"core",
"data",
]

REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": ("core.api.permissions.DenyAny",),
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_jwt.authentication.JSONWebTokenAuthentication",
),
}
15 changes: 15 additions & 0 deletions app/peopledepot/urls_aws.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from django.contrib import admin
from django.http import HttpResponse
from django.urls import include
from django.urls import path


def index(request):
return HttpResponse("You're at the peopledepot index.")


urlpatterns = [
path("", index),
path("admin/", admin.site.urls),
path("api/v1/", include("core.api.urls")),
]
11 changes: 11 additions & 0 deletions app/requirements-aws.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
django~=4.2.27
django-extensions
django-phonenumber-field[phonenumbers]
django-timezone-field
djangorestframework
drf-jwt
drf-spectacular
gunicorn
psycopg2-binary
tzdata
whitenoise
76 changes: 76 additions & 0 deletions app/requirements-aws.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
asgiref==3.11.1
# via django
attrs==26.1.0
# via
# jsonschema
# referencing
cffi==2.0.0
# via cryptography
cryptography==48.0.1
# via pyjwt
django==4.2.30
# via
# -r requirements-aws.in
# django-extensions
# django-phonenumber-field
# django-timezone-field
# djangorestframework
# drf-jwt
# drf-spectacular
django-extensions==4.1
# via -r requirements-aws.in
django-phonenumber-field==8.4.0
# via -r requirements-aws.in
django-timezone-field==7.2.2
# via -r requirements-aws.in
djangorestframework==3.17.1
# via
# -r requirements-aws.in
# drf-jwt
# drf-spectacular
drf-jwt==1.19.2
# via -r requirements-aws.in
drf-spectacular==0.29.0
# via -r requirements-aws.in
gunicorn==26.0.0
# via -r requirements-aws.in
inflection==0.5.1
# via drf-spectacular
jsonschema==4.26.0
# via drf-spectacular
jsonschema-specifications==2025.9.1
# via jsonschema
packaging==26.2
# via gunicorn
phonenumbers==9.0.32
# via django-phonenumber-field
psycopg2-binary==2.9.12
# via -r requirements-aws.in
pycparser==3.0
# via cffi
pyjwt==2.13.0
# via drf-jwt
pyyaml==6.0.3
# via drf-spectacular
referencing==0.37.0
# via
# jsonschema
# jsonschema-specifications
rpds-py==0.30.0
# via
# jsonschema
# referencing
sqlparse==0.5.5
# via django
typing-extensions==4.15.0
# via
# asgiref
# cryptography
# pyjwt
# referencing
tzdata==2026.2
# via -r requirements-aws.in
uritemplate==4.2.0
# via drf-spectacular
whitenoise==6.12.0
# via -r requirements-aws.in
10 changes: 7 additions & 3 deletions docs/architecture/project_structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ app/
├── manage.py # (7)!
├── requirements.in # (8)!
├── requirements.txt # (9)!
└── setup.cfg # (10)!
├── requirements-aws.in # (10)!
├── requirements-aws.txt # (11)!
└── setup.cfg # (12)!
```

1. The core app in django. This app contains the API and models. See [Core App](#core-app) below for details.
Expand All @@ -47,8 +49,10 @@ app/
1. Dockerfile used to build the Docker image.
1. Entrypoint script called by the Docker image.
1. Django manage.py script. In nearly all cases, there's no good reason to change this. Just leave it alone.
1. Requirements.in file used by `uv pip compile`. See the [uv tool](uv.md) for details.
1. Requirements.txt file generated by `uv pip install`. Do not modify this file. Edit the `requirements.in` file instead. See the [uv tool](uv.md) for details.
1. Development requirements source file used by `uv pip compile`. Contains all dependencies including dev/test packages. See the [uv tool](uv.md) for details.
1. Development requirements file generated from `requirements.in`. Do not modify this file directly. Edit `requirements.in` instead. See the [uv tool](uv.md) for details.
1. AWS/production requirements source file. Contains only production dependencies — no dev or test packages.
1. AWS/production requirements file generated from `requirements-aws.in`. Do not modify this file directly. Edit `requirements-aws.in` instead.
1. Config file for development support tools such as `flake8` and `pytest`. `flake8` is the only tool that doesn't support `pyproject.toml` yet, which is why we have this file.

#### Core App
Expand Down
3 changes: 3 additions & 0 deletions scripts/update-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ set -x

# generate requirements.txt with the latest package versions
docker compose exec web uv pip compile -o requirements.txt requirements.in --no-header --upgrade

# generate requirements-aws.txt with the latest package versions
docker compose exec web uv pip compile -o requirements-aws.txt requirements-aws.in --no-header --upgrade --python-version 3.10
Loading