git: 8f95215097ff - main - sysutils/fjord: New port: Web UI for managing container compose stacks

From: Jesús Daniel Colmenares Oviedo <dtxdf_at_FreeBSD.org>
Date: Sat, 03 Oct 2026 21:30:21 UTC
The branch main has been updated by dtxdf:

URL: https://cgit.FreeBSD.org/ports/commit/?id=8f95215097ff4d3fb44671d6907c5a6546ab02f8

commit 8f95215097ff4d3fb44671d6907c5a6546ab02f8
Author:     Michael Johnson <ahze@ahze.net>
AuthorDate: 2026-10-03 21:24:44 +0000
Commit:     Jesús Daniel Colmenares Oviedo <dtxdf@FreeBSD.org>
CommitDate: 2026-10-03 21:29:17 +0000

    sysutils/fjord: New port: Web UI for managing container compose stacks
    
    fjord is a web management interface and daemon for running OCI container
    applications natively on FreeBSD, as Compose stacks. Delivered as a single
    self-contained binary with an embedded web UI, it manages stack lifecycles,
    storage, networks and application catalogs using standard compose.yaml and
    .env files directly on the filesystem with zero database lock-in.
    
    Features:
    - Dual-engine runtime: orchestrate stacks via Podman (with ocijail) or
      native FreeBSD jails via AppJail (appjail-director).
    - Filesystem source of truth: stacks are plain directories containing
      standard compose.yaml and .env files.
    - Workload adoption: convert existing standalone containers or jails into
      managed Compose stacks in place.
    - Automated host diagnostics: pre-flight checks verify engine binaries,
      API sockets, and PF firewall anchors with copyable fixes.
    - Integrated application catalog for one-click stack deployments.
    
    WWW: https://fjord.daemonless.io
    
    PR:             299073
---
 sysutils/Makefile                   |  1 +
 sysutils/fjord/Makefile             | 39 ++++++++++++++++++++++++++++++++++
 sysutils/fjord/distinfo             |  3 +++
 sysutils/fjord/files/fjordd.in      | 42 +++++++++++++++++++++++++++++++++++++
 sysutils/fjord/files/pkg-message.in | 32 ++++++++++++++++++++++++++++
 sysutils/fjord/pkg-descr            | 16 ++++++++++++++
 6 files changed, 133 insertions(+)

diff --git a/sysutils/Makefile b/sysutils/Makefile
index 46e60e0d2e2c..cd7ca0e9026b 100644
--- a/sysutils/Makefile
+++ b/sysutils/Makefile
@@ -413,6 +413,7 @@
     SUBDIR += firstboot-freebsd-update
     SUBDIR += firstboot-pkg-upgrade
     SUBDIR += firstboot-pkgs
+    SUBDIR += fjord
     SUBDIR += flasher
     SUBDIR += flashrom
     SUBDIR += flexbackup
diff --git a/sysutils/fjord/Makefile b/sysutils/fjord/Makefile
new file mode 100644
index 000000000000..8baf6e479c62
--- /dev/null
+++ b/sysutils/fjord/Makefile
@@ -0,0 +1,39 @@
+PORTNAME=	fjord
+DISTVERSION=	0.3.0
+CATEGORIES=	sysutils
+MASTER_SITES=	https://github.com/daemonless/${PORTNAME}/releases/download/v${DISTVERSION}/
+
+MAINTAINER=	michaeljohnson@ahze.net
+COMMENT=	Web UI for managing container compose stacks
+WWW=		https://fjord.daemonless.io
+
+LICENSE=	BSD2CLAUSE
+LICENSE_FILE=	${WRKSRC}/LICENSE
+
+USES=		go:modules python:env
+
+GO_TARGET=	./cmd/fjordd:${PREFIX}/sbin/fjordd
+GO_LDFLAGS=	-X main.version=${DISTVERSION}
+
+USE_RC_SUBR=	fjordd
+
+OPTIONS_MULTI=	ENGINE
+OPTIONS_MULTI_ENGINE=	APPJAIL PODMAN
+OPTIONS_DEFAULT=	APPJAIL PODMAN
+ENGINE_DESC=	Container engines (at least one)
+APPJAIL_DESC=	AppJail engine (appjail, appjail-director)
+PODMAN_DESC=	Podman engine (podman, podman-compose)
+
+APPJAIL_RUN_DEPENDS=	appjail>=5.5.0:sysutils/appjail \
+		${PYTHON_PKGNAMEPREFIX}director>=0.18.0:sysutils/py-director@${PY_FLAVOR}
+PODMAN_RUN_DEPENDS=	podman:sysutils/podman \
+		${PYTHON_PKGNAMEPREFIX}podman-compose>=1.2.0:sysutils/podman-compose@${PY_FLAVOR} \
+		ocijail>=0.6.0:sysutils/ocijail \
+		${LOCALBASE}/libexec/cni/dnsname:sysutils/cni-dnsname \
+		${LOCALBASE}/libexec/cni/epair:sysutils/cni-epair
+
+PLIST_FILES=	sbin/fjordd
+
+SUB_FILES=	pkg-message
+
+.include <bsd.port.mk>
diff --git a/sysutils/fjord/distinfo b/sysutils/fjord/distinfo
new file mode 100644
index 000000000000..195827abd992
--- /dev/null
+++ b/sysutils/fjord/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1790963123
+SHA256 (fjord-0.3.0.tar.gz) = aac238aa26420829015cfc64622626b6eb0616f0bd99d5b1f88dab972fd48664
+SIZE (fjord-0.3.0.tar.gz) = 1299355
diff --git a/sysutils/fjord/files/fjordd.in b/sysutils/fjord/files/fjordd.in
new file mode 100644
index 000000000000..71d370a06a62
--- /dev/null
+++ b/sysutils/fjord/files/fjordd.in
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# FJORD Daemon
+
+# PROVIDE: fjordd
+# REQUIRE: LOGIN podman_service
+# KEYWORD: shutdown
+
+# Enable in /etc/rc.conf:
+#   fjordd_enable="YES"
+#
+# Configuration is via FJORD_* environment variables, passed with fjordd_env:
+#   fjordd_env="FJORD_CATALOG_URL=https://... FJORD_LISTEN=:3567"
+# (FJORD_STACKS_DIR, FJORD_ENGINE, FJORD_PODMAN_SOCKET, FJORD_HOST_ADDR also
+# available; defaults suit a host install.)
+
+. /etc/rc.subr
+
+name=fjordd
+rcvar=${name}_enable
+
+: ${fjordd_enable:="NO"}
+: ${fjordd_log:="/var/log/fjordd.log"}
+
+command="%%PREFIX%%/sbin/fjordd"
+pidfile="/var/run/${name}.pid"
+start_cmd="fjordd_start"
+
+fjordd_start()
+{
+    startmsg "Starting ${name}."
+    # env(1) carries fjordd_env (custom start_cmd bypasses rc.subr's automatic
+    # ${name}_env) and extends rc(8)'s boot PATH, which omits /usr/local --
+    # where podman/podman-compose live; without it every engine exec fails
+    # after a reboot.
+    /usr/sbin/daemon -o ${fjordd_log} -f -p ${pidfile} \
+        /usr/bin/env PATH="${PATH}:%%LOCALBASE%%/sbin:%%LOCALBASE%%/bin" ${fjordd_env} \
+        ${command} ${fjordd_flags}
+}
+
+load_rc_config ${name}
+run_rc_command "$1"
diff --git a/sysutils/fjord/files/pkg-message.in b/sysutils/fjord/files/pkg-message.in
new file mode 100644
index 000000000000..cf2ea9f1002b
--- /dev/null
+++ b/sysutils/fjord/files/pkg-message.in
@@ -0,0 +1,32 @@
+[
+{ type: install
+  message: <<EOM
+Quick Start:
+  sysrc fjordd_enable=YES
+  service fjordd start
+
+  Open http://<host-ip>:3567 in your browser to launch the setup wizard.
+  The wizard and System dashboard automatically check host readiness and
+  provide copyable shell fixes for any missing engine prerequisites.
+
+Host Prerequisites:
+  Fjord requires at least one container engine (Podman and/or AppJail).
+  See the host prerequisite guide for kernel, package, and PF setup:
+    https://fjord.daemonless.io/install/
+
+  - Podman: fjord requires the API socket service running:
+      sysrc podman_service_enable=YES
+      service podman_service start
+
+  - AppJail: fjord drives appjail-director (sysutils/py-director).
+    Requires AppJail 5.5.0 or newer.
+
+  - Firewall (PF): Port publishing on bridge/virtual networks requires
+    PF NAT and redirection anchors. If published ports hang or fail,
+    check the System dashboard in the web UI.
+
+Stacks are stored in /var/db/fjord/stacks. Additional daemon variables
+are documented in %%PREFIX%%/etc/rc.d/fjordd.
+EOM
+}
+]
diff --git a/sysutils/fjord/pkg-descr b/sysutils/fjord/pkg-descr
new file mode 100644
index 000000000000..76e5241413f1
--- /dev/null
+++ b/sysutils/fjord/pkg-descr
@@ -0,0 +1,16 @@
+fjord is a web management interface and daemon for running OCI container
+applications natively on FreeBSD, as Compose stacks. Delivered as a single
+self-contained binary with an embedded web UI, it manages stack lifecycles,
+storage, networks and application catalogs using standard compose.yaml and
+.env files directly on the filesystem with zero database lock-in.
+
+Features:
+- Dual-engine runtime: orchestrate stacks via Podman (with ocijail) or
+  native FreeBSD jails via AppJail (appjail-director).
+- Filesystem source of truth: stacks are plain directories containing
+  standard compose.yaml and .env files.
+- Workload adoption: convert existing standalone containers or jails into
+  managed Compose stacks in place.
+- Automated host diagnostics: pre-flight checks verify engine binaries,
+  API sockets, and PF firewall anchors with copyable fixes.
+- Integrated application catalog for one-click stack deployments.