Compare commits

...

6 Commits

16 changed files with 129 additions and 24 deletions

View File

@@ -1,15 +1,15 @@
FROM python:3.14-alpine FROM python:3.14-alpine
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /src WORKDIR /src
COPY requirements.txt /src/ COPY requirements.txt /src/
COPY gunicorn.conf.py /src/
COPY ./src/ /src/
RUN pip install --upgrade pip && \ RUN pip install --upgrade pip && \
pip install --no-cache-dir -r requirements.txt pip install --no-cache-dir -r requirements.txt
EXPOSE 8000 COPY gunicorn.conf.py /src/
COPY ./src/ /src/
CMD ["gunicorn", "website.wsgi:application"] CMD ["gunicorn", "website.wsgi:application"]

View File

@@ -1,20 +1,22 @@
.SHELLFLAGS := -ec
prod: prod:
docker compose down docker compose down
docker compose --env-file .env -f ./compose.yaml -f ./.docker-compose-files/compose.prod.yaml up -d --build docker compose --env-file .env -f ./compose.yaml -f ./.docker-compose-files/compose.prod.yaml up -d --build
docker exec quatsh-website-web-1 python manage.py collectstatic --noinput docker compose exec web python manage.py collectstatic --noinput
docker exec quatsh-website-web-1 python manage.py check --deploy docker compose exec web python manage.py check --deploy
docker exec quatsh-website-web-1 python manage.py migrate docker compose exec web python manage.py migrate
dev: dev:
docker compose down docker compose down
docker compose -f ./compose.yaml -f ./.docker-compose-files/compose.dev.yaml up --build -d docker compose -f ./compose.yaml -f ./.docker-compose-files/compose.dev.yaml up --build -d
docker exec quatsh-website-web-1 python manage.py collectstatic --noinput docker compose exec web python manage.py collectstatic --noinput
docker exec -it quatsh-website-web-1 sh docker compose exec -it web sh
dev_restart: dev_restart:
docker compose down docker compose down
docker compose -f ./compose.yaml -f ./.docker-compose-files/compose.dev.yaml up -d docker compose -f ./compose.yaml -f ./.docker-compose-files/compose.dev.yaml up -d
docker exec -it quatsh-website-web-1 sh docker compose exec -it web sh
dev_restart_with_logs: dev_restart_with_logs:
docker compose down docker compose down

View File

@@ -3,11 +3,11 @@ services:
build: . build: .
command: gunicorn website.wsgi:application command: gunicorn website.wsgi:application
depends_on: depends_on:
- db db:
condition: service_healthy
environment: environment:
ALLOWED_HOSTS: ${NGINX_HOSTNAME} ALLOWED_HOSTS: ${NGINX_HOSTNAME}
PYTHONDONTWRITEBYTECODE: 1
PYTHONUNBUFFERED: 1
DJANGO_SETTINGS_MODULE: ${DJANGO_SETTINGS_MODULE} DJANGO_SETTINGS_MODULE: ${DJANGO_SETTINGS_MODULE}
VIRTUAL_HOST: localhost VIRTUAL_HOST: localhost
#VIRTUAL_PORT: 8000 #VIRTUAL_PORT: 8000
@@ -15,6 +15,9 @@ services:
volumes: volumes:
- static_volume:/app/static - static_volume:/app/static
- media_volume:/app/media - media_volume:/app/media
networks:
- frontend
- backend
db: db:
@@ -26,6 +29,12 @@ services:
volumes: volumes:
- postgres_data:/var/lib/postgresql - postgres_data:/var/lib/postgresql
restart: unless-stopped restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DBNAME}"]
interval: 5s
retries: 5
networks:
- backend
adminer: adminer:
image: adminer image: adminer
@@ -33,7 +42,9 @@ services:
- db - db
restart: always restart: always
ports: ports:
- 8080:8080 - 127.0.0.1:8080:8080
networks:
- backend
proxy: proxy:
image: nginx:stable image: nginx:stable
@@ -51,15 +62,12 @@ services:
- NGINX_SSL_PORT=443 - NGINX_SSL_PORT=443
depends_on: depends_on:
- web - web
networks:
- frontend
test: networks:
build: . frontend:
command: python manage.py test backend:
depends_on:
- db
profiles:
- test
volumes: volumes:
postgres_data: postgres_data:

