mirror of
https://github.com/andwati/andwati.com.git
synced 2026-10-18 01:12:53 +00:00
Merge pull request #3 from andwati/migrate-security-headers-to-sws
Serve security headers via static-web-server, drop Cloudflare deploy path
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
public
|
public
|
||||||
node_modules
|
node_modules
|
||||||
.wrangler
|
|
||||||
.git
|
.git
|
||||||
manimations/*.*
|
manimations/*.*
|
||||||
/zola
|
/zola
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
public
|
public
|
||||||
node_modules
|
node_modules
|
||||||
.wrangler
|
|
||||||
manimations/*.*
|
manimations/*.*
|
||||||
/zola
|
/zola
|
||||||
/zola-v*.tar.gz
|
/zola-v*.tar.gz
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ A personal blog (andwati.com — "Thoughts and Musings") built with [Zola](https
|
|||||||
|
|
||||||
There is no JS/CSS build tooling beyond Zola itself: `compile_sass = true` in `zola.toml` means Sass under `sass/` is compiled directly by Zola.
|
There is no JS/CSS build tooling beyond Zola itself: `compile_sass = true` in `zola.toml` means Sass under `sass/` is compiled directly by Zola.
|
||||||
|
|
||||||
Deployment is via Cloudflare (`wrangler.toml`, `npm run deploy` → `zola build && wrangler deploy`), serving `public/` as static assets on `andwati.com`/`www.andwati.com`.
|
Deployment is self-hosted via Dokploy: `Dockerfile` builds the site with Zola and serves `public/` with `static-web-server`, configured by `sws.toml` (security headers, redirects) at the image's working directory root.
|
||||||
|
|
||||||
## Content structure
|
## Content structure
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -1,9 +1,8 @@
|
|||||||
# Multi-stage build: generate llms.txt with Node, build the site with Zola,
|
# Multi-stage build: generate llms.txt with Node, build the site with Zola,
|
||||||
# then serve the static output with static-web-server.
|
# then serve the static output with static-web-server.
|
||||||
#
|
#
|
||||||
# This is the Dokploy/self-hosted deployment path. It's independent of the
|
# This is the Dokploy/self-hosted deployment path (the only one - the prior
|
||||||
# Cloudflare Pages path (`npm run deploy` / wrangler.toml) - that stays in
|
# Cloudflare Pages/Workers path has been retired).
|
||||||
# place as an option, this doesn't replace it.
|
|
||||||
|
|
||||||
FROM node:22-slim AS llms
|
FROM node:22-slim AS llms
|
||||||
WORKDIR /project
|
WORKDIR /project
|
||||||
@@ -18,4 +17,5 @@ RUN ["/zola", "build"]
|
|||||||
|
|
||||||
FROM ghcr.io/static-web-server/static-web-server:2
|
FROM ghcr.io/static-web-server/static-web-server:2
|
||||||
COPY --from=zola /project/public /public
|
COPY --from=zola /project/public /public
|
||||||
|
COPY sws.toml /sws.toml
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|||||||
Generated
+1
-1540
File diff suppressed because it is too large
Load Diff
+2
-4
@@ -4,13 +4,11 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@resvg/resvg-js": "^2.6.2",
|
"@resvg/resvg-js": "^2.6.2",
|
||||||
"satori": "^0.29.0",
|
"satori": "^0.29.0",
|
||||||
"wawoff2": "^2.0.1",
|
"wawoff2": "^2.0.1"
|
||||||
"wrangler": "^4"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"generate:llms": "node scripts/generate-llms.mjs",
|
"generate:llms": "node scripts/generate-llms.mjs",
|
||||||
"generate:og": "node scripts/generate-og-images.mjs",
|
"generate:og": "node scripts/generate-og-images.mjs",
|
||||||
"build": "npm run generate:llms && npm run generate:og && zola build",
|
"build": "npm run generate:llms && npm run generate:og && zola build"
|
||||||
"deploy": "npm run build && wrangler deploy"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
/*
|
|
||||||
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://utteranc.es https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://www.google-analytics.com; font-src 'self'; connect-src 'self' https://www.google-analytics.com https://cloudflareinsights.com; frame-src https://www.youtube-nocookie.com https://utteranc.es; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests
|
|
||||||
X-Frame-Options: DENY
|
|
||||||
X-Content-Type-Options: nosniff
|
|
||||||
Referrer-Policy: strict-origin-when-cross-origin
|
|
||||||
Permissions-Policy: camera=(), microphone=(), geolocation=(), interest-cohort=()
|
|
||||||
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
/security.txt /.well-known/security.txt 301
|
|
||||||
/index.xml /rss.xml 301
|
|
||||||
+7
-1
@@ -58,7 +58,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const theme = htmlElement.classList.contains('dark')
|
const theme = htmlElement.classList.contains('dark')
|
||||||
? commentsEl.dataset.utterancesThemeDark
|
? commentsEl.dataset.utterancesThemeDark
|
||||||
: commentsEl.dataset.utterancesThemeLight;
|
: commentsEl.dataset.utterancesThemeLight;
|
||||||
frame.contentWindow.postMessage({ type: 'set-theme', theme }, 'https://utteranc.es');
|
// The iframe briefly shares our origin before it navigates to utteranc.es,
|
||||||
|
// so posting with that targetOrigin throws until the navigation completes.
|
||||||
|
try {
|
||||||
|
frame.contentWindow.postMessage({ type: 'set-theme', theme }, 'https://utteranc.es');
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore: frame hasn't navigated to utteranc.es yet.
|
||||||
|
}
|
||||||
};
|
};
|
||||||
new MutationObserver(syncUtterancesTheme).observe(htmlElement, {
|
new MutationObserver(syncUtterancesTheme).observe(htmlElement, {
|
||||||
attributes: true,
|
attributes: true,
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
[advanced]
|
||||||
|
|
||||||
|
[[advanced.headers]]
|
||||||
|
source = "**"
|
||||||
|
[advanced.headers.headers]
|
||||||
|
Content-Security-Policy = "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://utteranc.es https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://www.google-analytics.com; font-src 'self'; connect-src 'self' https://www.google-analytics.com https://cloudflareinsights.com; frame-src https://www.youtube-nocookie.com https://utteranc.es; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests"
|
||||||
|
X-Frame-Options = "DENY"
|
||||||
|
X-Content-Type-Options = "nosniff"
|
||||||
|
Referrer-Policy = "strict-origin-when-cross-origin"
|
||||||
|
Permissions-Policy = "camera=(), microphone=(), geolocation=(), interest-cohort=()"
|
||||||
|
Strict-Transport-Security = "max-age=63072000; includeSubDomains; preload"
|
||||||
|
|
||||||
|
[[advanced.redirects]]
|
||||||
|
source = "/security.txt"
|
||||||
|
destination = "/.well-known/security.txt"
|
||||||
|
kind = 301
|
||||||
|
|
||||||
|
[[advanced.redirects]]
|
||||||
|
source = "/index.xml"
|
||||||
|
destination = "/rss.xml"
|
||||||
|
kind = 301
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
name = "andwati-com"
|
|
||||||
compatibility_date = "2026-07-16"
|
|
||||||
|
|
||||||
[assets]
|
|
||||||
directory = "./public"
|
|
||||||
not_found_handling = "404-page"
|
|
||||||
|
|
||||||
[[routes]]
|
|
||||||
pattern = "andwati.com"
|
|
||||||
custom_domain = true
|
|
||||||
|
|
||||||
[[routes]]
|
|
||||||
pattern = "www.andwati.com"
|
|
||||||
custom_domain = true
|
|
||||||
|
|
||||||
[observability]
|
|
||||||
enabled = false
|
|
||||||
head_sampling_rate = 1
|
|
||||||
|
|
||||||
[observability.logs]
|
|
||||||
enabled = true
|
|
||||||
head_sampling_rate = 1
|
|
||||||
persist = true
|
|
||||||
invocation_logs = true
|
|
||||||
|
|
||||||
[observability.traces]
|
|
||||||
enabled = false
|
|
||||||
persist = true
|
|
||||||
head_sampling_rate = 1
|
|
||||||
Reference in New Issue
Block a user