aboutsummaryrefslogtreecommitdiffstats
path: root/roles/jails/20_immich/templates
diff options
context:
space:
mode:
Diffstat (limited to 'roles/jails/20_immich/templates')
-rw-r--r--roles/jails/20_immich/templates/jail.conf.j248
-rw-r--r--roles/jails/20_immich/templates/usr_local_bin_extract_image.sh47
-rw-r--r--roles/jails/20_immich/templates/usr_local_etc_immich_ml.env.j24
-rw-r--r--roles/jails/20_immich/templates/usr_local_etc_immich_server.env.j220
-rw-r--r--roles/jails/20_immich/templates/usr_local_etc_rc.d_immich_ml57
-rw-r--r--roles/jails/20_immich/templates/usr_local_etc_rc.d_immich_server54
6 files changed, 230 insertions, 0 deletions
diff --git a/roles/jails/20_immich/templates/jail.conf.j2 b/roles/jails/20_immich/templates/jail.conf.j2
new file mode 100644
index 0000000..482737f
--- /dev/null
+++ b/roles/jails/20_immich/templates/jail.conf.j2
@@ -0,0 +1,48 @@
+immich {
+ vnet;
+ persist;
+ exec.clean;
+ allow.raw_sockets;
+ mount.devfs;
+ allow.mount;
+ allow.mount.devfs;
+ allow.mount.linprocfs;
+ allow.mount.linsysfs;
+ allow.mount.tmpfs;
+ allow.mount.nullfs;
+ enforce_statfs = 1;
+
+ devfs_ruleset = 4;
+ host.hostname = "immich";
+ path = "/usr/local/jails/containers/immich";
+
+ exec.start = "/bin/sh /etc/rc";
+ exec.stop = "/bin/sh /etc/rc.shutdown";
+
+ # LAN epair
+ exec.prestart += "ifconfig epl{{ jail_num }}a destroy 2>/dev/null || true";
+ exec.prestart += "ifconfig epair{{ jail_num }}000 create";
+ exec.prestart += "ifconfig epair{{ jail_num }}000a name epl{{ jail_num }}a";
+ exec.prestart += "ifconfig epair{{ jail_num }}000b name epl{{ jail_num }}b";
+ exec.prestart += "ifconfig epl{{ jail_num }}b ether random";
+ exec.prestart += "ifconfig brlan0 addm epl{{ jail_num }}a";
+ exec.poststart += "ifconfig epl{{ jail_num }}b vnet immich";
+ exec.poststart += "ifconfig epl{{ jail_num }}a up";
+ exec.poststart += "jexec immich ifconfig epl{{ jail_num }}b up";
+ exec.poststart += "jexec immich ifconfig epl{{ jail_num }}b {{ jail_lan_cidr | ipv4_nth_cidr(jail_num | int + jail_lan_offset | int) }}";
+ exec.poststart += "jexec immich route delete default || true";
+ exec.poststart += "jexec immich route add default {{ ingress_ip }} || true";
+ exec.poststop += "ifconfig epl{{ jail_num }}a destroy 2>/dev/null || true";
+{% for img in oci_images %}
+
+ # Mounts for {{ img.name }} rootfs
+ mount += "linprocfs $path/image/{{ img.name }}/proc linprocfs rw 0 0";
+ mount += "linsysfs $path/image/{{ img.name }}/sys linsysfs rw 0 0";
+ mount += "devfs $path/image/{{ img.name }}/dev devfs rw 0 0";
+ mount += "tmpfs $path/image/{{ img.name }}/tmp tmpfs rw 0 0";
+ mount += "tmpfs $path/image/{{ img.name }}/run tmpfs rw 0 0";
+{% for mnt in img.mounts | default([]) %}
+ mount += "$path/{{ mnt.src }} $path/image/{{ img.name }}{{ mnt.dst }} nullfs rw 0 0";
+{% endfor %}
+{% endfor %}
+}
diff --git a/roles/jails/20_immich/templates/usr_local_bin_extract_image.sh b/roles/jails/20_immich/templates/usr_local_bin_extract_image.sh
new file mode 100644
index 0000000..e8226dd
--- /dev/null
+++ b/roles/jails/20_immich/templates/usr_local_bin_extract_image.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+# Extract a Docker image to a directory under /image/
+# Usage: extract-image.sh <image-ref> <name>
+# Example: extract-image.sh ghcr.io/immich-app/immich-server:v2.4.1 immich-server
+
+set -eu
+
+IMAGE="$1"
+NAME="$2"
+IMAGE_DIR="/image"
+TARGET="${IMAGE_DIR}/${NAME}"
+TMP_DIR="/tmp/oci-${NAME}"
+
+echo "Extracting ${IMAGE} to ${TARGET}..."
+
+# Clean up any previous extraction attempt
+rm -rf "${TMP_DIR}"
+mkdir -p "${TMP_DIR}"
+
+# Pull image layers
+skopeo copy --override-os linux "docker://${IMAGE}" "dir:${TMP_DIR}"
+
+# Extract all layers in order into new rootfs
+rm -rf "${TARGET}.new"
+mkdir -p "${TARGET}.new"
+
+# Parse layer digests from manifest and extract each layer
+grep -o '"sha256:[a-f0-9]*"' "${TMP_DIR}/manifest.json" | \
+ sed 's/"//g; s/sha256://' | \
+ while read hash; do
+ if [ -f "${TMP_DIR}/${hash}" ]; then
+ echo " Extracting layer ${hash}..."
+ tar -xzf "${TMP_DIR}/${hash}" -C "${TARGET}.new" 2>/dev/null || \
+ tar -xf "${TMP_DIR}/${hash}" -C "${TARGET}.new" 2>/dev/null || true
+ fi
+ done
+
+# Swap in the new rootfs
+if [ -d "${TARGET}" ]; then
+ mv "${TARGET}" "${TARGET}.old"
+fi
+mv "${TARGET}.new" "${TARGET}"
+
+# Cleanup
+rm -rf "${TMP_DIR}" "${TARGET}.old"
+
+echo "Done: ${TARGET}"
diff --git a/roles/jails/20_immich/templates/usr_local_etc_immich_ml.env.j2 b/roles/jails/20_immich/templates/usr_local_etc_immich_ml.env.j2
new file mode 100644
index 0000000..f2c14a7
--- /dev/null
+++ b/roles/jails/20_immich/templates/usr_local_etc_immich_ml.env.j2
@@ -0,0 +1,4 @@
+# Immich machine learning configuration
+TZ=Europe/Helsinki
+IMMICH_PORT=3003
+MACHINE_LEARNING_CACHE_FOLDER=/model_cache
diff --git a/roles/jails/20_immich/templates/usr_local_etc_immich_server.env.j2 b/roles/jails/20_immich/templates/usr_local_etc_immich_server.env.j2
new file mode 100644
index 0000000..87c563d
--- /dev/null
+++ b/roles/jails/20_immich/templates/usr_local_etc_immich_server.env.j2
@@ -0,0 +1,20 @@
+# Immich server configuration
+IMMICH_MEDIA_LOCATION=/data
+TZ=Europe/Helsinki
+IMMICH_PORT=80
+NODE_ENV=production
+
+# Database
+DB_HOSTNAME={{ jail_lan_cidr | ipv4_nth(2 + jail_lan_offset | int) }}
+DB_PORT=5432
+DB_USERNAME=immich
+DB_PASSWORD={{ pg_user_passwords.immich }}
+DB_DATABASE_NAME=immich
+
+# Redis
+REDIS_HOSTNAME={{ jail_lan_cidr | ipv4_nth(9 + jail_lan_offset | int) }}
+REDIS_PORT=6379
+REDIS_PASSWORD={{ valkey_password }}
+
+# Machine learning
+MACHINE_LEARNING_URL=http://127.0.0.1:3003
diff --git a/roles/jails/20_immich/templates/usr_local_etc_rc.d_immich_ml b/roles/jails/20_immich/templates/usr_local_etc_rc.d_immich_ml
new file mode 100644
index 0000000..d20e4a6
--- /dev/null
+++ b/roles/jails/20_immich/templates/usr_local_etc_rc.d_immich_ml
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# PROVIDE: immich_ml
+# REQUIRE: NETWORKING
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name="immich_ml"
+rcvar="${name}_enable"
+pidfile="/var/run/${name}.pid"
+logfile="/var/log/${name}.log"
+
+load_rc_config $name
+: ${immich_ml_enable:="NO"}
+: ${immich_ml_envfile:="/usr/local/etc/immich_ml.env"}
+: ${immich_ml_root:="/image/immich-ml"}
+
+start_cmd="${name}_start"
+stop_cmd="${name}_stop"
+status_cmd="${name}_status"
+
+immich_ml_start() {
+ echo "Starting ${name}."
+ set -a
+ . ${immich_ml_envfile}
+ set +a
+ export PATH=/opt/venv/bin:/usr/local/bin:/usr/bin:/bin
+ export VIRTUAL_ENV=/opt/venv
+ export PYTHONDONTWRITEBYTECODE=1
+ export PYTHONUNBUFFERED=1
+ export PYTHONPATH=/usr/src
+ /usr/sbin/daemon -P ${pidfile} -o ${logfile} \
+ /usr/sbin/chroot ${immich_ml_root} \
+ /opt/venv/bin/python -m immich_ml
+}
+
+immich_ml_stop() {
+ if [ -f ${pidfile} ]; then
+ echo "Stopping ${name}."
+ kill $(cat ${pidfile}) 2>/dev/null
+ rm -f ${pidfile}
+ else
+ echo "${name} is not running."
+ fi
+}
+
+immich_ml_status() {
+ if [ -f ${pidfile} ] && kill -0 $(cat ${pidfile}) 2>/dev/null; then
+ echo "${name} is running as pid $(cat ${pidfile})."
+ else
+ echo "${name} is not running."
+ return 1
+ fi
+}
+
+run_rc_command "$1"
diff --git a/roles/jails/20_immich/templates/usr_local_etc_rc.d_immich_server b/roles/jails/20_immich/templates/usr_local_etc_rc.d_immich_server
new file mode 100644
index 0000000..42946cc
--- /dev/null
+++ b/roles/jails/20_immich/templates/usr_local_etc_rc.d_immich_server
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+# PROVIDE: immich_server
+# REQUIRE: NETWORKING
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name="immich_server"
+rcvar="${name}_enable"
+pidfile="/var/run/${name}.pid"
+logfile="/var/log/${name}.log"
+
+load_rc_config $name
+: ${immich_server_enable:="NO"}
+: ${immich_server_envfile:="/usr/local/etc/immich_server.env"}
+: ${immich_server_root:="/image/immich-server"}
+
+start_cmd="${name}_start"
+stop_cmd="${name}_stop"
+status_cmd="${name}_status"
+
+immich_server_start() {
+ echo "Starting ${name}."
+ set -a
+ . ${immich_server_envfile}
+ set +a
+ export PATH=/usr/local/bin:/usr/bin:/bin
+ export NODE_ENV=production
+ /usr/sbin/daemon -P ${pidfile} -o ${logfile} \
+ /usr/sbin/chroot ${immich_server_root} \
+ /usr/local/bin/node /usr/src/app/server/dist/main.js
+}
+
+immich_server_stop() {
+ if [ -f ${pidfile} ]; then
+ echo "Stopping ${name}."
+ kill $(cat ${pidfile}) 2>/dev/null
+ rm -f ${pidfile}
+ else
+ echo "${name} is not running."
+ fi
+}
+
+immich_server_status() {
+ if [ -f ${pidfile} ] && kill -0 $(cat ${pidfile}) 2>/dev/null; then
+ echo "${name} is running as pid $(cat ${pidfile})."
+ else
+ echo "${name} is not running."
+ return 1
+ fi
+}
+
+run_rc_command "$1"