build fixes and static files fix, closes #28

This commit is contained in:
badblocks 2025-04-19 17:10:46 -07:00
parent bff2525c65
commit 6a44ef30a3
26 changed files with 91 additions and 39 deletions

View file

@ -1,14 +1,12 @@
# Pull base image
FROM python:3.12.2-bookworm
# Set environment variables (we want to write bytecode as we have multiple workers, so omit PYTHONDONTWRITEBYTECODE)
# (we want to write bytecode as we have multiple workers, so omit PYTHONDONTWRITEBYTECODE)
ENV PYTHONUNBUFFERED 1
ENV HOME /code
# Create and set work directory called `app`
RUN mkdir -p /code
WORKDIR /code
# Install dependencies
COPY requirements.txt /tmp/requirements.txt
RUN set -ex && \
@ -16,20 +14,16 @@ RUN set -ex && \
pip install -r /tmp/requirements.txt && \
rm -rf /root/.cache/
# Copy local project
COPY . /code/
COPY .env.production /code/.env
ENV HOME=/code
RUN apt-get update && apt-get install -y nodejs npm xvfb netcat-openbsd nano curl
# Install playwright (via pip and install script)
RUN playwright install-deps && playwright install
# Expose port 8000
COPY . /code/
COPY .env.production /code/.env
EXPOSE 8000
HEALTHCHECK CMD curl --fail http://localhost:8000 || exit 1
# Use gunicorn on port 8000
CMD ["gunicorn", "--bind", ":8000", "django_project.wsgi", "--workers", "4", "--worker-tmp-dir", "/dev/shm", "--timeout", "90"]
#CMD ["gunicorn", "--bind", ":8000", "django_project.wsgi", "--workers", "3", "--worker-class", "gevent", "--worker-connections", "1000", "--worker-tmp-dir", "/dev/shm", "--timeout", "90"]
CMD ["granian", "--interface", "wsgi", "django_project.wsgi", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"]

View file

@ -1,4 +1,4 @@
#!/bin/bash
python manage.py migrate --noinput
python manage.py clear_cache
python manage.py collectstatic --noinput
python manage.py collectstatic -c --no-input

View file

@ -1,19 +1,18 @@
from django.conf import settings
from django.contrib.auth import login
from accounts.models import CustomUser
from django.contrib.auth.models import User
class AutoLoginMiddleware:
"""
In development, automatically logs in as a predefined user if the request is anonymous.
"""
import time
import logging
class LogRequestsMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Only perform auto-login if in DEBUG mode and user is not authenticated.
if settings.DEBUG and not request.user.is_authenticated and request.host in ['pocket-trade.fly.dev', 'localhost', '127.0.0.1']:
user = CustomUser.objects.get(email='rob@badblocks.email')
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
start = time.perf_counter()
response = self.get_response(request)
return response
end = time.perf_counter()
self.log(request, response, start, end)
return response
def log(self, request, response, start, end):
logging.info(f"{request.method} {request.path_info} -> {response.status_code}, took {end - start}s")

View file

@ -2,11 +2,48 @@ import socket
from pathlib import Path
import environ
import os
import logging
import sys
env = environ.Env(
DEBUG=(bool, False)
)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
},
},
'handlers': {
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'stream': sys.stdout,
'formatter': 'verbose',
'filters': [],
},
},
'loggers': {
'django': {
'handlers': ['console'],
'level': 'INFO',
},
'django.server': {
'handlers': ['console'],
'level': 'INFO',
'propagate': False,
},
'': {
'handlers': ['console'],
'level': 'INFO',
'propagate': True,
},
},
}
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@ -80,10 +117,12 @@ MIDDLEWARE = [
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"allauth.account.middleware.AccountMiddleware", # django-allauth
"django_project.middleware.LogRequestsMiddleware",
]
if DEBUG:
MIDDLEWARE.append("django_browser_reload.middleware.BrowserReloadMiddleware")
MIDDLEWARE.append(
"django_browser_reload.middleware.BrowserReloadMiddleware")
MIDDLEWARE.append("debug_toolbar.middleware.DebugToolbarMiddleware")
DAISY_SETTINGS = {
@ -164,7 +203,7 @@ STATIC_ROOT = BASE_DIR / "staticfiles"
STATIC_URL = "/static/"
# https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = []
STATICFILES_DIRS = [BASE_DIR / "static"]
# https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = BASE_DIR / "media"
@ -211,7 +250,9 @@ INTERNAL_IPS = [
# for docker development
hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
INTERNAL_IPS.append([ip[:-1] + "1" for ip in ips])
for ip in ips:
INTERNAL_IPS.append(ip)
ALLOWED_HOSTS.append(ip)
# https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model
AUTH_USER_MODEL = "accounts.CustomUser"

View file

@ -10,7 +10,6 @@ urlpatterns = [
path('account/', include('accounts.urls')),
path("trades/", include("trades.urls")),
path("__reload__/", include("django_browser_reload.urls")),
#path('silk/', include('silk.urls', namespace='silk')),
]
if settings.DEBUG:

View file

@ -5,3 +5,4 @@ from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_project.settings")
application = get_wsgi_application()
app = application

View file

@ -1,7 +1,7 @@
services:
web:
build: .
command: python /code/manage.py runserver 0.0.0.0:8000
#command: python /code/manage.py runserver 0.0.0.0:8000
volumes:
- .:/code:z
ports:

View file

@ -12,6 +12,7 @@ console_command = '/code/manage.py shell'
[deploy]
release_command = 'bash deploy.sh'
strategy = 'bluegreen'
[env]
PORT = '8000'
@ -24,9 +25,16 @@ console_command = '/code/manage.py shell'
min_machines_running = 0
processes = ['app']
[[http_service.checks]]
grace_period = "15s"
interval = "30s"
method = "GET"
timeout = "10s"
path = "/health"
[[vm]]
size = 'shared-cpu-4x'
memory = '1gb'
size = 'shared-cpu-8x'
memory = '2gb'
[[statics]]
guest_path = '/code/static'

View file

@ -1,7 +1,9 @@
from django.urls import path
from .views import HomePageView
from .views import HomePageView, HealthCheckView
urlpatterns = [
path("", HomePageView.as_view(), name="home"),
path("health", HealthCheckView.as_view(), name="health"),
path("health/", HealthCheckView.as_view(), name="health"),
]

View file

@ -10,7 +10,8 @@ from django.utils.decorators import method_decorator
from django.template.response import TemplateResponse
from django.http import HttpResponseRedirect
import logging
#from silk.profiling.profiler import silk_profile
from django.views import View
from django.http import HttpResponse
logger = logging.getLogger(__name__)
@ -113,4 +114,8 @@ class HomePageView(TemplateView):
def get(self, request, *args, **kwargs):
"""Override get method to add caching"""
return super().get(request, *args, **kwargs)
return super().get(request, *args, **kwargs)
class HealthCheckView(View):
def get(self, request, *args, **kwargs):
return HttpResponse("OK/HEALTHY")

View file

@ -14,6 +14,9 @@ docker compose -f docker-compose_db_only.yml down \
echo "Waiting for the database to be ready..."
sleep 10
echo "Resetting static files..."
uv run python manage.py collectstatic -c --no-input
echo "Running makemigrations..."
uv run python manage.py makemigrations

View file

Before

Width:  |  Height:  |  Size: 549 B

After

Width:  |  Height:  |  Size: 549 B

Before After
Before After

View file

@ -25,12 +25,12 @@
</a>
<!-- Main Card Row: Single row with the acceptance's cards -->
<div class="px-2 pb-0">
<div class="grid grid-cols-2 items-center">
<div class="grid grid-cols-2 items-center gap-2">
<div class="flex flex-col items-center">
<div class="cursor-pointer">{% card_badge acceptance.requested_card %}</div>
{% card_badge acceptance.requested_card %}
</div>
<div class="flex flex-col items-center">
<div class="cursor-pointer">{% card_badge acceptance.offered_card %}</div>
{% card_badge acceptance.offered_card %}
</div>
</div>
</div>