generated from Dicken/dickendock
HTTPS im lokalen Netz (Port 8443, selbstsigniertes Zertifikat, optional mkcert)
This commit is contained in:
@@ -24,7 +24,12 @@ RUN pnpm --filter @launchpad/frontend build
|
||||
|
||||
# ---- runtime: nginx --------------------------------------------------------
|
||||
FROM nginx:1.27-alpine AS runtime
|
||||
RUN apk add --no-cache openssl
|
||||
COPY apps/frontend/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY apps/frontend/nginx-locations.conf /etc/nginx/launchpad-locations.conf
|
||||
COPY apps/frontend/docker-entrypoint.sh /docker-entrypoint.sh
|
||||
RUN chmod +x /docker-entrypoint.sh
|
||||
COPY --from=build /app/apps/frontend/dist /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
EXPOSE 80 443
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
38
apps/frontend/docker-entrypoint.sh
Normal file
38
apps/frontend/docker-entrypoint.sh
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
CERT_DIR="/etc/nginx/certs"
|
||||
CERT_FILE="$CERT_DIR/fullchain.pem"
|
||||
KEY_FILE="$CERT_DIR/privkey.pem"
|
||||
|
||||
# Falls der Nutzer eigene Zertifikate eingebunden hat (siehe README, z. B.
|
||||
# per mkcert erzeugt), diese nicht überschreiben.
|
||||
if [ ! -f "$CERT_FILE" ] || [ ! -f "$KEY_FILE" ]; then
|
||||
HOST="${LAUNCHPAD_HOST:-localhost}"
|
||||
mkdir -p "$CERT_DIR"
|
||||
|
||||
# IP-Adresse oder Hostname? Browser verlangen bei IP-Zugriff eine
|
||||
# IP-SAN, ein DNS-Name genügt da nicht.
|
||||
case "$HOST" in
|
||||
*[0-9]*.*[0-9]*.*[0-9]*.*[0-9]*)
|
||||
SAN="IP:$HOST,DNS:localhost,IP:127.0.0.1"
|
||||
;;
|
||||
*)
|
||||
SAN="DNS:$HOST,DNS:localhost,IP:127.0.0.1"
|
||||
;;
|
||||
esac
|
||||
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout "$KEY_FILE" \
|
||||
-out "$CERT_FILE" \
|
||||
-subj "/CN=$HOST" \
|
||||
-addext "subjectAltName=$SAN" \
|
||||
2>/dev/null
|
||||
|
||||
echo "[entrypoint] Selbstsigniertes HTTPS-Zertifikat für '$HOST' erzeugt."
|
||||
echo "[entrypoint] Der Browser zeigt dafür eine Sicherheitswarnung - siehe README fuer eine Variante ohne Warnung (mkcert)."
|
||||
else
|
||||
echo "[entrypoint] Verwende eingebundenes Zertifikat unter $CERT_DIR."
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
32
apps/frontend/nginx-locations.conf
Normal file
32
apps/frontend/nginx-locations.conf
Normal file
@@ -0,0 +1,32 @@
|
||||
# PWA / SPA: alle unbekannten Routen auf index.html zurückführen
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# API-Anfragen an den Backend-Container weiterleiten
|
||||
location /api/ {
|
||||
proxy_pass http://backend:3001/api/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# Service Worker und Manifest dürfen nicht langfristig gecacht werden,
|
||||
# sonst bekommen installierte PWA-Nutzer nie ein Update mit.
|
||||
location = /sw.js {
|
||||
add_header Cache-Control "no-cache";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location = /manifest.webmanifest {
|
||||
add_header Cache-Control "no-cache";
|
||||
default_type application/manifest+json;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location ~* \.(?:css|js|svg|png|jpg|jpeg|gif|ico|woff2?)$ {
|
||||
expires 7d;
|
||||
add_header Cache-Control "public, max-age=604800, immutable";
|
||||
}
|
||||
@@ -1,39 +1,26 @@
|
||||
# HTTP – bleibt zusätzlich zu HTTPS verfügbar (kein erzwungener Redirect,
|
||||
# damit bestehende http://-Zugriffe nicht plötzlich brechen).
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# PWA / SPA: alle unbekannten Routen auf index.html zurückführen
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# API-Anfragen an den Backend-Container weiterleiten
|
||||
location /api/ {
|
||||
proxy_pass http://backend:3001/api/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# Service Worker und Manifest dürfen nicht langfristig gecacht werden,
|
||||
# sonst bekommen installierte PWA-Nutzer nie ein Update mit.
|
||||
location = /sw.js {
|
||||
add_header Cache-Control "no-cache";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location = /manifest.webmanifest {
|
||||
add_header Cache-Control "no-cache";
|
||||
default_type application/manifest+json;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location ~* \.(?:css|js|svg|png|jpg|jpeg|gif|ico|woff2?)$ {
|
||||
expires 7d;
|
||||
add_header Cache-Control "public, max-age=604800, immutable";
|
||||
}
|
||||
include /etc/nginx/launchpad-locations.conf;
|
||||
}
|
||||
|
||||
# HTTPS – Zertifikat wird vom Entrypoint-Skript automatisch erzeugt
|
||||
# (selbstsigniert) oder ist vom Nutzer eingebunden, siehe README.
|
||||
server {
|
||||
listen 443 ssl;
|
||||
http2 on;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
||||
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
||||
include /etc/nginx/launchpad-locations.conf;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user