View File

72
docs/templates/template.md vendored Normal file
View File

@@ -0,0 +1,72 @@
# Feature Name
> One sentence description of what this feature does and who it is for.
## Status
<!-- Delete all that do not apply -->
`Planned` `In Progress` `In Review` `Complete` `Deferred`
## Background
<!-- Why are we building this? What problem does it solve? Link to any relevant roadmap phase. -->
## Scope
<!-- What is included in this feature. Be explicit about what is out of scope too. -->
**In scope:**
-
**Out of scope:**
-
## User Stories
<!-- Who interacts with this feature and what do they want to achieve? -->
- As a **[member / board member / anonymous visitor]**, I want to **[action]** so that **[outcome]**.
## Data Model
<!-- What models are created or modified? List fields and their types. -->
```python
class ExampleModel(models.Model):
pass
```
**Related models:**
- `User`
## GDPR Considerations
<!-- See docs/gdpr/ for shared policies. Only document what is specific to this feature. -->
| Question | Answer |
|---|---|
| Personal data collected | |
| Legal basis | Legitimate interest / Consent / Legal obligation |
| Retention period | See `docs/gdpr/retention-policy.md` / [custom policy] |
| Erasure behaviour | Cascade delete / Anonymise / Transfer ownership |
| Visible to non-members | Yes / No |
## Open Questions
<!-- Unresolved decisions that are blocking or will affect implementation. -->
- [ ]
## Decisions Log
<!-- Record decisions made during development so future contributors understand why things are the way they are. -->
| Date | Decision | Reasoning |
|---|---|---|
| YYYY-MM-DD | | |
## Tasks
<!-- Break the feature down into concrete implementation steps. -->
### Backend
- [ ]
### Frontend
- [ ]
### Tests
- [ ]
## Related
<!-- Links to related feature files, external docs, or GitHub issues. -->
-

View File

@@ -3,3 +3,7 @@ gunicorn==25.1.0
psycopg [binary] ==3.3.3 psycopg [binary] ==3.3.3
django-browser-reload django-browser-reload
django-watchfiles django-watchfiles
docutils==0.22.4
ruff==0.15.9
Mypy==1.20
django-stubs==5.0.2

0
src/gallery/__init__.py Normal file
View File

3
src/gallery/admin.py Normal file
View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
src/gallery/apps.py Normal file
View File

@@ -0,0 +1,5 @@
from django.apps import AppConfig
class GalleryConfig(AppConfig):
name = 'gallery'

View File

3
src/gallery/models.py Normal file
View File

@@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

3
src/gallery/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
src/gallery/views.py Normal file
View File

@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

View File

@@ -40,6 +40,7 @@ INSTALLED_APPS = [
"django.contrib.sessions", "django.contrib.sessions",
"django.contrib.messages", "django.contrib.messages",
"django.contrib.staticfiles", "django.contrib.staticfiles",
"django.contrib.admindocs",
"django_browser_reload", "django_browser_reload",
"django_watchfiles", "django_watchfiles",
] ]

View File

@@ -19,7 +19,8 @@ from django.contrib import admin
from django.urls import path, include from django.urls import path, include
urlpatterns = [ urlpatterns = [
path("__reload__/", include("django_browser_reload.urls")),
path("polls/", include("polls.urls")), path("polls/", include("polls.urls")),
path("admin/doc/", include("django.contrib.admindocs.urls")),
path("admin/", admin.site.urls), path("admin/", admin.site.urls),
path("__reload__/", include("django_browser_reload.urls")),
] ]