summaryrefslogtreecommitdiff
path: root/deploy
diff options
context:
space:
mode:
Diffstat (limited to 'deploy')
-rw-r--r--deploy/Caddyfile47
-rw-r--r--deploy/Dockerfile.cross8
-rwxr-xr-xdeploy/bokftui-web40
-rw-r--r--deploy/cross-build.sh12
-rwxr-xr-xdeploy/web-entrypoint.sh26
5 files changed, 125 insertions, 8 deletions
diff --git a/deploy/Caddyfile b/deploy/Caddyfile
new file mode 100644
index 0000000..c86f4e5
--- /dev/null
+++ b/deploy/Caddyfile
@@ -0,0 +1,47 @@
+# Web frontend routing inside the bokf-web container: the login gate
+# (bokfweb, 127.0.0.1:7682) and the browser terminal (ttyd, 127.0.0.1:7681).
+# Nothing reaches ttyd without the gate's OK.
+#
+# Plain HTTP on :8790, published on the host's loopback only. TLS for
+# https://bokf.makandra.eu is the host's reverse proxy (the NAS Caddy):
+#
+# bokf.makandra.eu {
+# tls { dns inwx ... } # as for the other sites
+# reverse_proxy 127.0.0.1:8790
+# }
+{
+ auto_https off
+ admin off
+ servers {
+ # the host proxy's X-Forwarded-For names the real client (the
+ # gate limits failed logins per client address)
+ trusted_proxies static private_ranges
+ }
+}
+
+:8790 {
+ header {
+ Strict-Transport-Security "max-age=31536000"
+ -Server
+ }
+
+ redir / /web/ 302
+
+ # the terminal: only with a live login whose handle is in the URL
+ @tty path /web/tty /web/tty/*
+ handle @tty {
+ forward_auth 127.0.0.1:7682 {
+ uri /auth
+ }
+ reverse_proxy 127.0.0.1:7681
+ }
+
+ # login page, login and logout
+ handle /web* {
+ reverse_proxy 127.0.0.1:7682
+ }
+
+ handle {
+ respond "not found" 404
+ }
+}
diff --git a/deploy/Dockerfile.cross b/deploy/Dockerfile.cross
index ab0504c..a14ac0f 100644
--- a/deploy/Dockerfile.cross
+++ b/deploy/Dockerfile.cross
@@ -1,12 +1,12 @@
-# Cross-compile the static arm64 backend binaries on an amd64 host. The
-# runtime image is assembled later on the target host from the produced
-# binaries; there is no TUI in the runtime image.
+# Cross-compile the static arm64 binaries on an amd64 host: the backend
+# (bokfd, bokfctl) and the web frontend's bokftui and bokfweb. The images
+# are assembled later on the target host from the produced binaries.
FROM debian:bookworm
RUN dpkg --add-architecture arm64 \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
make ca-certificates gcc-aarch64-linux-gnu \
- libc6-dev:arm64 libssl-dev:arm64 \
+ libc6-dev:arm64 libssl-dev:arm64 libncurses-dev:arm64 \
&& rm -rf /var/lib/apt/lists/*
COPY cross-build.sh /usr/local/bin/cross-build
RUN chmod 0755 /usr/local/bin/cross-build
diff --git a/deploy/bokftui-web b/deploy/bokftui-web
new file mode 100755
index 0000000..b6ec9b5
--- /dev/null
+++ b/deploy/bokftui-web
@@ -0,0 +1,40 @@
+#!/bin/sh
+# Started by ttyd for every browser terminal, with the terminal handle from
+# the URL (?arg=) as $1. Trades the handle for the bokfd session at the
+# gate (bokfweb /redeem, internal only), then runs bokftui already logged
+# in, in a private throwaway HOME, in web mode (no local files), with
+# resource limits. No shell is ever offered: when bokftui exits, the
+# terminal ends.
+set -u
+gate="${BOKFWEB_INTERNAL:-http://127.0.0.1:7682}"
+
+msg() {
+ printf '\r\n %s\r\n\r\n' "$1"
+ sleep 4
+ exit 1
+}
+
+handle="${1:-}"
+case "$handle" in
+ "" | *[!A-Za-z0-9_-]*) msg "Ogiltig länk. Öppna /web/ och logga in igen." ;;
+esac
+
+session=$(wget -q -O - --post-data "handle=$handle" "$gate/redeem" 2>/dev/null) ||
+ msg "Sessionen har gått ut. Öppna /web/ och logga in igen."
+case "$session" in
+ "" | *[!A-Za-z0-9_-]*) msg "Sessionen har gått ut. Öppna /web/ och logga in igen." ;;
+esac
+
+home=$(mktemp -d /tmp/bokf-web.XXXXXXXX) || msg "Kunde inte starta sessionen."
+trap 'rm -rf "$home"' EXIT HUP INT TERM
+chmod 0700 "$home"
+
+# per-session limits: memory, CPU time, open files (the process count is
+# capped per container in compose.yaml: every session runs as one uid)
+ulimit -v 524288 2>/dev/null || true
+ulimit -t 7200 2>/dev/null || true
+ulimit -n 256 2>/dev/null || true
+
+HOME="$home" XDG_CONFIG_HOME="$home/.config" XDG_CACHE_HOME="$home/.cache" \
+BOKF_WEB=1 BOKFD_SESSION="$session" \
+ bokftui --socket "${BOKFD_SOCKET:-/run/bokfd/bokfd.sock}"
diff --git a/deploy/cross-build.sh b/deploy/cross-build.sh
index 19d07b7..54a2929 100644
--- a/deploy/cross-build.sh
+++ b/deploy/cross-build.sh
@@ -1,16 +1,20 @@
#!/bin/sh
-# Cross-compile the static aarch64 backend binaries (bokfd, bokfctl).
+# Cross-compile the static aarch64 binaries: bokfd, bokfctl and, for the
+# web image, bokftui and bokfweb.
# Expects the source read-only at /src, writes the binaries to /out and takes
# the version from $VERSION. Run through deploy/Dockerfile.cross. OpenSSL and
# glibc are linked statically, so the Alpine runtime image needs no shared
# libraries (the kernel ABI is all that matters).
set -eu
-make -C /src -j"$(nproc)" BUILD=/tmp/build backend \
+# ncursesw needs its tinfo half spelled out for a static link
+make -C /src -j"$(nproc)" BUILD=/tmp/build \
+ backend /tmp/build/bokftui /tmp/build/bokfweb \
CC=aarch64-linux-gnu-gcc \
CFLAGS="-O2 -g -static -L/usr/lib/aarch64-linux-gnu" \
- SSL_LIBS="-l:libssl.a -l:libcrypto.a -ldl -lpthread" \
+ SSL_LIBS="-l:libssl.a -l:libcrypto.a -l:libtinfo.a -ldl -lpthread" \
VERSION="${VERSION:-0.1.0-dev}"
mkdir -p /out
-cp /tmp/build/bokfd /tmp/build/bokfctl /out/
+cp /tmp/build/bokfd /tmp/build/bokfctl /tmp/build/bokftui \
+ /tmp/build/bokfweb /out/
diff --git a/deploy/web-entrypoint.sh b/deploy/web-entrypoint.sh
new file mode 100755
index 0000000..38e07f9
--- /dev/null
+++ b/deploy/web-entrypoint.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+# Web frontend container: bokfweb (login gate), ttyd (browser terminal)
+# and Caddy (routing on :8790, behind the host's TLS proxy). The gate and
+# ttyd listen on 127.0.0.1 only. Each helper is restarted if it dies; Caddy
+# is the main process, so the container stops (and compose restarts it)
+# when Caddy does.
+set -eu
+
+export BOKFD_SOCKET="${BOKFD_SOCKET:-/run/bokfd/bokfd.sock}"
+export XDG_DATA_HOME=/tmp/caddy-data XDG_CONFIG_HOME=/tmp/caddy-config
+
+keep() {
+ while :; do
+ "$@" || true
+ echo "web: $1 exited, restarting" >&2
+ sleep 1
+ done
+}
+
+keep bokfweb &
+keep ttyd -i 127.0.0.1 -p 7681 -b /web/tty -a -W -O \
+ -m "${BOKF_WEB_MAX_SESSIONS:-20}" \
+ -t titleFixed=bokf -t fontSize=15 -t disableLeaveAlert=true \
+ bokftui-web &
+
+exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile