diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f65dedb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +# Stage 1: Build the application +FROM --platform=linux/amd64 node:lts AS builder + +RUN npm install -g pnpm + +WORKDIR /app + +COPY package*.json pnpm-*.yaml ./ + +RUN pnpm install + +COPY . . + +RUN pnpm run build + +# Stage 2: Serve the application using Nginx +FROM nginx:stable-alpine + +# Remove the default nginx.conf +RUN rm /etc/nginx/conf.d/default.conf + +# Copy custom nginx configuration +COPY ./nginx.conf /etc/nginx/conf.d/default.conf + +# Copy build artifacts from the builder stage +COPY --from=builder /app/dist /usr/share/nginx/html + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..51af09d --- /dev/null +++ b/nginx.conf @@ -0,0 +1,106 @@ +server { + listen 80; + listen [::]:80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + # Error 404 + error_page 404 /404.html; + + # General headers applied to all routes + add_header X-Frame-Options "DENY"; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Content-Type-Options "nosniff"; + add_header Referrer-Policy "no-referrer-when-downgrade"; + add_header Permissions-Policy "interest-cohort=()"; + + # Special handling for /sw.js + location = /sw.js { + add_header cache-control "max-age=0, no-cache, no-store, must-revalidate"; + } + + # Redirect domain aliases to primary domain + if ($host = 'www.imhoff.name') { + return 301 https://www.stefanimhoff.de$request_uri; + } + + if ($host = 'imhoff.name') { + return 301 https://www.stefanimhoff.de$request_uri; + } + + # Redirects + rewrite ^/feed-raindrop.xml$ https://bg.raindrop.io/rss/public/25041238 permanent; + rewrite ^/index.xml$ /rss.xml permanent; + rewrite ^/templates-for-ia-writer$ /template-ia-writer-nanzan permanent; + rewrite ^/notiz/das-koi-design-inspiration-und-idee$ /koi-design permanent; + rewrite ^/notiz/kostenlose-vektorkarten-mit-openstreetmap$ /openstreetmap permanent; + rewrite ^/notiz/kostenlose-vektorkarten-openstreetmap$ /openstreetmap permanent; + rewrite ^/notiz/domains-extern-hosten$ /domain-hosting permanent; + rewrite ^/notiz/versionskontrolle-mit-git$ /git permanent; + rewrite ^/versionskontrolle-mit-git$ /git permanent; + rewrite ^/notiz/eineinhalb-jahre-gtd-eine-billanz$ /gtd permanent; + rewrite ^/notiz/traditionelle-japanische-farben-photoshop-illustrator$ /japanese-colors permanent; + rewrite ^/notiz/gtd-mit-omnifocus-oder-things$ /gtd permanent; + rewrite ^/notiz/einstieg-in-git-als-versionskontrollsystem$ /git permanent; + rewrite ^/notiz/gitweb-theme-github-stil$ /gitweb-theme permanent; + rewrite ^/notiz/home-atemberaubende-erde-dokumentation-yann-arthus-bertrand$ /home-documentary permanent; + rewrite ^/notiz/git-praesentation$ /git permanent; + rewrite ^/notiz/buchtipp-rework-37signals$ /rework permanent; + rewrite ^/notiz/webstandards-magazin-django$ /webstandards-magazin-django permanent; + rewrite ^/notiz/vim$ /vim permanent; + rewrite ^/notiz/buchtipp-decodeunicode$ /decodeunicode permanent; + rewrite ^/2007/domains-extern-hosten/$ /domain-hosting permanent; + rewrite ^/2007/koi-design/$ /koi-design/ permanent; + rewrite ^/2007/eineinhalb-jahre-gtd-eine-billanz/$ /gtd/ permanent; + rewrite ^/2007/traditionelle-japanische-farben-photoshop-illustrator/$ /japanese-colors/ permanent; + rewrite ^/2008/kostenlose-vektorkarten-openstreetmap/$ /openstreetmap/ permanent; + rewrite ^/2009/einstieg-in-git-als-versionskontrollsystem/$ /git/ permanent; + rewrite ^/2009/gitweb-theme-github-stil/$ /gitweb-theme/ permanent; + rewrite ^/2009/home-atemberaubende-erde-dokumentation-yann-arthus-bertrand/$ /home-documentary/ permanent; + rewrite ^/2010/buchtipp-rework-37signals/$ /rework/ permanent; + rewrite ^/2010/webstandards-magazin-django/$ /webstandards-magazine-django/ permanent; + rewrite ^/2010/vim/$ /vim/ permanent; + rewrite ^/2011/buchtipp-decodeunicode/$ /decodeunicode/ permanent; + rewrite ^/2014/gestaltung-neues-logo/$ /logo-design/ permanent; + rewrite ^/2014/die-typographie-meiner-website/$ /website-typography/ permanent; + rewrite ^/2014/john-seymour-buecher-selbstversorgung/$ /john-seymour-books/ permanent; + rewrite ^/2014/gulp-tutorial-1-intro-setup/$ /gulp-tutorial-1-intro-setup/ permanent; + rewrite ^/2014/gulp-tutorial-2-development-server-browsersync-configuration/$ /gulp-tutorial-2-development-server-browsersync-configuration/ permanent; + rewrite ^/2014/gulp-tutorial-3-build-clean-jekyll/$ /gulp-tutorial-3-build-clean-jekyll/ permanent; + rewrite ^/2014/gulp-tutorial-4-css-generation-sass/$ /gulp-tutorial-4-css-generation-sass/ permanent; + rewrite ^/2014/gulp-tutorial-5-javascripts-browserify/$ /gulp-tutorial-5-javascripts-browserify/ permanent; + rewrite ^/2014/gulp-tutorial-6-images-vector-fonts/$ /gulp-tutorial-6-images-vector-fonts/ permanent; + rewrite ^/2014/gulp-tutorial-7-base64/$ /gulp-tutorial-7-base64/ permanent; + rewrite ^/2014/gulp-tutorial-8-watch/$ /gulp-tutorial-8-watch/ permanent; + rewrite ^/2014/gulp-tutorial-9-linting-scss-and-javascript/$ /gulp-tutorial-9-linting-scss-and-javascript/ permanent; + rewrite ^/2014/gulp-tutorial-10-generating-sprites/$ /gulp-tutorial-10-generating-sprites/ permanent; + rewrite ^/2014/gulp-tutorial-11-production-build-server-and-jekyll/$ /gulp-tutorial-11-production-build-server-and-jekyll/ permanent; + rewrite ^/2014/gulp-tutorial-12-optimize-css-javascript-images-and-html/$ /gulp-tutorial-12-optimize-css-javascript-images-and-html/ permanent; + rewrite ^/2014/gulp-tutorial-13-revisioning/$ /gulp-tutorial-13-revisioning/ permanent; + rewrite ^/2014/gulp-tutorial-14-deploying-the-website/$ /gulp-tutorial-14-deploying-the-website/ permanent; + rewrite ^/2014/gulp-tutorial-15-performance-improvements-webp-gzip/$ /gulp-tutorial-15-performance-improvements-webp-gzip/ permanent; + rewrite ^/2015/responsive-relaunch-of-my-martial-arts-website/$ /responsive-relaunch-martial-arts-website/ permanent; + rewrite ^/2015/getting-started-with-body-weight-training/$ /calisthenics/ permanent; + rewrite ^/2015/motivational-video/$ /motivational-video/ permanent; + rewrite ^/2015/human-film-yann-arthus-bertrand/$ /human-documentary/ permanent; + rewrite ^/2015/gulp-tutorial-16-postcss/$ /gulp-tutorial-16-postcss/ permanent; + rewrite ^/2016/japanese-netflix-tv-show-atelier-underwear/$ /japanese-netflix-tv-show-underwear/ permanent; + rewrite ^/2016/hugo-jekyll-migration/$ /jekyll-hugo-migration/ permanent; + rewrite ^/2016/speed-up-videos/$ /speed-up-videos/ permanent; + rewrite ^/2017/pursuit-of-minimalism/$ /minimalism/ permanent; + rewrite ^/2017/minimalism/$ /minimalism/ permanent; + rewrite ^/2017/i-wrote-a-book-in-gitbook/$ /gitbook/ permanent; + rewrite ^/2017/migration-hugo-css-grids-service-worker/$ /website-relaunch-css-grid-layout/ permanent; + rewrite ^/2017/self-defence-age-of-attention/$ /attention/ permanent; + rewrite ^/information/impressum$ /imprint permanent; + rewrite ^/notizbuch$ /journal permanent; + rewrite ^/archiv$ /journal permanent; + rewrite ^/on-learning-poems$ /learning-poems permanent; + + # Handling missing pages + try_files $uri $uri/ /index.html; +} diff --git a/package.json b/package.json index 48c6eb6..c005f4f 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,7 @@ "icons:generate": "node icons-generate.cjs", "plop": "plop", "astro": "astro", - "cspell": "cspell --words-only --unique 'src' | sort --ignore-case >> .cspell/dictionary.txt", - "prepare": "husky install" + "cspell": "cspell --words-only --unique 'src' | sort --ignore-case >> .cspell/dictionary.txt" }, "dependencies": { "@astro-community/astro-embed-youtube": "^0.4.4", @@ -34,7 +33,7 @@ "@swup/scripts-plugin": "^2.1.0", "@swup/scroll-plugin": "^3.3.2", "astro": "^4.5.4", - "astro-pagefind": "^1.4.0", + "astro-pagefind": "^1.5.0", "astro-seo": "^0.8.3", "astro-webmanifest": "^1.0.0", "astrojs-service-worker": "^2.0.0", @@ -82,8 +81,9 @@ "lodash": "^4.17.21", "netlify-cli": "^17.19.3", "npm-run-all": "^4.1.5", - "pagefind": "^1.0.4", + "pagefind": "^1.1.0", "plop": "^4.0.1", + "postcss-import": "^16.1.0", "postcss-nesting": "^12.1.0", "prettier": "^3.2.5", "prettier-plugin-astro": "^0.13.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 793cca3..7af87ae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,8 +58,8 @@ dependencies: specifier: ^4.5.4 version: 4.5.4(@types/node@20.11.27)(typescript@5.4.2) astro-pagefind: - specifier: ^1.4.0 - version: 1.4.0(astro@4.5.4) + specifier: ^1.5.0 + version: 1.5.0(astro@4.5.4) astro-seo: specifier: ^0.8.3 version: 0.8.3(prettier-plugin-astro@0.13.0)(prettier@3.2.5)(typescript@5.4.2) @@ -198,11 +198,14 @@ devDependencies: specifier: ^4.1.5 version: 4.1.5 pagefind: - specifier: ^1.0.4 - version: 1.0.4 + specifier: ^1.1.0 + version: 1.1.0 plop: specifier: ^4.0.1 version: 4.0.1 + postcss-import: + specifier: ^16.1.0 + version: 16.1.0(postcss@8.4.35) postcss-nesting: specifier: ^12.1.0 version: 12.1.0(postcss@8.4.35) @@ -4629,15 +4632,15 @@ packages: engines: {node: '>=8.0.0'} dev: true - /@pagefind/darwin-arm64@1.0.4: - resolution: {integrity: sha512-2OcthvceX2xhm5XbgOmW+lT45oLuHqCmvFeFtxh1gsuP5cO8vcD8ZH8Laj4pXQFCcK6eAdSShx+Ztx/LsQWZFQ==} + /@pagefind/darwin-arm64@1.1.0: + resolution: {integrity: sha512-SLsXNLtSilGZjvqis8sX42fBWsWAVkcDh1oerxwqbac84HbiwxpxOC2jm8hRwcR0Z55HPZPWO77XeRix/8GwTg==} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@pagefind/darwin-x64@1.0.4: - resolution: {integrity: sha512-xkdvp0D9Ld/ZKsjo/y1bgfhTEU72ITimd2PMMQtts7jf6JPIOJbsiErCvm37m/qMFuPGEq/8d+fZ4pydOj08HQ==} + /@pagefind/darwin-x64@1.1.0: + resolution: {integrity: sha512-QjQSE/L5oS1C8N8GdljGaWtjCBMgMtfrPAoiCmINTu9Y9dp0ggAyXvF8K7Qg3VyIMYJ6v8vg2PN7Z3b+AaAqUA==} cpu: [x64] os: [darwin] requiresBuild: true @@ -4647,22 +4650,22 @@ packages: resolution: {integrity: sha512-edkcaPSKq67C49Vehjo+LQCpT615v4d7JRhfGzFPccePvdklaL+VXrfghN/uIfsdoG+HoLI1PcYy2iFcB9CTkw==} dev: false - /@pagefind/linux-arm64@1.0.4: - resolution: {integrity: sha512-jGBrcCzIrMnNxLKVtogaQyajVfTAXM59KlBEwg6vTn8NW4fQ6nuFbbhlG4dTIsaamjEM5e8ZBEAKZfTB/qd9xw==} + /@pagefind/linux-arm64@1.1.0: + resolution: {integrity: sha512-8zjYCa2BtNEL7KnXtysPtBELCyv5DSQ4yHeK/nsEq6w4ToAMTBl0K06khqxdSGgjMSwwrxvLzq3so0LC5Q14dA==} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@pagefind/linux-x64@1.0.4: - resolution: {integrity: sha512-LIn/QcvcEtLEBqKe5vpSbSC2O3fvqbRCWOTIklslqSORisCsvzsWbP6j+LYxE9q0oWIfkdMoWV1vrE/oCKRxHg==} + /@pagefind/linux-x64@1.1.0: + resolution: {integrity: sha512-4lsg6VB7A6PWTwaP8oSmXV4O9H0IHX7AlwTDcfyT+YJo/sPXOVjqycD5cdBgqNLfUk8B9bkWcTDCRmJbHrKeCw==} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@pagefind/windows-x64@1.0.4: - resolution: {integrity: sha512-QlBCVeZfj9fc9sbUgdOz76ZDbeK4xZihOBAFqGuRJeChfM8pnVeH9iqSnXgO3+m9oITugTf7PicyRUFAG76xeQ==} + /@pagefind/windows-x64@1.1.0: + resolution: {integrity: sha512-OboCM76BcMKT9IoSfZuFhiqMRgTde8x4qDDvKulFmycgiJrlL5WnIqBHJLQxZq+o2KyZpoHF97iwsGAm8c32sQ==} cpu: [x64] os: [win32] requiresBuild: true @@ -6537,14 +6540,14 @@ packages: - supports-color dev: true - /astro-pagefind@1.4.0(astro@4.5.4): - resolution: {integrity: sha512-WMUlS0TTqIDqygplj/cxKU+l3oI+zB2qgYNMZed5R5nXuw8HhAKATog9zazuN05TOSWxI2Ap9+9WAYnnJ+4C7A==} + /astro-pagefind@1.5.0(astro@4.5.4): + resolution: {integrity: sha512-CN7Afe9qW640U1qliCQMXN259Dl6VPUnl8FneLfKE7STV4HLiif4PbNZejylC6yXYyP6uyNVDHNOfJfBBW5h6A==} peerDependencies: astro: ^2.0.4 || ^3.0.0 || ^4.0.0 dependencies: '@pagefind/default-ui': 1.0.4 astro: 4.5.4(@types/node@20.11.27)(typescript@5.4.2) - pagefind: 1.0.4 + pagefind: 1.1.0 sirv: 2.0.4 dev: false @@ -13751,7 +13754,7 @@ packages: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.2 + resolve: 1.22.8 semver: 5.7.2 validate-npm-package-license: 3.0.4 dev: true @@ -14296,16 +14299,15 @@ packages: semver: 7.6.0 dev: true - /pagefind@1.0.4: - resolution: {integrity: sha512-oRIizYe+zSI2Jw4zcMU0ebDZm27751hRFiSOBLwc1OIYMrsZKk+3m8p9EVaOmc6zZdtqwwdilNUNxXvBeHcP9w==} + /pagefind@1.1.0: + resolution: {integrity: sha512-1nmj0/vfYcMxNEQj0YDRp6bTVv9hI7HLdPhK/vBBYlrnwjATndQvHyicj5Y7pUHrpCFZpFnLVQXIF829tpFmaw==} hasBin: true - requiresBuild: true optionalDependencies: - '@pagefind/darwin-arm64': 1.0.4 - '@pagefind/darwin-x64': 1.0.4 - '@pagefind/linux-arm64': 1.0.4 - '@pagefind/linux-x64': 1.0.4 - '@pagefind/windows-x64': 1.0.4 + '@pagefind/darwin-arm64': 1.1.0 + '@pagefind/darwin-x64': 1.1.0 + '@pagefind/linux-arm64': 1.1.0 + '@pagefind/linux-x64': 1.1.0 + '@pagefind/windows-x64': 1.1.0 /pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -14849,7 +14851,7 @@ packages: postcss: 8.4.35 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.2 + resolve: 1.22.8 dev: true /postcss-import@15.1.0(postcss@8.4.35): @@ -14863,6 +14865,18 @@ packages: read-cache: 1.0.0 resolve: 1.22.8 + /postcss-import@16.1.0(postcss@8.4.35): + resolution: {integrity: sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==} + engines: {node: '>=18.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.35 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + dev: true + /postcss-js@4.0.1(postcss@8.4.35): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16}