1
0

Dockerize a test environment

This commit is contained in:
Marcel Schwarz 2022-08-03 02:06:55 +02:00
parent b9a598c4f6
commit 293c46631e
6 changed files with 94 additions and 4 deletions

View File

@ -0,0 +1,4 @@
FROM nginx:1.23.1-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d

View File

@ -0,0 +1,11 @@
FROM python:3.10
COPY clubhaus/requirements.txt /tmp/requirements.txt
RUN pip3 install -r /tmp/requirements.txt
RUN pip3 install gunicorn~=20.1.0
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DEBUG_MODE=False
WORKDIR /usr/src/app

View File

@ -0,0 +1,28 @@
version: "3"
services:
backend:
container_name: clubhaus_backend
image: icaotix/clubhaus_backend
build:
context: ../../
dockerfile: Deployment/Test/Dockerfile.python
command: gunicorn clubhaus.wsgi:application --bind 0.0.0.0:8000
volumes:
- ../../clubhaus:/usr/src/app
environment:
- ALLOWED_HOSTS=internal.security
- CSRF_TRUSTED_ORIGINS=internal.security
- IP_RATE_LIMIT_TIME=1 # rate limit doesn't work in docker networking therefore disable it
nginx:
container_name: clubhaus_nginx
image: icaotix/clubhaus_nginx
build:
context: .
dockerfile: Dockerfile.nginx
volumes:
- ../../clubhaus:/usr/src/app:ro
ports:
- 1337:80
depends_on:
- backend

View File

@ -0,0 +1,34 @@
upstream clubhaus_website {
server backend:8000;
}
server {
listen 80;
location / {
proxy_pass http://clubhaus_website;
# forwarding the remote ip
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE_ADDR $remote_addr;
# setting the origin always to the same value as in the docker compose file
# removes the need to set the host on different dev envs
# NEVER USE IN PRODUCTION
proxy_set_header Origin "http://internal.security";
proxy_set_header Host "internal.security";
proxy_redirect off;
# allow uploads up to 20 megabytes (like pictures)
client_max_body_size 20M;
}
# redirect static files to filesystem
location /static/ {
alias /usr/src/app/static/;
}
# redirect media files to filesystem (user uploaded files)
location /media/ {
alias /usr/src/app/media/;
}
}

View File

@ -9,6 +9,7 @@ https://docs.djangoproject.com/en/4.0/topics/settings/
For the full list of settings and their values, see For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/ https://docs.djangoproject.com/en/4.0/ref/settings/
""" """
import os
from pathlib import Path from pathlib import Path
from django.conf.locale.en import formats as en_formats from django.conf.locale.en import formats as en_formats
@ -20,12 +21,12 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-!@gqe(nmv4ylos+2p14nk+&8h$j7g%=n4sdrwqzvr6!8ee$y9@' SECRET_KEY = os.getenv("SECRET_KEY", "django-insecure-!@gqe(nmv4ylos+2p14nk+&8h$j7g%=n4sdrwqzvr6!8ee$y9@")
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = os.getenv("DEBUG_MODE", True)
ALLOWED_HOSTS = ["*", "192.168.235.51", "127.0.0.1", "localhost", "192.168.0.52", "192.168.235.35"] ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "* 192.168.235.51 127.0.0.1 localhost 192.168.0.52 192.168.235.35").split(" ")
# Application definition # Application definition
@ -67,6 +68,9 @@ TEMPLATES = [
}, },
] ]
if csrf_origins := os.getenv("CSRF_TRUSTED_ORIGINS"):
CSRF_TRUSTED_ORIGINS = csrf_origins.split(" ")
WSGI_APPLICATION = 'clubhaus.wsgi.application' WSGI_APPLICATION = 'clubhaus.wsgi.application'
# Database # Database
@ -129,4 +133,8 @@ MEDIA_ROOT = BASE_DIR / "media/"
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# Custom Settings
IP_RATE_LIMIT_TIME = int(os.getenv("IP_RATE_LIMIT_TIME", "3600"))
IP_RATE_LIMIT_COUNT = int(os.getenv("IP_RATE_LIMIT_COUNT", "2"))
# TODO: delete devserver port forward in windows firewall in hammerhead # TODO: delete devserver port forward in windows firewall in hammerhead

View File

@ -5,6 +5,7 @@ from django.shortcuts import render
from django.urls import reverse from django.urls import reverse
from .models import Tobacco, ClubhausEvent, EventDate, EventDateVotes from .models import Tobacco, ClubhausEvent, EventDate, EventDateVotes
import clubhaus.settings as django_settings
def index(request: HttpRequest) -> django.http.HttpResponse: def index(request: HttpRequest) -> django.http.HttpResponse:
@ -42,11 +43,15 @@ def events(request: HttpRequest) -> django.http.HttpResponse:
def voting(request: HttpRequest) -> django.http.HttpResponse: def voting(request: HttpRequest) -> django.http.HttpResponse:
request.session.clear_expired() request.session.clear_expired()
# Proxy use is forbidden
if request.META.get("X-Forwarded-For"):
return HttpResponseForbidden()
ip = request.META.get("REMOTE_ADDR") ip = request.META.get("REMOTE_ADDR")
cache_key = f"voting_block_{ip}" cache_key = f"voting_block_{ip}"
rate_cache: django.core.cache.BaseCache = cache rate_cache: django.core.cache.BaseCache = cache
if ip not in rate_cache: if ip not in rate_cache:
rate_cache.add(cache_key, 0, 3600) rate_cache.add(cache_key, 0, django_settings.IP_RATE_LIMIT_TIME)
rate_cache.incr(cache_key) rate_cache.incr(cache_key)
if request.method == "POST" and rate_cache.get(cache_key) < 3: if request.method == "POST" and rate_cache.get(cache_key) < 3: