diff options
Diffstat (limited to 'content/articles')
-rw-r--r-- | content/articles/site-backend.md | 278 |
1 files changed, 200 insertions, 78 deletions
diff --git a/content/articles/site-backend.md b/content/articles/site-backend.md index 5fb750b..ca36b2d 100644 --- a/content/articles/site-backend.md +++ b/content/articles/site-backend.md @@ -5,9 +5,6 @@ title: "Site Backend" # date (optional for articles) date: "2024-05-31T03:57:18-04:00" -# draft articles are not visible on live site -draft: true - # show on articles page show: true @@ -46,6 +43,11 @@ Site content is managed as [Markdown][] files stored in a [Git][] repository. The theme is a modified version of [Bulma][]. The site is statically generated by [Hugo][]. +I create and edit site content with [Vim][] and preview the results +locally with `hugo serve -D ...`. Articles and blog posts are saved as +drafts and committed to the [Git][] repository so I can work on them as +time permits. + [{{< pe-figure "editing" >}}][editing-this-article] ## History @@ -57,47 +59,44 @@ hiatus and migrated the site from the custom [PHP][] backend to ## Goals -The goals of this site backend are: +The content and layout of this site should be: - Small - Fast - Secure -- Mobile-friendly - Accessible -- Simple (for me) - -Static generation neatly addresses the first three goals: - -- The site is small because the [Hugo][] can be configured to - aggressively pack and minify content and assets. Images are - also compressed and served in multiple formats (see [Hugo - Configuration](#hugo-configurationi "Hugo Configuration") and [Images](#images - "Images")). -- The site is fast because web servers can serve static content - extremely quickly, and because static content can be cached. Caching - and compression are enabled in [Apache][] (see [Apache - Configuration](#apache-configuration "Apache Configuration")). -- The site is secure because the content is static; there is no - web-accessible endpoint which can upload files or modify content. - Additional security measures are discussed in several of the following - sections. - -Explanations of how I keep the site mobile-friendly and accessible are -available in the [HTML](#html "HTML") and [Hugo -Configuration](#hugo-configuration "Hugo Configuration") sections below. - -**TODO:** discuss simplicity +- Mobile-friendly + +These goals are addressed as follows: + +- Small: [Hugo][] is configured to aggressively pack content and minify + assets. Images are compressed and served in multiple formats. [HTTP + compression][http compression] is enabled (with caution). See + [Hugo Configuration][s-hugo-configuration], [Images][s-images] and + [Apache Configuration][s-apache-configuration]. +- Fast: Static content can be served quickly. Assets are fingerprinted + and browser caching is enabled. See [Hugo + Configuration][s-hugo-configuration] and [Apache + Configuration][s-apache-configuration]. +- Secure: Static content; no web-accessible endpoint which can make + changes. Additional security measures are discussed in + [Deployment][s-deployment], [Apache + Configuration][s-apache-configuration], and [Other][s-other]. +- Accessible: Addressed when creating content and with custom + [shortcodes][shortcode]. See [HTML][s-html] and [Hugo + Configuration][s-hugo-configuration]. +- Mobile-friendly: Addressed when creating content and with the site + theme. See [HTML][s-html] and [Bulma + Configuration][s-bulma-configuration]. ## Content -### HTML +This section describes how content is created for this site. -I create and edit site content with [Vim][] in [Markdown][] format and -preview the results locally with `hugo serve -D ...`. Articles and blog -posts are saved as drafts and committed to the [Git][] repository so I -can work on them as time permits. +### HTML -The content and layout is designed to be accessible and mobile-friendly: +The site content and layout is designed to be accessible and +mobile-friendly: - links and table components have `title` and `aria-label` attributes - images have captions, fallback formats, and `title` and `alt` attributes @@ -107,6 +106,12 @@ The content and layout is designed to be accessible and mobile-friendly: and has a [manual theme switcher][post-theme-switcher] - The menu bar collapes to a hamburger menu on mobile. +Here are a few articles which cover guidelines that I follow: + +- [Progressive Enhancement][] +- [Why your website should be under 14kB in size][14kb] +- [5 things you don't need JavaScript for][you-dont-need-js] + ### Images Images are created as follows: @@ -130,6 +135,23 @@ Other notes: - Menubar icons are borrowed from [Bootstrap Icons][]. - I reviewed several [PNG][] compressors in [this post][post-png-compressors]. +Managing images manually helps to keep the site small and fast. Here +are a couple common [GraphicsMagick][] commands: + +```sh +# scale with antialiasing and convert from png to webp +gm convert -antialias -scale 1024x1024 some-image.{png,webp} + +# get image dimensions +gm identify some-image.png + +# convert from png to webp (lossless) +gm convert -quality 100 -define webp:lossless=true some-image.{png,webp} + +# crop image to 256x256 +gm convert -crop 256x256 some-image{,-cropped}.png +``` + ### JavaScript This site has almost no [JavaScript][], by design. The [JavaScript][] @@ -137,7 +159,7 @@ that is used is minimal, [modern][es2015], [deferred][], and only used for the [theme switcher][post-theme-switcher] and burger menu. Below is the unminified `script.js` for this site with some notes -removed. It is 777 bytes minified and 586 bytes minified and +removed. It is served as 777 bytes minified and 586 bytes minified and compressed: ```js @@ -207,21 +229,20 @@ This section discusses the configuration for [Apache][], [Bulma][], ### Apache Configuration -This section disusses the [Apache][] configuration for this site. I -have broken this section into three sub-sections to make them easier to -digest. +This section disusses the [Apache][] configuration for this site. The +information is divided into several sub-sections in order to make it +easier to digest. -The [Apache][] configuration relies on the following modules: +This site relies on the following [Apache][] modules: -- [mod\_deflate][mod-deflate] (see note below) -- [mod\_http2][mod-http2] -- [mod\_macro][mod-macro] -- [mod\_proxy][mod-proxy] -- [mod\_rewrite][mod-rewrite] - -Note: It is safe for this site to enable [mod\_deflate][mod-deflate] -because it does not use [cookies][] and is not vulnerable to [BREACH][]. -and does not use [cookies][]. +- [mod\_deflate][mod-deflate]: Enable [HTTP compression][]. +- [mod\_http2][mod-http2]: Enable [HTTP/2][]. +- [mod\_macro][mod-macro]: Simplify common configuration. +- [mod\_proxy][mod-proxy]: Proxy [web hook][] requests to internal + [webhook][] daemon. +- [mod\_rewrite][mod-rewrite]: Unconditionally redirect from [HTTP][] to + [HTTPS][], strip `www.` from the path hostname, and redirect from legacy + [URLs][url]. #### Virtual Host Configuration @@ -230,7 +251,8 @@ The [Apache][] virtual host configuration is modified as follows: - Unconditionally redirect from [HTTP][] to [HTTPS][] - Unconditionally redirect to strip the `www.` hostname prefix - Enable [HTTP/2][] -- Set security headers (discussed in [Security Headers](#security-headers)) +- Set security headers (discussed in [Security + Headers][s-security-headers]) - Enable aggressive caching of image, script, and style assets Below is the [Apache][] virtual host configuration for this site with @@ -285,6 +307,17 @@ redirects removed: [Download][apache-vhost.conf] +#### HTTP Compression + +[HTTP compression][] is supported via [mod\_deflate][mod-deflate]. + +It is safe for this site to enable [mod\_deflate][mod-deflate] because +it does not use [cookies][] and is not vulnerable to [BREACH][]. + +In 2022 I tried [mod\_brotli][mod-brotli], but the improvement over +[mod\_deflate][mod-deflate] was minimal (deflate: 125k, brotli: 117k) so +I abandoned it. + #### Security Headers This site uses a strict [Content-Security-Policy][] header; it rejects @@ -427,28 +460,30 @@ minified and compressed. ### Hugo Configuration -[Hugo][] is configured to use [Chroma syntax higlighting][] with inline -styles disabled (e.g., `class` attributes only, no `style`) in order to -support the restrictive `Content-Security-Policy` header (see "HTTP -Headers"). +[Hugo][] is configured to use [Chroma syntax higlighting][chroma] with +inline styles disabled in order to support the strict +[Content-Security-Policy][]. See [Security Headers][s-security-headers] +for details. -The formatted tables in the pages site are generated via [my -`hugo-shortcode-table` shortcode][], because the native table generator -for [Hugo][] uses inline styles. +Tables are are generated by [a custom table +shortcode][hugo-shortcode-table], because the [Hugo's][hugo] native +[Markdown][] table generator in [Hugo][] uses inline styles. -I have also written a couple of custom [shortcodes][] to generate -`<picture>` and `<figure>` elements in order to support [progressive -enhancement][]. +I have also written a couple of custom [shortcodes][shortcode] to +generate `<picture>` and `<figure>` elements in order to support +[progressive enhancement][]. -The generated [HTML][] has been modified to: +Custom archetypes have been added for the [Archives][] section, blog +posts, articles, and projects. -**TODO:** +The generated [HTML][] has been modified to: -- add support `go-import` -- add a [Mastodon][] `<link rel='me' ...>` tag. -- remove all unnecessary tags -- to combine and [minify][] and [JavaScript][] and [CSS][] assets. -- to add `integrity` attributes to `<link>` and `<script>` tags. +- Use a custom theme. See [Bulma Configuration][s-bulma-configuration]. +- Add support for [`<meta name='go-import' ...>`][go-import]. +- Add a [Mastodon][] `<link rel='me' ...>` tag. +- Remove all unnecessary tags. +- Combine, [minify][], and enable caching of [JavaScript][] and [CSS][] assets. +- add `integrity` attributes to `<link>` and `<script>` tags. ### Webhook Configuration @@ -495,23 +530,62 @@ The generated [HTML][] has been modified to: ## Validation -I periodically verify the following manually: +I periodically use the following tools to verify this site: -- Developer console: Page load time, cached and uncached page size. -- [Lighthouse][]: Accessibility, desktop score, and mobile score. -- security headers -- tls configuration -- manual verification in the desktop and mobile versions of chrome and - firefox +- Developer Console: Check page load time, cached and uncached page size. +- [Lighthouse][]: Check accessibility, desktop score, and mobile score. +- [Security Headers][securityheaders.com]: Check [HTTP][] + security headers. +- [SSL Labs SSL Test][ssl-labs-ssl-test]: Check [TLS][] configuration. -## Other +I also manually check the site in the desktop and mobile versions of +[Chrome][] and [Firefox][]. -**TODO:** +I am investigated doing automated validation with [htmltest][], +[htmltidy][], and the [W3C validator][], but have not added them yet. -- wireguard -- private ssh, private git -- (more stuff from `TODO.md`) +## Other +I do not store credentials (e.g., the [HMAC][] key for the deployment +[web hook][]) in the [Git repository for this site][git-repo]. + +Write access to the [Git repository for this site][git-repo] is only +accessible via [SSH][]. + +[SSH][] access firewalled off and is only available via [Wireguard][]. + +Here are recommendations regarding [SSH][], in order of preference: + +1. Only allow [SSH][] access via a [VPN][] and do not expose it to the + public. +2. Only allow key-based authentication and disable password authentication. Use an [Ed25519][] key, if possible. +3. Limit the [IP addresses][ip] which can connect to [SSH][] at the firewall. +4. Always disable remote `root` logins. + +Note that these options are not mutually exclusive. + +I have written about firewall configuration and [Wireguard][] elsewhere +on this site: + +- [NFTables Examples][] +- [Wireguard is Awesome][] + +[s-hugo-configuration]: #hugo-configuration + "Hugo Configuration" +[s-security-headers]: #security-headers + "Security Headers" +[s-images]: #images + "Images" +[s-deployment]: #deployment + "Deployment" +[s-html]: #html + "HTML" +[s-bulma-configuration]: #bulma-configuration + "Bulma Configuration" +[s-apache-configuration]: #apache-configuration + "Apache Configuration" +[s-other]: #other + "Other" [hugo]: https://gohugo.io/ "Hugo static site generator." [bulma]: https://bulma.io/ @@ -584,6 +658,8 @@ I periodically verify the following manually: "Transport Layer Security" [post-receive]: https://git-scm.com/docs/githooks#post-receive "Git hook triggered on a remote repository after a push operation" +[git-repo]: https://git.pablotron.org/sites/pablotron.org/ + "Read-only web view of the Git repository for this site." [deploy.rb]: https://git.pablotron.org/sites/pablotron.org/plain/bin/hook/deploy.rb "Deployment script invoked as a web hook." [gen-logo.rb]: https://git.pablotron.org/sites/pablotron.org/plain/bin/logo-0/gen-logo.rb @@ -618,6 +694,8 @@ I periodically verify the following manually: "Apache module which provides macros within configuration files." [mod-deflate]: https://httpd.apache.org/docs/current/mod/mod_deflate.html "Apache module which provides DEFLATE output compression." +[mod-brotli]: https://httpd.apache.org/docs/current/mod/mod_brotli.html + "Apache module which provides brotli output compression." [ssl-config]: https://ssl-config.mozilla.org/ "Mozilla SSL Configuration Generator" [tls 1.2]: https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1.2 @@ -660,3 +738,47 @@ I periodically verify the following manually: "Download SASS configuration" [html]: https://en.wikipedia.org/wiki/HTML "HyperText Markup Language (HTML)" +[shortcode]: https://gohugo.io/content-management/shortcodes/ + "Snippets in content which call built-in or custom templates." +[chroma]: https://github.com/alecthomas/chroma + "Chrome syntax highlighter" +[archives]: {{< relref "archive.md" >}} + "Archived blog posts" +[go-import]: https://go.dev/ref/mod#vcs-find + "HTML tag which allows Go to map a module name to a version control system repository." +[htmltest]: https://github.com/wjdp/htmltest + "htmltest static HTML checker" +[w3c validator]: https://validator.w3.org/ + "W3C HTML validator" +[htmltidy]: https://www.html-tidy.org/ + "htmltidy" +[lighthouse]: https://developer.chrome.com/docs/lighthouse/overview/ + "Open source automated tool for improving the quality of web pages." +[chrome]: https://www.google.com/chrome/index.html + "Google Chrome web browser." +[firefox]: https://www.mozilla.org/en-US/firefox/new/ + "Mozilla Firefox web browser." +[ssh]: https://en.wikipedia.org/wiki/Secure_Shell + "Secure Shell" +[wireguard]: https://wireguard.com/ + "Fast and simple VPN which uses modern cryptography." +[vpn]: https://en.wikipedia.org/wiki/Virtual_private_network + "Virtual Private Network" +[ip]: https://en.wikipedia.org/wiki/IP_address + "Internet Protocol (IP) address" +[nftables examples]: {{< relref "articles/nftables-examples.md" >}} + "NFTables Examples" +[wireguard is awesome]: {{< relref "posts/2021-11-06-wireguard-is-awesome.md" >}} + "Wireguard is Awesome" +[ed25519]: https://en.wikipedia.org/wiki/EdDSA#Ed25519 + "Ed25519 digital signature algorithm." +[14kb]: https://endtimes.dev/why-your-website-should-be-under-14kb-in-size/ + "Why your website should be under 14kB in size" +[you-dont-need-js]: https://lexoral.com/blog/you-dont-need-js/ + "5 things you don't need JavaScript for" +[http compression]: https://en.wikipedia.org/wiki/HTTP_compression + "HTTP compression" +[url]: https://en.wikipedia.org/wiki/URL + "Uniform resource locator (URL)" +[progressive enhancement]: https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement + "Web design which puts an emphasis on content first." |