k8s-native stack: Traefik edge + cert-manager LE DNS-01 + per-site static deployments
This commit is contained in:
parent
0e68abc772
commit
f33385dacc
9 changed files with 397 additions and 126 deletions
|
|
@ -1,11 +1,9 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Build the static site and ensure the edge nginx serves it.
|
# Build sites and sync docroots. Routing/TLS are handled by Traefik + cert-manager
|
||||||
# Content changes need no pod restart (hostPath is live); config changes trigger a reload.
|
# in the cluster, so content deploys need no pod reloads or restarts.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
BASE=/home/opc/zai-home-base
|
BASE=/home/opc/zai-home-base
|
||||||
K="sudo /usr/local/bin/k3s kubectl"
|
|
||||||
|
|
||||||
echo "==> building site"
|
echo "==> building site"
|
||||||
python3 build.py
|
python3 build.py
|
||||||
|
|
@ -13,25 +11,18 @@ python3 build.py
|
||||||
mkdir -p "$BASE/sites"
|
mkdir -p "$BASE/sites"
|
||||||
rm -rf "$BASE/sites/bestdadjokes.new"
|
rm -rf "$BASE/sites/bestdadjokes.new"
|
||||||
cp -r site "$BASE/sites/bestdadjokes.new"
|
cp -r site "$BASE/sites/bestdadjokes.new"
|
||||||
# ensure SELinux-friendly context if SELinux is enforcing
|
|
||||||
if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" = "Enforcing" ]; then
|
if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" = "Enforcing" ]; then
|
||||||
chcon -Rt container_file_t "$BASE/sites/bestdadjokes.new" 2>/dev/null || true
|
chcon -Rt container_file_t "$BASE/sites/bestdadjokes.new" 2>/dev/null || true
|
||||||
chcon -Rt container_file_t "$BASE/bdj/nginx/conf.d" 2>/dev/null || true
|
|
||||||
fi
|
fi
|
||||||
rm -rf "$BASE/sites/bestdadjokes.old"
|
rm -rf "$BASE/sites/bestdadjokes.old"
|
||||||
[ -d "$BASE/sites/bestdadjokes" ] && mv "$BASE/sites/bestdadjokes" "$BASE/sites/bestdadjokes.old"
|
[ -d "$BASE/sites/bestdadjokes" ] && mv "$BASE/sites/bestdadjokes" "$BASE/sites/bestdadjokes.old"
|
||||||
mv "$BASE/sites/bestdadjokes.new" "$BASE/sites/bestdadjokes"
|
mv "$BASE/sites/bestdadjokes.new" "$BASE/sites/bestdadjokes"
|
||||||
rm -rf "$BASE/sites/bestdadjokes.old"
|
rm -rf "$BASE/sites/bestdadjokes.old"
|
||||||
|
|
||||||
echo "==> applying edge manifest"
|
echo "==> verifying through Traefik (origin)"
|
||||||
$K apply -f k8s/nginx-edge.yaml
|
|
||||||
|
|
||||||
POD=$($K get pods -l app=nginx-edge -o jsonpath='{.items[0].metadata.name}')
|
|
||||||
echo "==> reloading nginx config in pod $POD"
|
|
||||||
$K exec "$POD" -- nginx -s reload 2>/dev/null || true
|
|
||||||
|
|
||||||
echo "==> verifying"
|
|
||||||
sleep 1
|
sleep 1
|
||||||
code=$($K exec "$POD" -- wget -q -O- --header="Host: bestdadjokes.lol" http://127.0.0.1/ | head -c 60)
|
for host in bestdadjokes.lol www.bestdadjokes.lol myadhd.dev; do
|
||||||
echo "first bytes of homepage: $code"
|
code=$(curl -sk -o /dev/null -w '%{http_code}' --resolve "$host:443:127.0.0.1" "https://$host/" --max-time 10)
|
||||||
|
echo " https://$host -> $code (origin)"
|
||||||
|
done
|
||||||
echo "==> deploy complete"
|
echo "==> deploy complete"
|
||||||
|
|
|
||||||
23
bdj/k8s/letsencrypt-issuer.yaml
Normal file
23
bdj/k8s/letsencrypt-issuer.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Let's Encrypt via cert-manager, DNS-01 through the Cloudflare API token.
|
||||||
|
# The token lives in Secret cert-manager/cloudflare-api-token (created out-of-band
|
||||||
|
# via `kubectl create secret ... --from-file=api-token=...`; never committed).
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: letsencrypt-prod
|
||||||
|
spec:
|
||||||
|
acme:
|
||||||
|
server: https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
email: hello@bestdadjokes.lol
|
||||||
|
privateKeySecretRef:
|
||||||
|
name: letsencrypt-prod-account-key
|
||||||
|
solvers:
|
||||||
|
- dns01:
|
||||||
|
cloudflare:
|
||||||
|
apiTokenSecretRef:
|
||||||
|
name: cloudflare-api-token
|
||||||
|
key: api-token
|
||||||
|
selector:
|
||||||
|
dnsZones:
|
||||||
|
- bestdadjokes.lol
|
||||||
|
- myadhd.dev
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: DaemonSet
|
|
||||||
metadata:
|
|
||||||
name: nginx-edge
|
|
||||||
namespace: default
|
|
||||||
labels:
|
|
||||||
app: nginx-edge
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: nginx-edge
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: nginx-edge
|
|
||||||
spec:
|
|
||||||
hostNetwork: true
|
|
||||||
dnsPolicy: ClusterFirstWithHostNet
|
|
||||||
nodeSelector:
|
|
||||||
kubernetes.io/hostname: djg-oracle-sl
|
|
||||||
tolerations:
|
|
||||||
- key: node-role.kubernetes.io/master
|
|
||||||
operator: Exists
|
|
||||||
effect: NoSchedule
|
|
||||||
- key: node-role.kubernetes.io/control-plane
|
|
||||||
operator: Exists
|
|
||||||
effect: NoSchedule
|
|
||||||
containers:
|
|
||||||
- name: nginx
|
|
||||||
image: nginx:alpine
|
|
||||||
imagePullPolicy: IfNotPresent
|
|
||||||
ports:
|
|
||||||
- containerPort: 80
|
|
||||||
hostPort: 80
|
|
||||||
protocol: TCP
|
|
||||||
volumeMounts:
|
|
||||||
- name: conf
|
|
||||||
mountPath: /etc/nginx/conf.d
|
|
||||||
readOnly: true
|
|
||||||
- name: sites
|
|
||||||
mountPath: /srv/www
|
|
||||||
readOnly: true
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
cpu: 20m
|
|
||||||
memory: 32Mi
|
|
||||||
limits:
|
|
||||||
memory: 128Mi
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /
|
|
||||||
port: 80
|
|
||||||
httpHeaders:
|
|
||||||
- name: Host
|
|
||||||
value: bestdadjokes.lol
|
|
||||||
initialDelaySeconds: 5
|
|
||||||
periodSeconds: 30
|
|
||||||
volumes:
|
|
||||||
- name: conf
|
|
||||||
hostPath:
|
|
||||||
path: /home/opc/zai-home-base/bdj/nginx/conf.d
|
|
||||||
type: Directory
|
|
||||||
- name: sites
|
|
||||||
hostPath:
|
|
||||||
path: /home/opc/zai-home-base/sites
|
|
||||||
type: DirectoryOrCreate
|
|
||||||
262
bdj/k8s/static-sites.yaml
Normal file
262
bdj/k8s/static-sites.yaml
Normal file
|
|
@ -0,0 +1,262 @@
|
||||||
|
# Static site fleet: one nginx Deployment + Service + Ingress + Certificate per site.
|
||||||
|
# Docroots come from hostPath /home/opc/zai-home-base/sites/<site> (built by deploy scripts).
|
||||||
|
# Edge routing/TLS: Traefik (80/443) + cert-manager Let's Encrypt secrets.
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: static-nginx-conf
|
||||||
|
data:
|
||||||
|
nginx.conf: |
|
||||||
|
worker_processes 1;
|
||||||
|
error_log /dev/stderr warn;
|
||||||
|
pid /run/nginx.pid;
|
||||||
|
events { worker_connections 1024; }
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
access_log /dev/stdout;
|
||||||
|
sendfile on;
|
||||||
|
gzip on;
|
||||||
|
gzip_types text/plain text/css application/javascript application/json application/xml image/svg+xml;
|
||||||
|
gzip_min_length 1024;
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
error_page 404 /404.html;
|
||||||
|
add_header X-Content-Type-Options nosniff always;
|
||||||
|
add_header Referrer-Policy strict-origin-when-cross-origin always;
|
||||||
|
location ~* \.(css|js|svg|png|jpg|ico|woff2?)$ {
|
||||||
|
expires 7d;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
}
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ $uri/index.html =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
---
|
||||||
|
# ---------------- bestdadjokes.lol ----------------
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: static-bdj
|
||||||
|
labels:
|
||||||
|
site: bestdadjokes.lol
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
site: bestdadjokes.lol
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
site: bestdadjokes.lol
|
||||||
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
kubernetes.io/hostname: djg-oracle-sl
|
||||||
|
tolerations:
|
||||||
|
- key: node-role.kubernetes.io/master
|
||||||
|
operator: Exists
|
||||||
|
effect: NoSchedule
|
||||||
|
- key: node-role.kubernetes.io/control-plane
|
||||||
|
operator: Exists
|
||||||
|
effect: NoSchedule
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: nginx:alpine
|
||||||
|
volumeMounts:
|
||||||
|
- name: conf
|
||||||
|
mountPath: /etc/nginx/nginx.conf
|
||||||
|
subPath: nginx.conf
|
||||||
|
readOnly: true
|
||||||
|
- name: html
|
||||||
|
mountPath: /usr/share/nginx/html
|
||||||
|
readOnly: true
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 20m
|
||||||
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
|
readinessProbe:
|
||||||
|
httpGet: {path: /, port: 80}
|
||||||
|
initialDelaySeconds: 2
|
||||||
|
periodSeconds: 20
|
||||||
|
volumes:
|
||||||
|
- name: conf
|
||||||
|
configMap:
|
||||||
|
name: static-nginx-conf
|
||||||
|
- name: html
|
||||||
|
hostPath:
|
||||||
|
path: /home/opc/zai-home-base/sites/bestdadjokes
|
||||||
|
type: Directory
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: static-bdj
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
site: bestdadjokes.lol
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 80
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: bestdadjokes
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: bestdadjokes.lol
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: static-bdj
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
- host: www.bestdadjokes.lol
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: static-bdj
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- bestdadjokes.lol
|
||||||
|
- www.bestdadjokes.lol
|
||||||
|
secretName: bestdadjokes-tls
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: bestdadjokes-lol
|
||||||
|
spec:
|
||||||
|
secretName: bestdadjokes-tls
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt-prod
|
||||||
|
kind: ClusterIssuer
|
||||||
|
dnsNames:
|
||||||
|
- bestdadjokes.lol
|
||||||
|
- www.bestdadjokes.lol
|
||||||
|
---
|
||||||
|
# ---------------- myadhd.dev (placeholder) ----------------
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: static-adhd
|
||||||
|
labels:
|
||||||
|
site: myadhd.dev
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
site: myadhd.dev
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
site: myadhd.dev
|
||||||
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
kubernetes.io/hostname: djg-oracle-sl
|
||||||
|
tolerations:
|
||||||
|
- key: node-role.kubernetes.io/master
|
||||||
|
operator: Exists
|
||||||
|
effect: NoSchedule
|
||||||
|
- key: node-role.kubernetes.io/control-plane
|
||||||
|
operator: Exists
|
||||||
|
effect: NoSchedule
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: nginx:alpine
|
||||||
|
volumeMounts:
|
||||||
|
- name: conf
|
||||||
|
mountPath: /etc/nginx/nginx.conf
|
||||||
|
subPath: nginx.conf
|
||||||
|
readOnly: true
|
||||||
|
- name: html
|
||||||
|
mountPath: /usr/share/nginx/html
|
||||||
|
readOnly: true
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 20m
|
||||||
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
|
readinessProbe:
|
||||||
|
httpGet: {path: /, port: 80}
|
||||||
|
initialDelaySeconds: 2
|
||||||
|
periodSeconds: 20
|
||||||
|
volumes:
|
||||||
|
- name: conf
|
||||||
|
configMap:
|
||||||
|
name: static-nginx-conf
|
||||||
|
- name: html
|
||||||
|
hostPath:
|
||||||
|
path: /home/opc/zai-home-base/sites/myadhd.dev
|
||||||
|
type: Directory
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: static-adhd
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
site: myadhd.dev
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 80
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: myadhd
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: myadhd.dev
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: static-adhd
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
- host: www.myadhd.dev
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: static-adhd
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- myadhd.dev
|
||||||
|
- www.myadhd.dev
|
||||||
|
secretName: myadhd-tls
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: myadhd-dev
|
||||||
|
spec:
|
||||||
|
secretName: myadhd-tls
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt-prod
|
||||||
|
kind: ClusterIssuer
|
||||||
|
dnsNames:
|
||||||
|
- myadhd.dev
|
||||||
|
- www.myadhd.dev
|
||||||
101
bdj/k8s/traefik.yaml
Normal file
101
bdj/k8s/traefik.yaml
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
# Traefik v3 as the cluster edge: hostNetwork 80/443, global http->https redirect.
|
||||||
|
# TLS certificates are provisioned by cert-manager into Ingress secrets.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
|
namespace: kube-system
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["services", "endpoints", "secrets", "namespaces"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
- apiGroups: ["networking.k8s.io"]
|
||||||
|
resources: ["ingresses", "ingressclasses"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
- apiGroups: ["networking.k8s.io"]
|
||||||
|
resources: ["ingresses/status"]
|
||||||
|
verbs: ["update"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: traefik
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: traefik
|
||||||
|
namespace: kube-system
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
name: traefik
|
||||||
|
namespace: kube-system
|
||||||
|
labels:
|
||||||
|
app: traefik
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: traefik
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: traefik
|
||||||
|
spec:
|
||||||
|
serviceAccountName: traefik
|
||||||
|
hostNetwork: true
|
||||||
|
dnsPolicy: ClusterFirstWithHostNet
|
||||||
|
nodeSelector:
|
||||||
|
kubernetes.io/hostname: djg-oracle-sl
|
||||||
|
tolerations:
|
||||||
|
- key: node-role.kubernetes.io/master
|
||||||
|
operator: Exists
|
||||||
|
effect: NoSchedule
|
||||||
|
- key: node-role.kubernetes.io/control-plane
|
||||||
|
operator: Exists
|
||||||
|
effect: NoSchedule
|
||||||
|
containers:
|
||||||
|
- name: traefik
|
||||||
|
image: traefik:v3.3
|
||||||
|
args:
|
||||||
|
- --providers.kubernetesingress
|
||||||
|
- --entrypoints.web.address=:80
|
||||||
|
- --entrypoints.web.http.redirections.entrypoint.to=websecure
|
||||||
|
- --entrypoints.web.http.redirections.entrypoint.scheme=https
|
||||||
|
- --entrypoints.websecure.address=:443
|
||||||
|
- --ping=true
|
||||||
|
- --ping.entrypoint=health
|
||||||
|
- --entrypoints.health.address=:8082
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
hostPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
- containerPort: 443
|
||||||
|
hostPort: 443
|
||||||
|
protocol: TCP
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /ping
|
||||||
|
port: 8082
|
||||||
|
initialDelaySeconds: 3
|
||||||
|
periodSeconds: 10
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /ping
|
||||||
|
port: 8082
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 30
|
||||||
2
bdj/nginx/README.md
Normal file
2
bdj/nginx/README.md
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Placeholder: the hand-rolled nginx edge was removed in favor of Traefik + cert-manager.
|
||||||
|
# Vhosts now live as Ingress resources in bdj/k8s/static-sites.yaml.
|
||||||
2
bdj/nginx/certs/README.md
Normal file
2
bdj/nginx/certs/README.md
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Placeholder: self-signed origin certs were removed in favor of cert-manager
|
||||||
|
# issuing Let's Encrypt certificates into k8s Secrets (see bdj/k8s/letsencrypt-issuer.yaml).
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
# bestdadjokes.lol
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
listen [::]:80;
|
|
||||||
server_name bestdadjokes.lol;
|
|
||||||
|
|
||||||
root /srv/www/bestdadjokes;
|
|
||||||
index index.html;
|
|
||||||
|
|
||||||
error_page 404 /404.html;
|
|
||||||
|
|
||||||
gzip on;
|
|
||||||
gzip_types text/plain text/css application/javascript application/json application/xml image/svg+xml;
|
|
||||||
gzip_min_length 1024;
|
|
||||||
|
|
||||||
add_header X-Content-Type-Options nosniff always;
|
|
||||||
add_header Referrer-Policy strict-origin-when-cross-origin always;
|
|
||||||
|
|
||||||
location ~* \.(css|js|svg|png|jpg|ico|woff2?)$ {
|
|
||||||
expires 7d;
|
|
||||||
add_header Cache-Control "public";
|
|
||||||
}
|
|
||||||
|
|
||||||
location = /favicon.ico { return 302 /static/favicon.svg; }
|
|
||||||
|
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ $uri/index.html =404;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# www redirect
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
listen [::]:80;
|
|
||||||
server_name www.bestdadjokes.lol;
|
|
||||||
return 301 http://bestdadjokes.lol$request_uri;
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
# catch-all: drop requests for unknown hosts
|
|
||||||
server {
|
|
||||||
listen 80 default_server;
|
|
||||||
listen [::]:80 default_server;
|
|
||||||
server_name _;
|
|
||||||
return 444;
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue