diff --git a/src/django_project/core/settings.py b/src/django_project/core/settings.py index 7e46033..6236cf4 100644 --- a/src/django_project/core/settings.py +++ b/src/django_project/core/settings.py @@ -85,6 +85,17 @@ ] +SECURE_HSTS_SECONDS = 0 +SECURE_SSL_REDIRECT: bool = env.bool("SECURE_SSL_REDIRECT", False) +SESSION_COOKIE_SECURE: bool = env.bool("SESSION_COOKIE_SECURE", True) +CSRF_COOKIE_SECURE: bool = env.bool("CSRF_COOKIE_SECURE", True) +CSRF_TRUSTED_ORIGINS: list[str] = [f"https://{host}" for host in ALLOWED_HOSTS] + +# Required for HTTP behind Traefik +SECURE_PROXY_SSL_HEADER: tuple = ("HTTP_X_FORWARDED_PROTO", "http") +USE_X_FORWARDED_HOST: bool = env.bool("USE_X_FORWARDED_HOST", True) + + ROOT_URLCONF = "core.urls" TEMPLATES = [ diff --git a/src/docker/docker-compose.yaml b/src/docker/docker-compose.yaml index 8c05292..1880182 100644 --- a/src/docker/docker-compose.yaml +++ b/src/docker/docker-compose.yaml @@ -1,17 +1,29 @@ -version: '3.9' +networks: + web: + external: true services: django: - image: ghcr.io/spokanetech/spokanepythonweb:latest container_name: django + image: ghcr.io/spokanetech/spokanepythonweb:latest build: context: ../.. dockerfile: src/docker/Dockerfile env_file: - ../envs/.env.docker-compose - command: ./entrypoint.sh - ports: - - "8000:8000" + command: "./entrypoint.sh" + labels: + - "traefik.enable=true" + + # Router for HTTPS + - "traefik.http.routers.django.rule=Host(`davidslusser.website`) || Host(`www.davidslusser.website`)" + - "traefik.http.routers.django.entrypoints=websecure" + - "traefik.http.routers.django.tls.certresolver=myresolver" + + # Service settings + - "traefik.http.services.django.loadbalancer.server.port=8000" + networks: + - web depends_on: - db restart: unless-stopped @@ -25,6 +37,8 @@ services: - "5432:5432" env_file: - ../envs/.env.docker-compose + networks: + - web restart: unless-stopped volumes: diff --git a/src/docker/local-compose.yaml b/src/docker/local-compose.yaml new file mode 100644 index 0000000..180ecf3 --- /dev/null +++ b/src/docker/local-compose.yaml @@ -0,0 +1,29 @@ +services: + django: + image: ghcr.io/spokanetech/spokanepythonweb:latest + container_name: django + build: + context: ../.. + dockerfile: src/docker/Dockerfile + env_file: + - ../envs/.env.docker-compose + command: ./entrypoint.sh + ports: + - "8000:8000" + depends_on: + - db + restart: unless-stopped + + db: + image: postgres:17 + container_name: postgres + volumes: + - spokanepython_postgres:/var/lib/postgresql/data + ports: + - "5432:5432" + env_file: + - ../envs/.env.docker-compose + restart: unless-stopped + +volumes: + spokanepython_postgres: diff --git a/src/docker/traefik-compose.yaml b/src/docker/traefik-compose.yaml new file mode 100644 index 0000000..c38b4bb --- /dev/null +++ b/src/docker/traefik-compose.yaml @@ -0,0 +1,54 @@ +networks: + web: + external: true + +services: + traefik: + image: traefik:v3.0 + container_name: traefik + command: + - "--api.dashboard=true" + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + + # Entry points + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + + # Redirect HTTP to HTTPS + - "--entrypoints.web.http.redirections.entrypoint.to=websecure" + - "--entrypoints.web.http.redirections.entrypoint.scheme=https" + + # Let's Encrypt + - "--certificatesresolvers.myresolver.acme.httpchallenge=true" + - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web" + - "--certificatesresolvers.myresolver.acme.email=admin@davidslusser.website" + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" + + ports: + - "80:80" + - "443:443" + - "8000:8000" + + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "letsencrypt:/letsencrypt" + + networks: + - web + restart: unless-stopped + + labels: + - "traefik.enable=true" + + # Dashboard route + - "traefik.http.routers.traefik.rule=Host(`traefik.davidslusser.website`)" + - "traefik.http.routers.traefik.service=api@internal" + - "traefik.http.routers.traefik.entrypoints=websecure" + - "traefik.http.routers.traefik.tls.certresolver=myresolver" + # Auth middleware for dashboard + - "traefik.http.middlewares.traefik-auth.basicauth.users=${TRAEFIK_DASH_AUTH}" + - "traefik.http.routers.traefik.middlewares=traefik-auth" + +volumes: + letsencrypt: