Add Authelia to OCI catalog

This commit is contained in:
Jonatan Castro
2026-11-03 11:34:27 +01:00
parent 9940f05adf
commit d9973635fb
7 changed files with 1047 additions and 1 deletions
+5
View File
@@ -615,6 +615,9 @@
"Authorize this key on the server": "Autorizovať tento kľúč na serveri",
"Authorize via 'pct exec' (Borg server is an LXC on a PVE host I can SSH into)": "Autorizovať cez 'pct exec' (Borg server je LXC na PVE hostovi, kam sa viem pripojiť cez SSH)",
"Authorized": "Autorizované",
"Authelia administrator": "Správca Authelia",
"Authelia session cookie domain for this portal (for example example.com)": "Doména súboru cookie relácie Authelia pre tento portál (napríklad example.com)",
"Authelia Web UI": "Webové rozhranie Authelia",
"Auto-detected firewall backend (nftables/iptables)": "Automaticky zistený firewall backend (nftables/iptables)",
"Auto-discover servers on network": "Automaticky nájsť servery v sieti",
"Auto-importing ZFS data pools from backup...": "Automaticky importujem ZFS dátové pooly zo zálohy...",
@@ -5402,6 +5405,7 @@
"Public UDP port peers connect to": "Verejný port UDP na pripojenie účastníkov",
"Public URL of phpMyAdmin when it is served behind a reverse proxy": "Verejné URL phpMyAdmin, keď sa podáva za reverzným proxy",
"Public URL used to access Baserow (for example https://baserow.example.com)": "Verejná adresa URL na prístup k Baserow (napríklad https://baserow.example.com)",
"Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)": "Verejná adresa HTTPS na otvorenie tohto portálu Authelia (napríklad https://auth.example.com)",
"Public address clients connect to (vpn.example.com or a public IP)": "Verejná adresa na pripojenie klientov (vpn.example.com alebo verejná IP adresa)",
"Public address peers connect to, or auto to detect it (vpn.example.com)": "Verejná adresa, ku ktorej sa pripájajú účastníci, alebo auto na jej zistenie (vpn.example.com)",
"Publish each directory from Resources: open it, switch on SMB, NFS or both, and save.": "Zverejnite každý adresár zo zdrojov: otvorte ho, zapnite SMB, NFS alebo oboje a uložte.",
@@ -6459,6 +6463,7 @@
"Single-node log storage and query UI.": "Úložisko logov a vyhľadávacie rozhranie pre jeden uzol.",
"Single-node observability database for metrics, logs and traces.": "Databáza na jednom uzle na ukladanie metrík, logov a záznamov o priebehu požiadaviek.",
"Single-server website CMS and visual editor with SQLite-backed content, media uploads, forms, and publishing.": "Webový CMS a vizuálny editor pre jeden server s obsahom uloženým v SQLite, nahrávaním médií, formulármi a publikovaním.",
"Single sign-on and multi-factor authentication": "Jednotné prihlásenie a viacfaktorové overovanie",
"Size": "Veľkosť",
"Size in GB of": "Veľkosť v GB pre",
"Size of each consume/export volume in GB": "Veľkosť každého dátového zväzku pre consume a export v GB",
+2 -1
View File
@@ -2,7 +2,7 @@
<!-- Generated from oci/catalog/verification.json by .github/scripts/oci_validation.py. Do not edit by hand. -->
52 of 533 applications in the OCI catalog have been tested for real: 49 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists.
53 of 534 applications in the OCI catalog have been tested for real: 50 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists.
Each test describes the scenario that was run and names the image it ran on. It does not cover every possible configuration of the application, and a newer image has not been tested until someone reports it.
@@ -38,6 +38,7 @@ Questions and ideas about OCI testing go in [discussion #440](https://github.com
| Alby Hub ✨ | Finance & Budgeting |
| Alist | Files & Sharing |
| aMule | Files & Downloads |
| Authelia | Authentication & Security |
| Authentik | Authentication & Security |
| Chromium | Browsers & Web Desktops |
| CodeProject.AI Server | AI |
+453
View File
@@ -0,0 +1,453 @@
{
"schema_version": "0.4.0",
"kind": "proxmenux.oci-template",
"id": "image-authelia",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Authelia",
"es_ES": "Authelia"
},
"tagline": {
"en_US": "Single sign-on and multi-factor authentication",
"es_ES": "Inicio de sesión único y autenticación multifactor"
},
"description": {
"en_US": "An open-source authentication and authorization server for protecting web applications. This single-image profile provides a local SQLite database and file notifications; configure your domain, reverse proxy and access rules before protecting other services.",
"es_ES": "Servidor de autenticación y autorización de código abierto para proteger aplicaciones web. Este perfil de una sola imagen incluye una base de datos SQLite local y notificaciones en archivo; configura el dominio, el proxy inverso y las reglas de acceso antes de proteger otros servicios."
},
"category": "security",
"category_label": "Authentication & Security",
"author": "Authelia",
"developer": "Authelia",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/authelia.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 9091,
"path": "/"
},
"website": "https://www.authelia.com/",
"documentation": "https://www.authelia.com/integration/deployment/docker/",
"repository": "https://github.com/authelia/authelia",
"tips": [
"The installer creates a unique admin password and stores only its Argon2id hash in /config/users_database.yml. The password is shown in the installation result.",
"Authelia requires an HTTPS portal URL and a cookie domain matching that hostname. If you use Nginx Proxy Manager, follow the official integration guide and configure trusted proxies and forward-auth separately.",
"The default notifier writes messages to /config/notification.txt. Configure SMTP in /config/configuration.yml if you want email delivery.",
"The initial access-control policy is one_factor. Add explicit access-control rules before attaching Authelia to protected proxy hosts."
],
"mini_changelog": [],
"display_version": "4.39.28",
"updated_at": "2026-09-17"
},
"source": {
"provider": "authelia",
"repository": "https://github.com/authelia/authelia",
"default_branch": "master",
"revision": "8da42b2348b0351c6284a2940a9c5eec3d4cd3fd",
"readme_raw_url": "https://raw.githubusercontent.com/authelia/authelia/v4.39.28/examples/compose/lite/compose.yml",
"readme_pushed_at": "2026-09-17T12:13:30Z",
"compose_sha256": "848ce0f70e502981a050ac200d9d1882978a6c3b0f9f0dfcc6d52ce66ca37fb5",
"generated_at": "2026-11-03T09:10:57+00:00",
"image_repository_url": "https://hub.docker.com/r/authelia/authelia"
},
"container_contract": {
"service_name": "authelia",
"container_name": "authelia",
"image": {
"reference": "docker.io/authelia/authelia:4.39.28",
"registry": "docker.io",
"repository": "docker.io/authelia/authelia",
"tag": "4.39.28",
"digest": null,
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
},
"environment": [
{
"name": "PROXMENUX_ADMIN_PASSWORD",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-first-start"
},
{
"name": "AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "AUTHELIA_SESSION_SECRET",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "AUTHELIA_STORAGE_ENCRYPTION_KEY",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "X_AUTHELIA_CONFIG_FILTERS",
"example": "template",
"required": true,
"sensitive": false,
"source": "authelia-container"
},
{
"name": "PROXMENUX_AUTHELIA_COOKIE_DOMAIN",
"example": "",
"prompt": "Authelia session cookie domain for this portal (for example example.com)",
"required": true,
"sensitive": false,
"source": "administrator"
},
{
"name": "PROXMENUX_AUTHELIA_URL",
"example": "",
"prompt": "Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)",
"required": true,
"sensitive": false,
"source": "administrator"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./authelia",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 4
}
}
],
"ports": [
{
"container_port": 9091,
"published_example": 9091,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n authelia:\n entrypoint:\n - /bin/sh\n - /usr/local/bin/proxmenux-authelia-bootstrap\n environment:\n AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET: ${GENERATED_RESET_PASSWORD_JWT_SECRET}\n AUTHELIA_SESSION_SECRET: ${GENERATED_SESSION_SECRET}\n AUTHELIA_STORAGE_ENCRYPTION_KEY: ${GENERATED_STORAGE_ENCRYPTION_KEY}\n PROXMENUX_ADMIN_PASSWORD: ${GENERATED_ADMIN_PASSWORD}\n PROXMENUX_AUTHELIA_COOKIE_DOMAIN: ${AUTHELIA_COOKIE_DOMAIN}\n PROXMENUX_AUTHELIA_URL: ${AUTHELIA_URL}\n X_AUTHELIA_CONFIG_FILTERS: template\n image: docker.io/authelia/authelia:4.39.28\n ports:\n - 9091:9091\n restart: unless-stopped\n volumes:\n - ./authelia:/config\n"
},
"first_run": {
"endpoints": [
{
"label": "Authelia Web UI",
"scheme": "http",
"port": 9091,
"path": "/",
"source": "official-image"
}
],
"credentials": [
{
"label": "Authelia administrator",
"type": "configured-or-installer-generated",
"username": "admin",
"password": null,
"password_environment": "PROXMENUX_ADMIN_PASSWORD",
"change_required": false,
"source": "Generated on first start and stored as an Argon2id hash in the persistent users file."
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 512,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 60
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"runtime": {
"compose_entrypoint": [
"/bin/sh",
"/usr/local/bin/proxmenux-authelia-bootstrap"
]
},
"generated_sensitive_environment": {
"PROXMENUX_ADMIN_PASSWORD": {
"strategy": "token-hex",
"bytes": 24,
"prompt": false
},
"AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"AUTHELIA_SESSION_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"AUTHELIA_STORAGE_ENCRYPTION_KEY": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
}
},
"minimum_secret_length": {
"PROXMENUX_ADMIN_PASSWORD": 24,
"AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET": 32,
"AUTHELIA_SESSION_SECRET": 32,
"AUTHELIA_STORAGE_ENCRYPTION_KEY": 32
},
"generated_files": [
{
"container_path": "/config/configuration.yml",
"mode": "0600",
"owner": "mapped-root",
"only_if_missing": true,
"content": "---\nserver:\n address: 'tcp://:9091'\n\nlog:\n level: 'info'\n\ntotp:\n issuer: 'Authelia'\n\nidentity_validation:\n reset_password:\n jwt_secret: 'configured-by-environment'\n\nauthentication_backend:\n file:\n path: '/config/users_database.yml'\n watch: true\n\naccess_control:\n default_policy: 'one_factor'\n\nsession:\n secret: 'configured-by-environment'\n cookies:\n - name: 'authelia_session'\n domain: '{{ env \"PROXMENUX_AUTHELIA_COOKIE_DOMAIN\" }}'\n authelia_url: '{{ env \"PROXMENUX_AUTHELIA_URL\" }}'\n expiration: '1 hour'\n inactivity: '5 minutes'\n\nstorage:\n encryption_key: 'configured-by-environment'\n local:\n path: '/config/db.sqlite3'\n\nnotifier:\n filesystem:\n filename: '/config/notification.txt'\n"
},
{
"container_path": "/usr/local/bin/proxmenux-authelia-bootstrap",
"mode": "0700",
"owner": "mapped-root",
"only_if_missing": false,
"content": "#!/bin/sh\nset -eu\numask 077\n\nusers_file=/config/users_database.yml\nif [ ! -s \"$users_file\" ]; then\n : \"${PROXMENUX_ADMIN_PASSWORD:?ProxMenux did not provide an initial administrator password}\"\n mkdir -p /config\n hash_output=$(authelia crypto hash generate argon2 --password \"$PROXMENUX_ADMIN_PASSWORD\" --no-confirm)\n password_hash=$(printf '%s\\n' \"$hash_output\" | sed -n 's/^Digest: //p')\n case \"$password_hash\" in\n '$argon2id$'*) ;;\n *) printf '%s\\n' 'Authelia did not return an Argon2id password hash' >&2; exit 1 ;;\n esac\n temporary_file=\"${users_file}.tmp.$$\"\n cat >\"$temporary_file\" <<EOF\nusers:\n admin:\n disabled: false\n displayname: 'Authelia Administrator'\n password: \"$password_hash\"\n groups:\n - 'admins'\nEOF\n chmod 0600 \"$temporary_file\"\n mv -f \"$temporary_file\" \"$users_file\"\nfi\nunset PROXMENUX_ADMIN_PASSWORD\nexec /app/entrypoint.sh \"$@\"\n"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 9091,
"path": "/api/health",
"timeout_seconds": 240,
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
}
},
"adaptations": [
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "The application listens on the same container ports at its dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Users open the LXC address instead of the Proxmox host address.",
"validation": "pending-per-application"
},
{
"id": "compose-environment-overlay",
"upstream_behavior": "Compose environment values override OCI image environment values.",
"native_lxc_behavior": "ProxMenux merges the same values into lxc.environment.runtime while the CT is stopped.",
"reason": "PVE imports image Env automatically; Compose values still need to override it.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "stop-grace-period",
"upstream_behavior": "Docker waits for Compose stop_grace_period before forcing termination.",
"native_lxc_behavior": "ProxMenux records the same timeout for its pct shutdown lifecycle operations.",
"reason": "Proxmox has no equivalent per-CT persistent restart-policy field; startup.down is not a shutdown timeout.",
"behavioral_impact": "Normal Proxmox node shutdown remains governed by the node-wide shutdown policy.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "pending-per-application"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "A single-image profile for the Authelia authentication portal. ProxMenux creates a unique initial administrator account; the local notifier and SQLite storage are kept in /config. Reverse-proxy trust and explicit access-control rules remain administrator settings."
},
"validation": {
"schema": "pending-local-validation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "replace-rootfs-from-new-oci-image-preserve-managed-volumes",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+453
View File
@@ -0,0 +1,453 @@
{
"schema_version": "0.4.0",
"kind": "proxmenux.oci-template",
"id": "image-authelia",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Authelia",
"es_ES": "Authelia"
},
"tagline": {
"en_US": "Single sign-on and multi-factor authentication",
"es_ES": "Inicio de sesión único y autenticación multifactor"
},
"description": {
"en_US": "An open-source authentication and authorization server for protecting web applications. This single-image profile provides a local SQLite database and file notifications; configure your domain, reverse proxy and access rules before protecting other services.",
"es_ES": "Servidor de autenticación y autorización de código abierto para proteger aplicaciones web. Este perfil de una sola imagen incluye una base de datos SQLite local y notificaciones en archivo; configura el dominio, el proxy inverso y las reglas de acceso antes de proteger otros servicios."
},
"category": "security",
"category_label": "Authentication & Security",
"author": "Authelia",
"developer": "Authelia",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/authelia.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 9091,
"path": "/"
},
"website": "https://www.authelia.com/",
"documentation": "https://www.authelia.com/integration/deployment/docker/",
"repository": "https://github.com/authelia/authelia",
"tips": [
"The installer creates a unique admin password and stores only its Argon2id hash in /config/users_database.yml. The password is shown in the installation result.",
"Authelia requires an HTTPS portal URL and a cookie domain matching that hostname. If you use Nginx Proxy Manager, follow the official integration guide and configure trusted proxies and forward-auth separately.",
"The default notifier writes messages to /config/notification.txt. Configure SMTP in /config/configuration.yml if you want email delivery.",
"The initial access-control policy is one_factor. Add explicit access-control rules before attaching Authelia to protected proxy hosts."
],
"mini_changelog": [],
"display_version": "4.39.28",
"updated_at": "2026-09-17"
},
"source": {
"provider": "authelia",
"repository": "https://github.com/authelia/authelia",
"default_branch": "master",
"revision": "8da42b2348b0351c6284a2940a9c5eec3d4cd3fd",
"readme_raw_url": "https://raw.githubusercontent.com/authelia/authelia/v4.39.28/examples/compose/lite/compose.yml",
"readme_pushed_at": "2026-09-17T12:13:30Z",
"compose_sha256": "848ce0f70e502981a050ac200d9d1882978a6c3b0f9f0dfcc6d52ce66ca37fb5",
"generated_at": "2026-11-03T09:10:57+00:00",
"image_repository_url": "https://hub.docker.com/r/authelia/authelia"
},
"container_contract": {
"service_name": "authelia",
"container_name": "authelia",
"image": {
"reference": "docker.io/authelia/authelia:4.39.28",
"registry": "docker.io",
"repository": "docker.io/authelia/authelia",
"tag": "4.39.28",
"digest": null,
"pull_policy": "resolve-selected-tag-to-architecture-digest-at-install"
},
"environment": [
{
"name": "PROXMENUX_ADMIN_PASSWORD",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-first-start"
},
{
"name": "AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "AUTHELIA_SESSION_SECRET",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "AUTHELIA_STORAGE_ENCRYPTION_KEY",
"example": "",
"required": true,
"sensitive": true,
"source": "proxmenux-generated"
},
{
"name": "X_AUTHELIA_CONFIG_FILTERS",
"example": "template",
"required": true,
"sensitive": false,
"source": "authelia-container"
},
{
"name": "PROXMENUX_AUTHELIA_COOKIE_DOMAIN",
"example": "",
"prompt": "Authelia session cookie domain for this portal (for example example.com)",
"required": true,
"sensitive": false,
"source": "administrator"
},
{
"name": "PROXMENUX_AUTHELIA_URL",
"example": "",
"prompt": "Public HTTPS URL used to open this Authelia portal (for example https://auth.example.com)",
"required": true,
"sensitive": false,
"source": "administrator"
}
],
"volumes": [
{
"id": "config",
"container_path": "/config",
"compose_source_example": "./authelia",
"read_only": false,
"required": true,
"installation_choice": [
"managed-volume"
],
"default": "managed-volume",
"managed_volume": {
"backup": true,
"default_size_gb": 4
}
}
],
"ports": [
{
"container_port": 9091,
"published_example": 9091,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "services:\n authelia:\n entrypoint:\n - /bin/sh\n - /usr/local/bin/proxmenux-authelia-bootstrap\n environment:\n AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET: ${GENERATED_RESET_PASSWORD_JWT_SECRET}\n AUTHELIA_SESSION_SECRET: ${GENERATED_SESSION_SECRET}\n AUTHELIA_STORAGE_ENCRYPTION_KEY: ${GENERATED_STORAGE_ENCRYPTION_KEY}\n PROXMENUX_ADMIN_PASSWORD: ${GENERATED_ADMIN_PASSWORD}\n PROXMENUX_AUTHELIA_COOKIE_DOMAIN: ${AUTHELIA_COOKIE_DOMAIN}\n PROXMENUX_AUTHELIA_URL: ${AUTHELIA_URL}\n X_AUTHELIA_CONFIG_FILTERS: template\n image: docker.io/authelia/authelia:4.39.28\n ports:\n - 9091:9091\n restart: unless-stopped\n volumes:\n - ./authelia:/config\n"
},
"first_run": {
"endpoints": [
{
"label": "Authelia Web UI",
"scheme": "http",
"port": 9091,
"path": "/",
"source": "official-image"
}
],
"credentials": [
{
"label": "Authelia administrator",
"type": "configured-or-installer-generated",
"username": "admin",
"password": null,
"password_environment": "PROXMENUX_ADMIN_PASSWORD",
"change_required": false,
"source": "Generated on first start and stored as an Argon2id hash in the persistent users file."
}
]
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 512,
"swap_mb": 512,
"rootfs_size_gb": 8,
"rootfs_storage": "local-lvm",
"volume_storage": "local-lvm",
"template_storage": "local",
"bridge": "vmbr0",
"ipv4": "dhcp",
"firewall": true,
"host_managed_network": true,
"onboot": false,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 60
},
"image_metadata_policy": {
"entrypoint": "import-from-oci-image",
"cmd": "import-from-oci-image",
"environment": "import-image-env-then-apply-compose-overrides",
"user": "import-from-oci-image",
"working_dir": "import-from-oci-image",
"stop_signal": "import-from-oci-image"
},
"installer_profile": {
"runtime": {
"compose_entrypoint": [
"/bin/sh",
"/usr/local/bin/proxmenux-authelia-bootstrap"
]
},
"generated_sensitive_environment": {
"PROXMENUX_ADMIN_PASSWORD": {
"strategy": "token-hex",
"bytes": 24,
"prompt": false
},
"AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"AUTHELIA_SESSION_SECRET": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
},
"AUTHELIA_STORAGE_ENCRYPTION_KEY": {
"strategy": "token-hex",
"bytes": 32,
"prompt": false
}
},
"minimum_secret_length": {
"PROXMENUX_ADMIN_PASSWORD": 24,
"AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET": 32,
"AUTHELIA_SESSION_SECRET": 32,
"AUTHELIA_STORAGE_ENCRYPTION_KEY": 32
},
"generated_files": [
{
"container_path": "/config/configuration.yml",
"mode": "0600",
"owner": "mapped-root",
"only_if_missing": true,
"content": "---\nserver:\n address: 'tcp://:9091'\n\nlog:\n level: 'info'\n\ntotp:\n issuer: 'Authelia'\n\nidentity_validation:\n reset_password:\n jwt_secret: 'configured-by-environment'\n\nauthentication_backend:\n file:\n path: '/config/users_database.yml'\n watch: true\n\naccess_control:\n default_policy: 'one_factor'\n\nsession:\n secret: 'configured-by-environment'\n cookies:\n - name: 'authelia_session'\n domain: '{{ env \"PROXMENUX_AUTHELIA_COOKIE_DOMAIN\" }}'\n authelia_url: '{{ env \"PROXMENUX_AUTHELIA_URL\" }}'\n expiration: '1 hour'\n inactivity: '5 minutes'\n\nstorage:\n encryption_key: 'configured-by-environment'\n local:\n path: '/config/db.sqlite3'\n\nnotifier:\n filesystem:\n filename: '/config/notification.txt'\n"
},
{
"container_path": "/usr/local/bin/proxmenux-authelia-bootstrap",
"mode": "0700",
"owner": "mapped-root",
"only_if_missing": false,
"content": "#!/bin/sh\nset -eu\numask 077\n\nusers_file=/config/users_database.yml\nif [ ! -s \"$users_file\" ]; then\n : \"${PROXMENUX_ADMIN_PASSWORD:?ProxMenux did not provide an initial administrator password}\"\n mkdir -p /config\n hash_output=$(authelia crypto hash generate argon2 --password \"$PROXMENUX_ADMIN_PASSWORD\" --no-confirm)\n password_hash=$(printf '%s\\n' \"$hash_output\" | sed -n 's/^Digest: //p')\n case \"$password_hash\" in\n '$argon2id$'*) ;;\n *) printf '%s\\n' 'Authelia did not return an Argon2id password hash' >&2; exit 1 ;;\n esac\n temporary_file=\"${users_file}.tmp.$$\"\n cat >\"$temporary_file\" <<EOF\nusers:\n admin:\n disabled: false\n displayname: 'Authelia Administrator'\n password: \"$password_hash\"\n groups:\n - 'admins'\nEOF\n chmod 0600 \"$temporary_file\"\n mv -f \"$temporary_file\" \"$users_file\"\nfi\nunset PROXMENUX_ADMIN_PASSWORD\nexec /app/entrypoint.sh \"$@\"\n"
}
],
"startup_healthcheck": {
"scheme": "http",
"port": 9091,
"path": "/api/health",
"timeout_seconds": 240,
"request_timeout_seconds": 10,
"stability_seconds": 4,
"verify_tls": true
}
},
"adaptations": [
{
"id": "dedicated-lxc-network",
"upstream_behavior": "Docker publishes selected container ports on the Docker host.",
"native_lxc_behavior": "The application listens on the same container ports at its dedicated LXC address.",
"reason": "A native LXC has its own address and does not require Docker port NAT.",
"behavioral_impact": "Users open the LXC address instead of the Proxmox host address.",
"validation": "pending-per-application"
},
{
"id": "compose-environment-overlay",
"upstream_behavior": "Compose environment values override OCI image environment values.",
"native_lxc_behavior": "ProxMenux merges the same values into lxc.environment.runtime while the CT is stopped.",
"reason": "PVE imports image Env automatically; Compose values still need to override it.",
"behavioral_impact": "None expected.",
"validation": "pending-per-application"
},
{
"id": "stop-grace-period",
"upstream_behavior": "Docker waits for Compose stop_grace_period before forcing termination.",
"native_lxc_behavior": "ProxMenux records the same timeout for its pct shutdown lifecycle operations.",
"reason": "Proxmox has no equivalent per-CT persistent restart-policy field; startup.down is not a shutdown timeout.",
"behavioral_impact": "Normal Proxmox node shutdown remains governed by the node-wide shutdown policy.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-shm-size",
"upstream_behavior": "Compose sets the size of the container /dev/shm tmpfs.",
"native_lxc_behavior": "ProxMenux mounts a native LXC tmpfs at /dev/shm with the same requested capacity.",
"reason": "The OCI image runs directly as an LXC and therefore needs the equivalent Proxmox mount entry.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-command",
"upstream_behavior": "Compose replaces the image Cmd while retaining its Entrypoint.",
"native_lxc_behavior": "ProxMenux reads the official OCI Entrypoint and combines it with the Compose command as the native LXC init command.",
"reason": "Proxmox stores the effective OCI process as one entrypoint string.",
"behavioral_impact": "None expected.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-process-runtime",
"upstream_behavior": "Compose can replace Entrypoint, User and WorkingDir and request an init process or interactive terminal.",
"native_lxc_behavior": "ProxMenux applies the process overrides through native LXC init directives; lxc-init provides PID 1 supervision and the CT console provides terminal access.",
"reason": "The OCI process must start with the same identity, command and working directory without Docker.",
"behavioral_impact": "Compose stdin_open and tty become access through the Proxmox LXC console.",
"validation": "pending-per-application"
},
{
"id": "compose-healthcheck",
"upstream_behavior": "Docker periodically executes the declared container healthcheck.",
"native_lxc_behavior": "For a single-service LXC, ProxMenux translates HTTP localhost checks into a mandatory first-start service check.",
"reason": "Proxmox has no persistent Docker health state, while the installer still must detect a failed first boot.",
"behavioral_impact": "The check runs during installation rather than continuously after installation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-cpu-priority",
"upstream_behavior": "Docker cpu_shares sets a relative scheduling weight with 1024 as its neutral value.",
"native_lxc_behavior": "ProxMenux converts the relative weight to Proxmox cpuunits with 100 as its neutral value and lets the user review it.",
"reason": "Both settings express relative CPU priority on different scales.",
"behavioral_impact": "Rounding and Proxmox minimum limits can slightly change very low weights.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-resource-limits",
"upstream_behavior": "mem_limit sets the memory ceiling; ulimits sets process soft/hard resource limits.",
"native_lxc_behavior": "mem_limit supplies the editable Proxmox memory default, rounded up to MiB; ulimits maps to lxc.prlimit with -1 represented as unlimited.",
"reason": "Use native Proxmox memory and LXC prlimits, without a wrapper or changing the host kernel configuration.",
"behavioral_impact": "User-selected memory overrides Compose. Swap is a separate choice. Kernel restrictions still apply; nproc counts processes by real UID, not by container.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-identity",
"upstream_behavior": "Compose can set hostname, MAC address, extra hosts and attach a service to Docker networks.",
"native_lxc_behavior": "ProxMenux applies hostname and MAC to net0, writes additional host aliases into the LXC and uses its dedicated bridge connection for single-service networks.",
"reason": "A dedicated LXC has its own network namespace and does not need a Docker bridge per service.",
"behavioral_impact": "host-gateway resolves to the IPv4 address of the selected Proxmox bridge.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-network-mode",
"upstream_behavior": "Docker host mode removes Docker network isolation; bridge and default use a Docker-managed network.",
"native_lxc_behavior": "The OCI process uses the dedicated LXC network namespace directly, so host, bridge and default all listen on the LXC address without Docker NAT.",
"reason": "The LXC is the application host and already has its own address and port namespace.",
"behavioral_impact": "host means the LXC host, never the Proxmox host; this preserves Proxmox network isolation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-capabilities-and-sysctls",
"upstream_behavior": "Compose can add Linux capabilities and set kernel parameters in the container network namespace.",
"native_lxc_behavior": "ProxMenux validates requested capabilities against the native LXC capability set and writes namespaced network settings as lxc.sysctl directives.",
"reason": "A native OCI-LXC already starts with the namespaced capability set; lxc.cap.keep would incorrectly discard unrelated required capabilities.",
"behavioral_impact": "Host-global capabilities such as SYS_MODULE remain blocked until their host prerequisite is explicitly adapted.",
"validation": "not-requested-by-compose"
},
{
"id": "docker-engine-metadata",
"upstream_behavior": "Compose labels annotate Docker objects and the json-file logging driver rotates Docker-managed logs.",
"native_lxc_behavior": "Labels remain source metadata; Docker json-file settings are not applied because the OCI process runs directly under LXC.",
"reason": "There is no Docker object or Docker json-file log behind a native OCI-LXC application.",
"behavioral_impact": "Docker-only label consumers and Docker log-driver rotation do not exist in the native deployment.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-device-passthrough",
"upstream_behavior": "Compose passes host character devices or requests an NVIDIA runtime GPU.",
"native_lxc_behavior": "ProxMenux converts recognized device declarations to native Proxmox dev resources; NVIDIA profiles also inject compatible host driver libraries read-only.",
"reason": "Native OCI-LXC does not execute Docker device or NVIDIA runtime hooks.",
"behavioral_impact": "Hardware is exposed only after explicit user confirmation and host-path validation.",
"validation": "not-requested-by-compose"
},
{
"id": "compose-host-ipc",
"upstream_behavior": "ipc: host shares the Docker host IPC namespace, commonly to avoid Docker's small default shared-memory allocation.",
"native_lxc_behavior": "The application keeps the LXC IPC namespace and receives a configurable 1 GiB /dev/shm instead of sharing Proxmox host IPC.",
"reason": "Processes in a single native LXC already share one IPC namespace; retaining isolation is safer than exposing host IPC.",
"behavioral_impact": "The application cannot exchange IPC objects with processes on the Proxmox host.",
"validation": "not-requested-by-compose"
}
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"devices",
"entrypoint",
"environment",
"extra_hosts",
"group_add",
"healthcheck",
"hostname",
"image",
"init",
"ipc",
"labels",
"logging",
"mac_address",
"mem_limit",
"network_mode",
"networks",
"ports",
"privileged",
"restart",
"runtime",
"security_opt",
"shm_size",
"stdin_open",
"stop_grace_period",
"stop_signal",
"sysctls",
"tty",
"ulimits",
"user",
"volumes",
"working_dir"
],
"untranslated_blockers": [],
"policy": "A single-image profile for the Authelia authentication portal. ProxMenux creates a unique initial administrator account; the local notifier and SQLite storage are kept in /config. Reverse-proxy trust and explicit access-control rules remain administrator settings."
},
"validation": {
"schema": "pending-local-validation",
"clean_install": "pending",
"service_health": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending"
},
"lifecycle": {
"update_strategy": "replace-rootfs-from-new-oci-image-preserve-managed-volumes",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": null,
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-latest-image-digest",
"automatic_unattended_updates": false
}
}
+32
View File
@@ -18733,6 +18733,38 @@
"requires_security_confirmation": false,
"hidden": true,
"template_id": "image-ztnet"
},
{
"id": "authelia",
"provider": "authelia",
"template_family": "curated-profile",
"title": "Authelia",
"repository": "https://github.com/authelia/authelia",
"description": "An open-source authentication and authorization server for protecting web applications. This single-image profile provides a local SQLite database and file notifications; configure your domain, reverse proxy and access rules before protecting other services.",
"website": "https://www.authelia.com/",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/authelia.webp",
"architectures": [
"amd64",
"arm64"
],
"updated_at": "2026-09-17",
"main_image": "docker.io/authelia/authelia:4.39.28",
"category": "security",
"category_label": "Authentication & Security",
"replaces_discovered_ids": [],
"curated_path": "catalog/curated/authelia.json",
"template": "apps/authelia.json",
"template_status": "generated-unvalidated",
"automatic_install_candidate": true,
"untranslated_blockers": [],
"requires_privileged_lxc": false,
"optional_privileged_lxc": false,
"requires_host_pid_namespace": false,
"requires_relaxed_confinement": false,
"optional_relaxed_confinement": false,
"requires_security_confirmation": false,
"hidden": false,
"template_id": "image-authelia"
}
],
"discovery": {
+3
View File
@@ -22,6 +22,9 @@
"authentik": {
"status": "laboratory-validated"
},
"authelia": {
"status": "laboratory-validated"
},
"chromium": {
"status": "laboratory-validated"
},
+99
View File
@@ -0,0 +1,99 @@
"""The Authelia profile bootstraps a usable single-image authentication portal."""
import json
from pathlib import Path
import sys
import unittest
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src"))
from proxmenux_oci.catalog import Catalog
class AutheliaRecipeTests(unittest.TestCase):
def setUp(self):
self.path = ROOT / "catalog/curated/authelia.json"
self.recipe = json.loads(self.path.read_text(encoding="utf-8"))
self.index_copy = json.loads(
(ROOT / "catalog/apps/authelia.json").read_text(encoding="utf-8")
)
self.profile = self.recipe["proxmox"]["installer_profile"]
self.generated = {
item["container_path"]: item
for item in self.profile["generated_files"]
}
def test_local_catalog_lists_and_loads_the_curated_recipe(self):
catalog = Catalog(ROOT)
item = catalog.find_item("authelia")
self.assertEqual(item["template_family"], "curated-profile")
self.assertEqual(catalog.compose("authelia")["id"], "image-authelia")
self.assertEqual(self.recipe, self.index_copy)
def test_official_image_tag_icon_and_supported_architectures_are_declared(self):
self.assertEqual(
self.recipe["container_contract"]["image"]["reference"],
"docker.io/authelia/authelia:4.39.28",
)
self.assertEqual(self.recipe["catalog_ui"]["architectures"], ["amd64", "arm64"])
self.assertEqual(
self.recipe["catalog_ui"]["icon"],
"https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/authelia.webp",
)
def test_sensitive_secrets_are_generated_and_domain_settings_are_prompted(self):
environment = {
item["name"]: item
for item in self.recipe["container_contract"]["environment"]
}
for name in (
"PROXMENUX_ADMIN_PASSWORD",
"AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET",
"AUTHELIA_SESSION_SECRET",
"AUTHELIA_STORAGE_ENCRYPTION_KEY",
):
self.assertTrue(environment[name]["sensitive"])
self.assertEqual(self.profile["generated_sensitive_environment"][name]["strategy"], "token-hex")
self.assertTrue(environment["PROXMENUX_AUTHELIA_COOKIE_DOMAIN"]["required"])
self.assertTrue(environment["PROXMENUX_AUTHELIA_URL"]["required"])
self.assertIn("cookie domain", environment["PROXMENUX_AUTHELIA_COOKIE_DOMAIN"]["prompt"])
self.assertIn("HTTPS URL", environment["PROXMENUX_AUTHELIA_URL"]["prompt"])
self.assertEqual(environment["PROXMENUX_AUTHELIA_COOKIE_DOMAIN"]["example"], "")
self.assertEqual(environment["PROXMENUX_AUTHELIA_URL"]["example"], "")
self.assertEqual(environment["X_AUTHELIA_CONFIG_FILTERS"]["example"], "template")
def test_config_is_persistent_and_has_a_working_initial_policy(self):
config = self.generated["/config/configuration.yml"]["content"]
self.assertIn("path: '/config/users_database.yml'", config)
self.assertIn("path: '/config/db.sqlite3'", config)
self.assertIn("filename: '/config/notification.txt'", config)
self.assertIn("default_policy: 'one_factor'", config)
self.assertIn('{{ env \"PROXMENUX_AUTHELIA_COOKIE_DOMAIN\" }}', config)
self.assertIn('{{ env \"PROXMENUX_AUTHELIA_URL\" }}', config)
self.assertTrue(self.generated["/config/configuration.yml"]["only_if_missing"])
volume = self.recipe["container_contract"]["volumes"][0]
self.assertEqual(volume["container_path"], "/config")
self.assertEqual(volume["installation_choice"], ["managed-volume"])
self.assertTrue(volume["managed_volume"]["backup"])
def test_bootstrap_hashes_initial_password_and_never_ships_a_default_password(self):
bootstrap = self.generated["/usr/local/bin/proxmenux-authelia-bootstrap"]["content"]
self.assertIn("authelia crypto hash generate argon2", bootstrap)
self.assertIn("unset PROXMENUX_ADMIN_PASSWORD", bootstrap)
self.assertIn("exec /app/entrypoint.sh", bootstrap)
self.assertNotIn("password: authelia", bootstrap)
self.assertEqual(
self.recipe["first_run"]["credentials"][0]["password_environment"],
"PROXMENUX_ADMIN_PASSWORD",
)
def test_healthcheck_uses_authelias_documented_endpoint_and_profile_remains_unvalidated(self):
healthcheck = self.profile["startup_healthcheck"]
self.assertEqual((healthcheck["port"], healthcheck["path"]), (9091, "/api/health"))
self.assertFalse(self.recipe["compatibility"]["validated"])
self.assertEqual(self.recipe["status"], "generated-unvalidated")
if __name__ == "__main__":
unittest.main()