aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile81
-rw-r--r--README.md67
-rwxr-xr-xdeploy/build-image.sh64
-rw-r--r--deploy/headers_secure.conf10
-rw-r--r--deploy/headers_static.conf3
-rw-r--r--deploy/nginx.conf60
-rw-r--r--deploy/www.yaml134
7 files changed, 87 insertions, 332 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 28762ef..d2c51d9 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,55 +1,66 @@
-SHELL := bash
-.SHELLFLAGS := -eu -o pipefail -c
-.ONESHELL:
+.DEFAULT_GOAL := help
.DELETE_ON_ERROR:
-MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
+MAKEFLAGS += --warn-undefined-variables
+.ONESHELL:
+SHELL := bash
+.SHELLFLAGS := -eu -o pipefail -c
-CACHEDIR=/tmp/hugo-cache-$(USER)
-DESTDIR=public/
-HOSTNAME=$(shell hostname -f)
-REVISION=$(shell git rev-parse HEAD)
+##### Variables ################################################################
+CACHEDIR := /tmp/hugo-cache-$(USER)
+DESTDIR := public/
+HOSTNAME := $(shell hostname -f)
+REVISION := $(shell git rev-parse HEAD)
+##### Development ##############################################################
.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 -----"
- 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/search/index.html search/
- (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
+ cd search
+ CGO_ENABLED=0 go build -ldflags '-s -w -extldflags "-static"' ./search.go
.PHONY: clean
-clean: ## make clean # removed all $(DESTDIR) contents
+clean: ## make clean
@echo "----- Cleaning old build -----"
rm -f search/index.html search/index.json search/search
rm -rf $(DESTDIR)
+.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
+
+##### Operations ###############################################################
.PHONY: deploy
-deploy: ## make deploy # deploy the website to myth.adyxax.org
- rsync -a $(DESTDIR) root@myth.adyxax.org:/srv/www/
- rsync search/search root@myth.adyxax.org:/srv/www/search/search
- ssh root@myth.adyxax.org "systemctl restart www-search"
+deploy: ## make deploy
+ 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"
-.PHONY: deploy-kube
-deploy-kube: ## make deploy-kube # deploy the website to the active kubernetes context
- sed -i deploy/www.yaml -e 's/^\(\s*image:[^:]*:\).*$$/\1$(REVISION)/'
- kubectl apply -f deploy/www.yaml
+##### Quality ##################################################################
+.PHONY: check
+check: ## run all code checks
+ (cd search && go mod verify && go vet ./...)
-.PHONY: help
-help:
- @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
+.PHONY: tidy
+tidy: ## tidy up the code
+ (cd search && go fmt ./... && go mod tidy -v)
-.PHONY: push
-push: ## make push # push the built images to quay.io
- buildah push adyxax/www quay.io/adyxax/www:$(REVISION)
- buildah push adyxax/www-search quay.io/adyxax/www-search:$(REVISION)
+##### Utils ####################################################################
+.PHONY: confirm
+confirm:
+ @echo -n 'Are you sure? [y/N] ' && read ans && [ $${ans:-N} = y ]
-.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
+.PHONY: help
+help:
+ @grep -E '^[a-zA-Z\/_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' | sort
-.DEFAULT_GOAL := help
+.PHONY: no-dirty
+no-dirty:
+ git diff --exit-code
diff --git a/README.md b/README.md
index a9dc39f..e9530f6 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,18 @@
# 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!
@@ -18,37 +26,44 @@ Have a good time!
## 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.
-
-buildah is optionally required in order to build the container images with my deploy script.
+hugo is required in order to build the website html pages. Only hugo >= 0.111.3
+is being regularly tested.
## 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
-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:
-
-- assets/: css files, which will be compiled into a single minified file.
-- content/: markdown files
- - blog/: blog section of this website.
- - 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.
- - search/: dummy section I need for the search feature.
-- deploy/: container images building script.
-- layouts/: html, json and rss templates. Also some useful hugo shortcodes.
-- search: the go program that powers the search feature.
-- static: favicon, blog images and schematics.
+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.
+- `content/`: markdown files
+ - `blog/`: blog section of this website.
+ - `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.
+ - `search/`: dummy section I need for the search feature.
+- `deploy/`: container images building script.
+- `layouts/`: html, json and rss templates. Also some useful hugo shortcodes.
+- `search/`: the go program that powers the search feature.
+- `static/`: favicon, blog images and schematics.
## 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.
-
-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/).
-
-## Kubernetes
+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.
-I host this website on a k3s cluster. An example manifest can be found in the deploy folder.
+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
+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/).
diff --git a/deploy/build-image.sh b/deploy/build-image.sh
deleted file mode 100755
index a9cf511..0000000
--- a/deploy/build-image.sh
+++ /dev/null
@@ -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}"
diff --git a/deploy/headers_secure.conf b/deploy/headers_secure.conf
deleted file mode 100644
index 6dfc381..0000000
--- a/deploy/headers_secure.conf
+++ /dev/null
@@ -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;
diff --git a/deploy/headers_static.conf b/deploy/headers_static.conf
deleted file mode 100644
index 2b3f31d..0000000
--- a/deploy/headers_static.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-include headers_secure.conf;
-# Infinite caching
-add_header Cache-Control "public, max-age=31536000, immutable";
diff --git a/deploy/nginx.conf b/deploy/nginx.conf
deleted file mode 100644
index d4fe348..0000000
--- a/deploy/nginx.conf
+++ /dev/null
@@ -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";
- }
- }
-}
diff --git a/deploy/www.yaml b/deploy/www.yaml
deleted file mode 100644
index 6613173..0000000
--- a/deploy/www.yaml
+++ /dev/null
@@ -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