chore(hugo): cleanup README and makefile

This commit is contained in:
Julien Dessaux 2025-03-09 20:31:45 +01:00
parent 6314ca3119
commit ab877f967d
Signed by: adyxax
GPG key ID: F92E51B86E07177E
7 changed files with 87 additions and 332 deletions

View file

@ -1,55 +1,66 @@
.DEFAULT_GOAL := help
.DELETE_ON_ERROR:
MAKEFLAGS += --no-builtin-rules
MAKEFLAGS += --warn-undefined-variables
.ONESHELL:
SHELL := bash SHELL := bash
.SHELLFLAGS := -eu -o pipefail -c .SHELLFLAGS := -eu -o pipefail -c
.ONESHELL:
.DELETE_ON_ERROR:
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
CACHEDIR=/tmp/hugo-cache-$(USER) ##### Variables ################################################################
DESTDIR=public/ CACHEDIR := /tmp/hugo-cache-$(USER)
HOSTNAME=$(shell hostname -f) DESTDIR := public/
REVISION=$(shell git rev-parse HEAD) HOSTNAME := $(shell hostname -f)
REVISION := $(shell git rev-parse HEAD)
##### Development ##############################################################
.PHONY: build .PHONY: build
build: ## make build # builds an optimized version of the website in $(DESTDIR) build: ## make build
# TODO make sure to stash everything in content/ ?
@echo "----- Generating site -----" @echo "----- Generating site -----"
hugo --gc --minify --cleanDestinationDir -d $(DESTDIR) --cacheDir $(CACHEDIR) --buildFuture hugo --gc --minify --cleanDestinationDir -d $(DESTDIR) \
--cacheDir $(CACHEDIR) --buildFuture
cp public/index.json search/ cp public/index.json search/
cp public/search/index.html search/ cp public/search/index.html search/
(cd search && CGO_ENABLED=0 go build -ldflags '-s -w -extldflags "-static"' ./search.go) cd search
CGO_ENABLED=0 go build -ldflags '-s -w -extldflags "-static"' ./search.go
.PHONY: buildah
buildah: ## make buildah # builds the container images
deploy/build-image.sh
.PHONY: clean .PHONY: clean
clean: ## make clean # removed all $(DESTDIR) contents clean: ## make clean
@echo "----- Cleaning old build -----" @echo "----- Cleaning old build -----"
rm -f search/index.html search/index.json search/search rm -f search/index.html search/index.json search/search
rm -rf $(DESTDIR) rm -rf $(DESTDIR)
.PHONY: deploy .PHONY: serve
deploy: ## make deploy # deploy the website to myth.adyxax.org serve: ## make serve # hugo web server development mode
rsync -a $(DESTDIR) root@myth.adyxax.org:/srv/www/ hugo serve --disableFastRender --noHTTPCache \
rsync search/search root@myth.adyxax.org:/srv/www/search/search --cacheDir $(CACHEDIR) --bind 0.0.0.0 --port 1313 \
ssh root@myth.adyxax.org "systemctl restart www-search" -b http://$(HOSTNAME):1313/ --buildFuture --navigateToChanged
.PHONY: deploy-kube ##### Operations ###############################################################
deploy-kube: ## make deploy-kube # deploy the website to the active kubernetes context .PHONY: deploy
sed -i deploy/www.yaml -e 's/^\(\s*image:[^:]*:\).*$$/\1$(REVISION)/' deploy: ## make deploy
kubectl apply -f deploy/www.yaml rsync -a $(DESTDIR) root@www.adyxax.org:/srv/www/
rsync search/search root@www.adyxax.org:/usr/local/bin/www-search
ssh root@www.adyxax.org "systemctl restart www-search"
##### Quality ##################################################################
.PHONY: check
check: ## run all code checks
(cd search && go mod verify && go vet ./...)
.PHONY: tidy
tidy: ## tidy up the code
(cd search && go fmt ./... && go mod tidy -v)
##### Utils ####################################################################
.PHONY: confirm
confirm:
@echo -n 'Are you sure? [y/N] ' && read ans && [ $${ans:-N} = y ]
.PHONY: help .PHONY: help
help: help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' @grep -E '^[a-zA-Z\/_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' | sort
.PHONY: push .PHONY: no-dirty
push: ## make push # push the built images to quay.io no-dirty:
buildah push adyxax/www quay.io/adyxax/www:$(REVISION) git diff --exit-code
buildah push adyxax/www-search quay.io/adyxax/www-search:$(REVISION)
.PHONY: serve
serve: ## make serve # hugo web server development mode
hugo serve --disableFastRender --noHTTPCache --cacheDir $(CACHEDIR) --bind 0.0.0.0 --port 1313 -b http://$(HOSTNAME):1313/ --buildFuture --navigateToChanged
.DEFAULT_GOAL := help

View file

@ -1,10 +1,18 @@
# www : My personal website # www : My personal website
My name is Julien Dessaux, also known by my pseudonym Adyxax : welcome to my personal website! My name is Julien Dessaux, also known by my pseudonym Adyxax: welcome to my
personal website!
These pages are an aggregation of various thoughts and tutorials I accumulated over my years of service as a system and network administrator and architect. Topics covered are open source, BSD and GNU/Linux system administration, and networking. It is a personal space that I try to fill up with my experience and knowledge of computer systems and network administration in the hope it serves others. You can learn more about me on this page. These pages are an aggregation of various thoughts and tutorials I accumulated
over my years of service as a system and network administrator and architect.
Topics covered are open source, BSD and GNU/Linux system administration, and
networking. It is a personal space that I try to fill up with my experience and
knowledge of computer systems and network administration in the hope it serves
others. You can learn more about me on this page.
I hope you feel welcome here, do not hesitate to leave a message at julien -DOT- dessaux -AT- adyxax -DOT- org. You can ask for a translation, some more details on a topic covered here, or just say hi or whatever ;-) I hope you feel welcome here, do not hesitate to leave a message at julien -DOT-
dessaux -AT- adyxax -DOT- org. You can ask for a translation, some more details
on a topic covered here, or just say hi or whatever ;-)
Have a good time! Have a good time!
@ -18,37 +26,44 @@ Have a good time!
## Dependencies ## Dependencies
go is required for the search feature. Only go version >= 1.22 on linux amd64 (Gentoo) is being regularly tested. go is required for the search feature. Only go version >= 1.22 on linux amd64
(Gentoo) is being regularly tested.
hugo is required in order to build the website html pages. Only hugo >= 0.111.3 is being regularly tested. hugo is required in order to build the website html pages. Only hugo >= 0.111.3
is being regularly tested.
buildah is optionally required in order to build the container images with my deploy script.
## Quick Start ## Quick Start
There is a makefile with everything you need, just type `make help` (or `gmake help` if running BSD). There is a makefile with everything you need, just type `make help` (or `gmake
help` if running BSD).
## Hugo ## Hugo
Contrary to popular usage, I do not use a theme with hugo. I decided to simplify write my own in order to keep it light and simple. Here is a breakdown of each folder's contents: Contrary to popular usage, I do not use a theme with hugo. I decided to write my
own in order to keep it light and simple. Here is a breakdown of each folder's
contents:
- assets/: css files, which will be compiled into a single minified file. - `assets/`: css files, which will be compiled into a single minified file.
- content/: markdown files - `content/`: markdown files
- blog/: blog section of this website. - `blog/`: blog section of this website.
- books/: a log of simple reviews of books I read. - `books/`: a log of simple reviews of books I read.
- docs/: wiki like section, where information is not sorted just chronologically like in the blog section. - `docs/`: wiki like section, where information is not sorted just
- search/: dummy section I need for the search feature. chronologically like in the blog section.
- deploy/: container images building script. - `search/`: dummy section I need for the search feature.
- layouts/: html, json and rss templates. Also some useful hugo shortcodes. - `deploy/`: container images building script.
- search: the go program that powers the search feature. - `layouts/`: html, json and rss templates. Also some useful hugo shortcodes.
- static: favicon, blog images and schematics. - `search/`: the go program that powers the search feature.
- `static/`: favicon, blog images and schematics.
## Search ## Search
Hugo can easily generate a json index of the website, and according to my google-fu hugo users use javascript solutions to implement search on top of this. I was not satisfied by the idea of having javascript download the whole website index and running searches locally, but I found no alternative. Since I love having a javascript free website I wanted to keep it that way if possible, so I designed an alternative. Hugo can easily generate a json index of the website, and according to my
google-fu hugo users use javascript solutions to implement search on top of
this. I was not satisfied by the idea of having javascript download the whole
website index and running searches locally, but I found no alternative. I
therefore designed an alternative.
The search folders contains code for a go webservice that can handle search queries and serve results. It is fully integrated in the container images build process to maintain a coherent look with the website. For more details, see the related [blog article](https://www.adyxax.org/blog/2021/09/19/implementing-a-search-feature-for-my-hugo-static-website/). The search folder contains code for a go webservice that can handle search
queries and serve results. It is fully integrated to maintain a coherent look
## Kubernetes with the website. For more details, see the related [blog
article](https://www.adyxax.org/blog/2021/09/19/implementing-a-search-feature-for-my-hugo-static-website/).
I host this website on a k3s cluster. An example manifest can be found in the deploy folder.

View file

@ -1,64 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
ret=0; buildah images adyxax/alpine &>/dev/null || ret=$?
if [[ "${ret}" != 0 ]]; then
buildah rmi --all
ALPINE_LATEST=$(curl --silent https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/x86_64/ |
perl -lane '$latest = $1 if $_ =~ /^<a href="(alpine-minirootfs-\d+\.\d+\.\d+-x86_64\.tar\.gz)">/; END {print $latest}'
)
if [ ! -e "./${ALPINE_LATEST}" ]; then
echo "Fetching ${ALPINE_LATEST}..."
curl --silent "https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/x86_64/${ALPINE_LATEST}" \
--output "./${ALPINE_LATEST}"
fi
ctr=$(buildah from scratch)
buildah add "${ctr}" "${ALPINE_LATEST}" /
buildah run "${ctr}" /bin/sh -c 'apk upgrade --no-cache'
buildah run "${ctr}" /bin/sh -c 'apk add --no-cache pcre sqlite-libs'
buildah commit "${ctr}" adyxax/alpine
buildah rm "${ctr}"
fi
ret=0; buildah images adyxax/hugo &>/dev/null || ret=$?
if [[ "${ret}" != 0 ]]; then
hugo=$(buildah from adyxax/alpine)
buildah run "${hugo}" /bin/sh -c 'apk add --no-cache go git hugo make'
buildah commit "${hugo}" adyxax/hugo
else
hugo=$(buildah from adyxax/hugo)
fi
buildah run -v "${PWD}":/www "${hugo}" -- sh -c 'cd /www; make build'
buildah rm "${hugo}"
ret=0; buildah images adyxax/nginx &>/dev/null || ret=$?
if [[ "${ret}" != 0 ]]; then
nginx=$(buildah from adyxax/alpine)
buildah run "${nginx}" /bin/sh -c 'apk add --no-cache nginx'
buildah commit "${nginx}" adyxax/nginx
else
nginx=$(buildah from adyxax/nginx)
fi
(cd deploy && buildah copy "${nginx}" nginx.conf headers_secure.conf headers_static.conf /etc/nginx/)
buildah config \
--author 'Julien Dessaux' \
--cmd nginx \
--port 80 \
"${nginx}"
buildah copy "${nginx}" public /var/www/www.adyxax.org
buildah commit "${nginx}" adyxax/www
buildah rm "${nginx}"
ctr=$(buildah from scratch)
buildah copy "${ctr}" search/search /
buildah config \
--author 'Julien Dessaux' \
--cmd /search \
--port 8080 \
"${ctr}"
buildah commit "${ctr}" adyxax/www-search
buildah rm "${ctr}"

View file

@ -1,10 +0,0 @@
# A+ on https://securityheaders.io/
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 strict-origin;
add_header Cache-Control no-transform;
add_header Content-Security-Policy "script-src 'unsafe-inline'";
add_header Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()";
# 6 months HSTS pinning
add_header Strict-Transport-Security max-age=16000000;

View file

@ -1,3 +0,0 @@
include headers_secure.conf;
# Infinite caching
add_header Cache-Control "public, max-age=31536000, immutable";

View file

@ -1,60 +0,0 @@
user nginx;
worker_processes 1;
daemon off;
events {
# The maximum number of simultaneous connections that can be opened by
# a worker process
worker_connections 1024;
}
http {
# Includes mapping of file name extensions to MIME types of responses
# and defines the default type.
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Don't tell nginx version to the clients. Default is 'on'.
server_tokens off;
# Specifies the maximum accepted body size of a client request, as
# indicated by the request header Content-Length. If the stated content
# length is greater than this size, then the client receives the HTTP
# error code 413. Set to 0 to disable. Default is '1m'.
client_max_body_size 1m;
# Sendfile copies data between one FD and other from within the kernel,
# which is more efficient than read() + write(). Default is off.
sendfile on;
# Causes nginx to attempt to send its HTTP response head in one packet,
# instead of using partial frames. Default is 'off'.
tcp_nopush on;
# Enables or disables the use of the TCP_NODELAY option. The option is
# enabled when a connection is transitioned into the keep-alive state.
# Additionally, it is enabled on SSL connections, for unbuffered
# proxying, and for WebSocket proxying.
tcp_nodelay on;
# Specifies the main log format.
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
server {
listen 80;
listen [::]:80;
server_name _;
root /var/www/www.adyxax.org/;
index index.html;
error_page 404 /404.html;
location /static {
include /etc/nginx/headers_static.conf;
}
location / {
include headers_secure.conf;
add_header Cache-Control "private, max-age=0, must-revalidate, no-transform";
}
}
}

View file

@ -1,134 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: www
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: www
name: www
labels:
app: www
spec:
replicas: 1
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: www
template:
metadata:
labels:
app: www
spec:
containers:
- name: www
image: quay.io/adyxax/www:2021111202
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: '/'
port: 80
initialDelaySeconds: 1
timeoutSeconds: 1
livenessProbe:
httpGet:
path: '/'
port: 80
initialDelaySeconds: 1
timeoutSeconds: 1
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10"]
- name: search
image: quay.io/adyxax/www-search:2021111202
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: '/search/'
port: 8080
initialDelaySeconds: 1
timeoutSeconds: 1
livenessProbe:
httpGet:
path: '/search/'
port: 8080
initialDelaySeconds: 1
timeoutSeconds: 1
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10"]
---
apiVersion: v1
kind: Service
metadata:
namespace: www
name: www
spec:
type: ClusterIP
selector:
app: www
ports:
- protocol: TCP
port: 80
targetPort: 80
name: www
- protocol: TCP
port: 8080
targetPort: 8080
name: search
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Content-Security-Policy: script-src 'unsafe-inline'";
namespace: www
name: www
spec:
ingressClassName: nginx
tls:
- secretName: wildcard-adyxax-org
rules:
- host: www.adyxax.org
http:
paths:
- path: '/'
pathType: Prefix
backend:
service:
name: www
port:
number: 80
- path: '/search'
pathType: Prefix
backend:
service:
name: www
port:
number: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: www
name: redirects
annotations:
nginx.ingress.kubernetes.io/permanent-redirect: https://www.adyxax.org/
nginx.ingress.kubernetes.io/permanent-redirect-code: "308"
spec:
ingressClassName: nginx
tls:
- secretName: wildcard-adyxax-org
rules:
- host: adyxax.org
- host: wiki.adyxax.org