build fixes and static files fix, closes #28
This commit is contained in:
parent
bff2525c65
commit
6a44ef30a3
26 changed files with 91 additions and 39 deletions
20
Dockerfile
20
Dockerfile
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
12
fly.toml
12
fly.toml
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 549 B After Width: | Height: | Size: 549 B |
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue