2026-05-12 21:22:07 +02:00
#!/usr/bin/env bash
2026-09-01 13:28:55 +02:00
_cs_boot = " ${ COMMUNITY_SCRIPTS_CORE_DIR :-$( dirname " ${ BASH_SOURCE [0] } " ) /../../core } /core/build.func"
source " $_cs_boot " 2>/dev/null || source <( curl -fsSL " ${ COMMUNITY_SCRIPTS_CORE_URL :- https ://raw.githubusercontent.com/community-scripts/core/main } /core/build.func" )
2026-05-12 21:22:07 +02:00
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Thieneret
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/goauthentik/authentik
APP = "authentik"
var_tags = " ${ var_tags :- auth } "
var_cpu = " ${ var_cpu :- 4 } "
2026-06-05 12:02:00 +02:00
var_ram = " ${ var_ram :- 8192 } "
2026-05-12 21:22:07 +02:00
var_disk = " ${ var_disk :- 16 } "
var_os = " ${ var_os :- debian } "
var_version = " ${ var_version :- 13 } "
2026-05-23 07:46:44 +10:00
var_arm64 = " ${ var_arm64 :- no } "
2026-05-12 21:22:07 +02:00
var_unprivileged = " ${ var_unprivileged :- 1 } "
header_info " $APP "
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/authentik ]] ; then
msg_error "No authentik Installation Found!"
exit
fi
2026-07-06 21:15:04 +02:00
read -r MAJOR MINOR PATCH <<< " $( sed 's/^version\///; s/\./ /g' " $HOME /.authentik" ) "
2026-06-05 12:02:00 +02:00
2026-08-22 06:30:52 +02:00
if [[ $MAJOR == 2026 && $MINOR -lt 5 ]] ; then
msg_error "Updating from version ${ MAJOR } . ${ MINOR } . ${ PATCH } is not supported. A minimum version of 2026.5.x is required to update. See: https://docs.goauthentik.io/releases/2026.8/"
exit
fi
2026-06-05 12:02:00 +02:00
msg_info "Update dependencies"
2026-06-19 17:53:08 +10:00
ensure_dependencies crossbuild-essential-$( arch_resolve) gcc-$( arch_resolve "x86-64" "aarch64" ) -linux-gnu cmake clang libunwind-18-dev
2026-06-05 12:02:00 +02:00
msg_ok "Update dependencies"
2026-09-18 23:32:09 +02:00
NODE_VERSION = "26" NODE_MODULE = pnpm@12 setup_nodejs
2026-07-19 13:21:14 +02:00
$STD uv cache clean
2026-06-05 12:02:00 +02:00
RUST_PROFILE = "minimal" RUST_TOOLCHAIN = "stable" setup_rust
setup_yq
2026-05-12 21:22:07 +02:00
2026-09-18 23:32:09 +02:00
AUTHENTIK_VERSION = "version/2026.8.3"
2026-06-05 12:02:00 +02:00
# Source: https://github.com/goauthentik/fips/blob/main/Makefile#L26
2026-07-19 13:21:14 +02:00
XMLSEC_VERSION = "1.3.12"
2026-05-12 21:22:07 +02:00
if check_for_gh_release "geoipupdate" "maxmind/geoipupdate" ; then
fetch_and_deploy_gh_release "geoipupdate" "maxmind/geoipupdate" "binary"
fi
if check_for_gh_release "xmlsec" "lsh123/xmlsec" " ${ XMLSEC_VERSION } " ; then
CLEAN_INSTALL = 1 fetch_and_deploy_gh_release "xmlsec" "lsh123/xmlsec" "tarball" " ${ XMLSEC_VERSION } " "/opt/xmlsec"
msg_info "Updating xmlsec"
cd /opt/xmlsec
$STD ./autogen.sh
$STD make -j $( nproc)
$STD make check
$STD make install
$STD ldconfig
msg_ok "Updated xmlsec"
fi
if check_for_gh_release "authentik" "goauthentik/authentik" " ${ AUTHENTIK_VERSION } " ; then
msg_info "Stopping Services"
systemctl stop authentik-server authentik-worker
2026-07-06 21:15:04 +02:00
if [[ $( systemctl is-active authentik-ldap) == active ]] ; then
systemctl stop authentik-ldap
fi
if [[ $( systemctl is-active authentik-rac) == active ]] ; then
systemctl stop authentik-rac
fi
if [[ $( systemctl is-active authentik-radius) == active ]] ; then
systemctl stop authentik-radius
fi
2026-05-12 21:22:07 +02:00
msg_ok "Stopped Services"
2026-09-03 08:04:29 +02:00
if [[ ! -d /opt/authentik-data/blueprints ]] ; then
msg_info "Moving blueprints to presistent directory"
cp -r /opt/authentik/blueprints /opt/authentik-data/
rm -r /opt/authentik/blueprints
2026-09-05 22:41:58 +02:00
$STD find /opt/authentik-data -path '*/lost+found' -prune -o -exec chown authentik:authentik {} +
2026-09-03 08:04:29 +02:00
yq -i ".blueprints_dir = \"/opt/authentik-data/blueprints\"" /etc/authentik/config.yml
msg_ok "blueprints moved to presistent directory"
msg_warn "The blueprints provided by authentik are always overwritten when updated! Only manually created custom blueprints remain unchanged between updates."
fi
2026-05-12 21:22:07 +02:00
CLEAN_INSTALL = 1 fetch_and_deploy_gh_release "authentik" "goauthentik/authentik" "tarball" " ${ AUTHENTIK_VERSION } " "/opt/authentik"
2026-09-22 16:06:15 +02:00
UV_PYTHON_INSTALL_DIR = "/usr/local/bin" PYTHON_VERSION = "3.14.7" UV_PROJECT_DIR = "/opt/authentik" setup_uv
2026-09-03 15:45:59 +02:00
GO_VERSION = " $( grep -m1 '^go ' /opt/authentik/go.mod | awk '{print $2}' ) " setup_go
2026-05-12 21:22:07 +02:00
2026-07-06 21:15:04 +02:00
msg_info "Configuring rust"
cd /opt/authentik
$STD rustup install
$STD rustup default " $( sed -n 's/channel = "\(.*\)"/\1/p' rust-toolchain.toml) "
msg_ok "Configured rust"
2026-06-05 12:02:00 +02:00
2026-07-06 21:15:04 +02:00
msg_info "Updating web"
2026-05-12 21:22:07 +02:00
export NODE_ENV = "production"
2026-08-22 06:30:52 +02:00
cd /opt/authentik
2026-09-18 23:32:09 +02:00
$STD node ./scripts/node/lint-runtime.ts ./web
2026-08-22 06:30:52 +02:00
cd /opt/authentik/web
$STD pnpm install --frozen-lockfile
$STD pnpm run build
$STD pnpm run build:sfe
2026-05-12 21:22:07 +02:00
msg_ok "Updated web"
2026-08-22 06:30:52 +02:00
msg_info "Updating outposts"
2026-05-12 21:22:07 +02:00
cd /opt/authentik
2026-08-22 06:30:52 +02:00
mkdir -p /opt/authentik/bin
2026-05-12 21:22:07 +02:00
export CGO_ENABLED = "1"
2026-06-19 17:53:08 +10:00
export CC = " $( arch_resolve "x86_64" "aarch64" ) -linux-gnu-gcc"
2026-05-12 21:22:07 +02:00
$STD go mod download
2026-08-22 06:30:52 +02:00
$STD go build -o /opt/authentik/bin/ldap ./cmd/ldap
$STD go build -o /opt/authentik/bin/rac ./cmd/rac
$STD go build -o /opt/authentik/bin/radius ./cmd/radius
msg_ok "Updated outposts"
msg_info "Building binary. It may take more than 10 minutes, please be patient."
export AWS_LC_FIPS_SYS_CC = "clang"
cd /opt/authentik
$STD cargo build --package authentik --no-default-features --features core --locked --release
cp ./target/release/authentik /opt/authentik/bin/
rm -r ./target
2026-07-06 21:15:04 +02:00
msg_ok "Built worker"
2026-06-05 12:02:00 +02:00
2026-05-12 21:22:07 +02:00
msg_info "Updating python server"
export UV_NO_BINARY_PACKAGE = "cryptography lxml python-kadmin-rs xmlsec"
export UV_COMPILE_BYTECODE = "1"
export UV_LINK_MODE = "copy"
export UV_NATIVE_TLS = "1"
export RUSTUP_PERMIT_COPY_RENAME = "true"
export UV_PYTHON_INSTALL_DIR = "/usr/local/bin"
cd /opt/authentik
2026-08-02 17:46:02 +10:00
for attempt in 1 2 3; do
if [[ $attempt -eq 3 ]] ; then
2026-08-22 06:30:52 +02:00
$STD uv sync --locked --no-install-project --no-dev
2026-08-02 17:46:02 +10:00
break
fi
2026-08-22 06:30:52 +02:00
$STD uv sync --locked --no-install-project --no-dev && break
2026-08-02 17:46:02 +10:00
msg_warn "uv sync attempt $attempt failed, retrying..."
sleep $(( attempt * 15 ))
done
2026-05-12 21:22:07 +02:00
chown -R authentik:authentik /opt/authentik
msg_ok "Updated python server"
2026-06-05 12:02:00 +02:00
2026-09-03 08:04:29 +02:00
cp -r /opt/authentik/blueprints /opt/authentik-data/
rm -r /opt/authentik/blueprints
2026-09-05 22:41:58 +02:00
$STD find /opt/authentik-data -path '*/lost+found' -prune -o -exec chown authentik:authentik {} +
2026-09-03 08:04:29 +02:00
if [[ $MAJOR == 2026 && $MINOR -lt 8 ]] ; then
msg_info "Updating Worker and Server config (from $MAJOR . $MINOR )"
cat <<EOF >>/etc/default/authentik-server
2026-08-22 06:30:52 +02:00
RUST_BACKTRACE=full
2026-06-05 12:02:00 +02:00
EOF
2026-09-03 08:04:29 +02:00
cat <<EOF >>/etc/default/authentik-worker
2026-08-22 06:30:52 +02:00
RUST_BACKTRACE=full
2026-06-05 12:02:00 +02:00
EOF
2026-09-03 08:04:29 +02:00
msg_ok "Updated Worker and Server config (from $MAJOR . $MINOR )"
msg_info "Updating services (from $MAJOR . $MINOR )"
sed -i "s|ExecStart=/opt/authentik/authentik-server|ExecStart=/opt/authentik/bin/authentik server|g" /etc/systemd/system/authentik-server.service
sed -i "s|ExecStart=/opt/authentik/authentik-worker worker|ExecStart=/opt/authentik/bin/authentik worker|g" /etc/systemd/system/authentik-worker.service
sed -i "s|ExecStart=/opt/authentik/ldap|ExecStart=/opt/authentik/bin/ldap|g" /etc/systemd/system/authentik-ldap.service
sed -i "s|ExecStart=/opt/authentik/radius|ExecStart=/opt/authentik/bin/radius|g" /etc/systemd/system/authentik-radius.service
sed -i "s|ExecStart=/opt/authentik/rac|ExecStart=/opt/authentik/bin/rac|g" /etc/systemd/system/authentik-rac.service
systemctl daemon-reload
msg_ok "Updated services (from $MAJOR . $MINOR )"
fi
msg_info "Updating Worker and Server config"
2026-09-05 22:41:58 +02:00
sed -i "s|/dev/shm\/\? $|/dev/shm/authentik-server|g" /etc/default/authentik-server
sed -i "s|/dev/shm\/\? $|/dev/shm/authentik-worker|g" /etc/default/authentik-worker
2026-09-03 08:04:29 +02:00
msg_ok "Updated Worker and Server config"
2026-08-22 06:30:52 +02:00
msg_info "Updating services"
2026-09-03 08:04:29 +02:00
sed -i 's/authentik Go Server (API Gateway)/authentik Server/g' /etc/systemd/system/authentik-server.service
2026-09-11 20:12:18 +02:00
if ! grep -qF -- 'ExecStartPre=/usr/bin/mkdir -p "${TMPDIR}"' /etc/systemd/system/authentik-server.service; then
sed -i '/ExecStart=/i ExecStartPre=/usr/bin/mkdir -p "${TMPDIR}"' /etc/systemd/system/authentik-server.service
fi
if ! grep -qF -- 'ExecStartPre=/usr/bin/mkdir -p "${TMPDIR}"' /etc/systemd/system/authentik-worker.service; then
sed -i '/ExecStart=/i ExecStartPre=/usr/bin/mkdir -p "${TMPDIR}"' /etc/systemd/system/authentik-worker.service
fi
2026-08-22 06:30:52 +02:00
systemctl daemon-reload
msg_ok "Updated services"
msg_info "Starting Services"
systemctl start authentik-server authentik-worker
if [[ $( systemctl is-enabled authentik-ldap) == enabled ]] ; then
systemctl start authentik-ldap
fi
if [[ $( systemctl is-enabled authentik-rac) == enabled ]] ; then
systemctl start authentik-rac
fi
if [[ $( systemctl is-enabled authentik-radius) == enabled ]] ; then
systemctl start authentik-radius
fi
msg_ok "Started Services"
2026-05-12 21:22:07 +02:00
fi
msg_ok "Updated successfully!"
exit
}
start
build_container
msg_info "Attaching data storage volume"
$STD pct stop " $CTID "
if [ " ${ PROTECT_CT :- } " == "1" ] || [ " ${ PROTECT_CT :- } " == "yes" ] ; then
$STD pct set " $CTID " --protection 0
$STD pct set " $CTID " -mp0 " ${ CONTAINER_STORAGE } " :1,mp= /opt/authentik-data,backup= 1
$STD pct set " $CTID " --protection 1
else
$STD pct set " $CTID " -mp0 " ${ CONTAINER_STORAGE } " :1,mp= /opt/authentik-data,backup= 1
fi
$STD pct start " $CTID "
for i in { 1..10} ; do
pct status " $CTID " | grep -q "status: running" && break
sleep 1
done
$STD pct exec " $CTID " -- bash -c "mkdir -p /opt/authentik-data/{certs,media,geoip,templates}; \
2026-09-11 20:12:18 +02:00
cp /opt/authentik/tests/geoip/GeoLite2-ASN-Test.mmdb /opt/authentik-data/geoip/GeoLite2-ASN.mmdb; \
cp /opt/authentik/tests/geoip/GeoLite2-City-Test.mmdb /opt/authentik-data/geoip/GeoLite2-City.mmdb; \
2026-09-03 08:04:29 +02:00
cp -r /opt/authentik/blueprints /opt/authentik-data/; \
rm -r /opt/authentik/blueprints; \
2026-09-05 22:41:58 +02:00
find /opt/authentik-data -path '*/lost+found' -prune -o -exec chown authentik:authentik {} +"
2026-05-12 21:22:07 +02:00
msg_ok "Attached data storage volume"
msg_info "Starting Services"
pct exec " $CTID " -- systemctl enable -q --now authentik-server authentik-worker
msg_ok "Started Services"
description
msg_ok "Completed successfully!\n"
echo -e " ${ CREATING }${ GN }${ APP } setup has been successfully initialized! ${ CL } "
2026-07-06 21:15:04 +02:00
echo -e " ${ INFO }${ YW } Access it using the following URL: ${ CL } "
echo -e " ${ GATEWAY }${ BGN } https:// ${ IP } :9443 ${ CL } "