Compare commits
No commits in common. "a4e31beb216ffc8e534f062b377f17df9b5fd299" and "d4482a18bb3f074eeecbd0405a76291d056e5a89" have entirely different histories.
a4e31beb21
...
d4482a18bb
12 changed files with 47 additions and 336 deletions
|
|
@ -1 +0,0 @@
|
||||||
3.8.18
|
|
||||||
39
Caddyfile
39
Caddyfile
|
|
@ -1,39 +0,0 @@
|
||||||
boday-it.ch {
|
|
||||||
# 1. Globale Komprimierung für schnellere Ladezeiten aktivieren
|
|
||||||
encode gzip zstd
|
|
||||||
|
|
||||||
# 2. Statische Dateien (CSS, JS, Bilder) direkt über Caddy ausliefern
|
|
||||||
handle_path /static/* {
|
|
||||||
root * /code/staticfiles
|
|
||||||
file_server
|
|
||||||
}
|
|
||||||
|
|
||||||
# 3. Medien-Dateien (User-Uploads) direkt über Caddy ausliefern
|
|
||||||
handle_path /media/* {
|
|
||||||
root * /code/mediafiles
|
|
||||||
file_server
|
|
||||||
}
|
|
||||||
|
|
||||||
# 4. Alle anderen Anfragen direkt an den Django-Gunicorn-Container weiterleiten
|
|
||||||
handle {
|
|
||||||
reverse_proxy web:8000
|
|
||||||
}
|
|
||||||
|
|
||||||
# 5. Sicherheits-Header setzen (Optional, aber dringend empfohlen)
|
|
||||||
header {
|
|
||||||
# Verhindert, dass die Seite in einem fremden Frame geladen wird (Schutz vor Clickjacking)
|
|
||||||
#X-Frame-Options "DENY"
|
|
||||||
X-Frame-Options "SAMEORIGIN"
|
|
||||||
# Aktiviert den Cross-Site-Scripting-Schutz im Browser
|
|
||||||
X-XSS-Protection "1; mode=block"
|
|
||||||
# Verhindert das automatische Erraten des Inhaltstyps (MIME-Sniffing)
|
|
||||||
X-Content-Type-Options "nosniff"
|
|
||||||
# Strict-Transport-Security (HSTS) - Erzwingt HTTPS im Browser für 1 Jahr
|
|
||||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# 2. Die www-Subdomain (Automatische Zertifizierung + Weiterleitung)
|
|
||||||
www.boday-it.ch {
|
|
||||||
redir https://boday-it.ch{uri} permanent
|
|
||||||
}
|
|
||||||
25
Dockerfile
25
Dockerfile
|
|
@ -1,25 +0,0 @@
|
||||||
# 1. Das normale, vollständige Python-Image nutzen
|
|
||||||
FROM python:3.8.18
|
|
||||||
|
|
||||||
# 2. Setze Umgebungsvariablen für Python
|
|
||||||
ENV PYTHONDONTWRITEBYTECODE=1
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
|
||||||
|
|
||||||
# 3. Setze das Arbeitsverzeichnis im Container
|
|
||||||
WORKDIR /code
|
|
||||||
|
|
||||||
# 4. Installiere System-Abhängigkeiten
|
|
||||||
# 'gcc' wird hier nicht mehr benötigt, da es im Image schon enthalten ist
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
libpq-dev \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# 5. Installiere die Python-Abhängigkeiten
|
|
||||||
COPY requirements.txt /code/
|
|
||||||
RUN pip install --upgrade pip && pip install -r requirements.txt
|
|
||||||
|
|
||||||
# 6. Kopiere den restlichen Django-Quellcode in den Container
|
|
||||||
COPY . /code/
|
|
||||||
|
|
||||||
# 7. Erstelle die Ordner für statische Medien
|
|
||||||
RUN mkdir -p /code/staticfiles /code/mediafiles
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
# 1. Verwende das offizielle Python 3.8.18 Image auf minimaler Debian-Basis
|
|
||||||
FROM python:3.8.18-slim
|
|
||||||
|
|
||||||
# 2. Setze Umgebungsvariablen für Python
|
|
||||||
# Verhindert, dass Python .pyc-Dateien schreibt
|
|
||||||
ENV PYTHONDONTWRITEBYTECODE=1
|
|
||||||
# Verhindert, dass Python Ausgaben puffert (wichtig für Echtzeit-Docker-Logs)
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
|
||||||
|
|
||||||
# 3. Setze das Arbeitsverzeichnis im Container
|
|
||||||
WORKDIR /code
|
|
||||||
|
|
||||||
# 4. Installiere System-Abhängigkeiten
|
|
||||||
RUN sed -i 's/deb.debian.org/archive.debian.org/g' /etc/apt/sources.list && \
|
|
||||||
sed -i 's/security.debian.org/archive.debian.org/g' /etc/apt/sources.list && \
|
|
||||||
sed -i '/stretch-updates/d' /etc/apt/sources.list && \
|
|
||||||
apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
gcc \
|
|
||||||
libpq-dev \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
|
|
||||||
# 4. Installiere System-Abhängigkeiten
|
|
||||||
# gcc und libpq-dev werden für PostgreSQL (psycopg2) und einige Python-Pakete benötigt
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
gcc \
|
|
||||||
libpq-dev \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# 5. Installiere die Python-Abhängigkeiten
|
|
||||||
# Zuerst requirements.txt kopieren, um den Docker-Cache optimal zu nutzen
|
|
||||||
COPY requirements.txt /code/
|
|
||||||
RUN pip install --upgrade pip && pip install -r requirements.txt
|
|
||||||
|
|
||||||
# 6. Kopiere den restlichen Django-Quellcode in den Container
|
|
||||||
COPY . /code/
|
|
||||||
|
|
||||||
# 7. Erstelle die Ordner für statische Medien (wichtig für die Caddy-Anbindung)
|
|
||||||
RUN mkdir -p /code/staticfiles /code/mediafiles
|
|
||||||
|
|
@ -32,7 +32,7 @@ SECRET_KEY = '2^!=u2@h+36s^_ikb9=#)10gr#ymp1ds0d0*)d@b+e8%9$vv-v'
|
||||||
# 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 = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = ['www.boday-it.ch', '127.0.0.1','boday-it.ch']
|
ALLOWED_HOSTS = ['ww2.boday-it.ch', '127.0.0.1']
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
@ -60,12 +60,12 @@ USE_TZ = True
|
||||||
|
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
MEDIA_URL = '/media/'
|
MEDIA_URL = '/media/'
|
||||||
MEDIA_ROOT = os.path.join(DATA_DIR, 'mediafiles')
|
MEDIA_ROOT = os.path.join(DATA_DIR, 'media')
|
||||||
STATIC_ROOT = os.path.join(DATA_DIR, 'staticfiles')
|
#STATIC_ROOT = os.path.join(DATA_DIR, 'static')
|
||||||
#STATIC_ROOT = "/static"
|
STATIC_ROOT = "/var/www/boday_it/static"
|
||||||
|
|
||||||
STATICFILES_DIRS = (
|
STATICFILES_DIRS = (
|
||||||
os.path.join(BASE_DIR, 'boday_it/static'),
|
os.path.join(BASE_DIR, 'boday_it', 'static'),
|
||||||
)
|
)
|
||||||
SITE_ID = 1
|
SITE_ID = 1
|
||||||
|
|
||||||
|
|
@ -214,9 +214,3 @@ THUMBNAIL_PROCESSORS = (
|
||||||
'filer.thumbnail_processors.scale_and_crop_with_subject_location',
|
'filer.thumbnail_processors.scale_and_crop_with_subject_location',
|
||||||
'easy_thumbnails.processors.filters'
|
'easy_thumbnails.processors.filters'
|
||||||
)
|
)
|
||||||
|
|
||||||
# 1. Sagt Django, dass die Verbindung über Caddy (HTTPS) sicher ist
|
|
||||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
|
||||||
|
|
||||||
# 2. Erlaubt Django CMS das Laden von internen Bearbeitungs-Iframes
|
|
||||||
X_FRAME_OPTIONS = 'SAMEORIGIN'
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,3 @@
|
||||||
body {
|
|
||||||
font-family: Roboto, "Helvetica Neue", Helvetica, sans-serif;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 1.6;
|
|
||||||
color: #666;
|
|
||||||
font-weight: 500; /* Macht die Linien dicker */
|
|
||||||
}
|
|
||||||
|
|
||||||
body#page-top {
|
body#page-top {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
@ -16,6 +8,12 @@ body>div.container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 991px) {
|
||||||
|
body {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: rgb(28, 146, 204);
|
color: rgb(28, 146, 204);
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +57,7 @@ div.blue-box-child {
|
||||||
background: rgb(28, 146, 204);
|
background: rgb(28, 146, 204);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin: 12px;
|
margin: 12px;
|
||||||
width: 100%;
|
width: 96%;
|
||||||
padding: 2%;
|
padding: 2%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,44 +87,53 @@ div.footer-copyright li.pull-right a {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.page--contact a {
|
footer.footer a:focus,
|
||||||
color: inherit;
|
footer.footer a:hover {
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.page--contact a:focus,
|
footer.footer div.container:before,
|
||||||
div.page--contact a:hover {
|
footer.footer div.container:after {
|
||||||
color: rgb(28, 146, 204);
|
content: none;
|
||||||
cursor: pointer !important;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
div.page--contact {
|
footer.footer div.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 12px 0 24px 0;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.page--contact div.contact-child {
|
footer.footer div.container a {
|
||||||
margin: 0;
|
margin: auto 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.page--contact div.contact-child:nth-of-type(2) {
|
@media (max-width:399px) {
|
||||||
text-align: right;
|
footer.footer div.container a {
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width:767px) {
|
|
||||||
div.page--contact {
|
|
||||||
margin: 12px 12px 24px 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width:439px) {
|
|
||||||
div.page--contact div.contact-child {
|
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
footer.footer div.container a:nth-of-type(1) {
|
||||||
|
max-width: 126px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:399px) {
|
||||||
|
footer.footer div.container a:nth-of-type(1) {
|
||||||
|
max-width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer.footer p.footer-logo {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer.footer ul.list-inline {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
footer.footer li.back-top--hidden {
|
footer.footer li.back-top--hidden {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
body#page-top {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
body>div.container {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: rgb(28, 146, 204);
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-main .nav>.active>a>span, .navbar-main .nav>li:hover>a>span {
|
|
||||||
border-color: rgb(28, 146, 204);
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-visual img, .feature-visual-narrow img {
|
|
||||||
left: auto;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-head-narrow .navbar-brand, .navbar-head-narrow .navbar-brand a {
|
|
||||||
background-size: 168px 64px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav>ul a,
|
|
||||||
.nav>ul a:active,
|
|
||||||
.nav>ul a:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:focus,
|
|
||||||
a:-moz-focusring {
|
|
||||||
outline: 0 none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.leadText {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.blue-box {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.blue-box-child {
|
|
||||||
background: rgb(28, 146, 204);
|
|
||||||
color: #fff;
|
|
||||||
margin: 12px;
|
|
||||||
width: 100%;
|
|
||||||
padding: 2%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width:768px) {
|
|
||||||
div.blue-box-child {
|
|
||||||
margin: 12px 0;
|
|
||||||
width: calc(50% - 12px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
div.blue-box-child p,
|
|
||||||
div.blue-box-child ul {
|
|
||||||
line-height: 1.2;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.blue-box-child ul {
|
|
||||||
list-style: none;
|
|
||||||
padding-left: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.footer-copyright {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.footer-copyright li.pull-right a {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.page--contact a {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.page--contact a:focus,
|
|
||||||
div.page--contact a:hover {
|
|
||||||
color: rgb(28, 146, 204);
|
|
||||||
cursor: pointer !important;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.page--contact {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
position: relative;
|
|
||||||
margin: 12px 0 24px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.page--contact div.contact-child {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.page--contact div.contact-child:nth-of-type(2) {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width:767px) {
|
|
||||||
div.page--contact {
|
|
||||||
margin: 12px 12px 24px 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width:439px) {
|
|
||||||
div.page--contact div.contact-child {
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer.footer li.back-top--hidden {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.caret.caret_up {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
docker compose exec web python manage.py collectstatic --noinput
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
# Django Web Application (Python 3.8.18)
|
|
||||||
web:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
command: gunicorn boday_it.wsgi:application --bind 0.0.0.0:8000
|
|
||||||
volumes:
|
|
||||||
- .:/code
|
|
||||||
- static_volume:/code/staticfiles
|
|
||||||
- media_volume:/code/mediafiles
|
|
||||||
environment:
|
|
||||||
- DEBUG=0
|
|
||||||
- SECRET_KEY=aldhguroqugaplslljdgzlshfz
|
|
||||||
- ALLOWED_HOSTS=boday-it.ch,www.boday-it.ch,web,localhost,127.0.0.1
|
|
||||||
expose:
|
|
||||||
- "8000"
|
|
||||||
restart: always
|
|
||||||
depends_on:
|
|
||||||
- db
|
|
||||||
|
|
||||||
# PostgreSQL Database Server
|
|
||||||
db:
|
|
||||||
image: postgres:15-alpine
|
|
||||||
volumes:
|
|
||||||
- postgres_data:/var/lib/postgresql/data
|
|
||||||
environment:
|
|
||||||
- POSTGRES_DB=djangodb
|
|
||||||
- POSTGRES_USER=djangouser
|
|
||||||
- POSTGRES_PASSWORD=asafdksdf
|
|
||||||
restart: always
|
|
||||||
|
|
||||||
# Automatic Let's Encrypt SSL & Reverse Proxy (Caddy)
|
|
||||||
proxy:
|
|
||||||
image: caddy:2-alpine
|
|
||||||
ports:
|
|
||||||
- "80:80" # Natively handles HTTP-01 challenges
|
|
||||||
- "443:443" # Natively serves HTTPS
|
|
||||||
volumes:
|
|
||||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
|
||||||
- static_volume:/code/staticfiles:ro
|
|
||||||
- media_volume:/code/mediafiles:ro
|
|
||||||
- caddy_data:/data
|
|
||||||
- caddy_config:/config
|
|
||||||
restart: always
|
|
||||||
depends_on:
|
|
||||||
- web
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
static_volume:
|
|
||||||
media_volume:
|
|
||||||
caddy_data: # Important: Keeps your SSL certs safe across container restarts
|
|
||||||
caddy_config:
|
|
||||||
BIN
project.db
BIN
project.db
Binary file not shown.
BIN
project.db2
BIN
project.db2
Binary file not shown.
|
|
@ -1,6 +1,7 @@
|
||||||
django-cms>=3.6,<3.7
|
django-cms>=3.6,<3.7
|
||||||
djangocms-admin-style>=1.2,<1.3
|
djangocms-admin-style>=1.2,<1.3
|
||||||
django-treebeard>=4.0,<5.0
|
django-treebeard>=4.0,<5.0
|
||||||
|
|
||||||
djangocms-text-ckeditor>=3.7,<3.8
|
djangocms-text-ckeditor>=3.7,<3.8
|
||||||
djangocms-link>=2.3
|
djangocms-link>=2.3
|
||||||
djangocms-style>=2.1
|
djangocms-style>=2.1
|
||||||
|
|
@ -20,5 +21,3 @@ Pillow>=3.0
|
||||||
django-sekizai>=0.9
|
django-sekizai>=0.9
|
||||||
six
|
six
|
||||||
pytz
|
pytz
|
||||||
gunicorn>=20.1.0
|
|
||||||
psycopg2-binary>=2.9.0
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue