Merge pull request #563 from jcastro/feature/oci-authentik

Add Authentik to OCI catalog
This commit is contained in:
MacRimi
2026-10-31 09:53:15 +01:00
committed by GitHub
8 changed files with 1500 additions and 7 deletions
+640
View File
@@ -0,0 +1,640 @@
{
"schema_version": "0.5.0",
"kind": "proxmenux.oci-template",
"id": "image-authentik",
"status": "generated-unvalidated",
"catalog_ui": {
"title": {
"en_US": "Authentik"
},
"tagline": {
"en_US": "Identity provider for single sign-on and access control"
},
"description": {
"en_US": "Authentik is an open-source identity provider and access platform. This recipe follows the official three-service deployment with PostgreSQL, the server and a worker, each in its own Proxmox OCI LXC."
},
"category": "security",
"category_label": "Authentication & Security",
"author": "Authentik",
"developer": "Authentik",
"icon": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/authentik.webp",
"thumbnail": null,
"screenshots": [],
"architectures": [
"amd64",
"arm64"
],
"launch": {
"scheme": "http",
"port": 9000,
"path": "/"
},
"website": "https://goauthentik.io/",
"documentation": "https://docs.goauthentik.io/install-config/install/docker-compose/",
"repository": "https://github.com/goauthentik/authentik",
"tips": [
"The server and worker share /data and /templates through host directories; those directories are not included in Proxmox CT backups.",
"The worker Docker-socket mount is omitted. Use the embedded outpost or deploy and manage a separate outpost manually.",
"The worker gets an interface on the selected Proxmox bridge for outbound access; PostgreSQL stays on the private stack network."
],
"mini_changelog": [],
"display_version": "2026.8.5",
"updated_at": "2026-10-21"
},
"source": {
"provider": "goauthentik",
"repository": "https://github.com/goauthentik/authentik",
"default_branch": "main",
"revision": "4ec0d19b98da3c329781894cd550da95d3033954",
"readme_raw_url": "https://goauthentik.io/version/2026.8/lifecycle/container/compose.yml",
"image_repository_url": "https://github.com/goauthentik/authentik/pkgs/container/server",
"readme_pushed_at": "2026-10-21T12:57:59Z",
"compose_sha256": "a3e138b5a85844d15c4a7ba6339997e43c0479d9d198582c67dd19523aadc694",
"generated_at": "2026-10-30T18:09:01+00:00"
},
"container_contract": {
"service_name": "server",
"container_name": "authentik-server",
"image": {
"reference": "ghcr.io/goauthentik/server:2026.8.5",
"registry": "ghcr.io",
"repository": "ghcr.io/goauthentik/server",
"tag": "2026.8.5",
"digest": null,
"pull_policy": "resolve-written-reference-to-architecture-digest-at-install"
},
"environment": [
{
"name": "AUTHENTIK_POSTGRESQL__HOST",
"example": "postgresql",
"required": true,
"sensitive": false,
"source": "docker-compose"
},
{
"name": "AUTHENTIK_POSTGRESQL__NAME",
"example": "authentik",
"required": true,
"sensitive": false,
"source": "docker-compose"
},
{
"name": "AUTHENTIK_POSTGRESQL__PASSWORD",
"example": "${GENERATED_GENERATED_PG_PASS}",
"required": true,
"sensitive": true,
"source": "docker-compose"
},
{
"name": "AUTHENTIK_POSTGRESQL__USER",
"example": "authentik",
"required": true,
"sensitive": false,
"source": "docker-compose"
},
{
"name": "AUTHENTIK_SECRET_KEY",
"example": "${GENERATED_GENERATED_AUTHENTIK_SECRET_KEY}",
"required": true,
"sensitive": true,
"source": "docker-compose"
}
],
"volumes": [
{
"id": "volume-0",
"container_path": "/data",
"compose_source_example": "./data",
"read_only": false,
"required": true,
"installation_choice": [
"host-bind"
],
"default": "host-bind",
"managed_volume": {
"backup": false,
"default_size_gb": 8
}
},
{
"id": "volume-1",
"container_path": "/templates",
"compose_source_example": "./custom-templates",
"read_only": false,
"required": true,
"installation_choice": [
"host-bind"
],
"default": "host-bind",
"managed_volume": {
"backup": false,
"default_size_gb": 8
}
}
],
"ports": [
{
"container_port": 9000,
"published_example": 9000,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
},
{
"container_port": 9443,
"published_example": 9443,
"protocol": "tcp",
"required": true,
"proxmox_behavior": "listener-on-dedicated-lxc-address-no-nat"
}
],
"related_services": [
{
"name": "postgresql",
"image": "docker.io/library/postgres:16-alpine"
},
{
"name": "worker",
"image": "ghcr.io/goauthentik/server:2026.8.5"
}
],
"restart": "unless-stopped",
"stop_grace_period": null,
"original_compose": "name: authentik\nservices:\n postgresql:\n environment:\n POSTGRES_DB: authentik\n POSTGRES_PASSWORD: ${GENERATED_PG_PASS}\n POSTGRES_USER: authentik\n healthcheck:\n interval: 30s\n retries: 5\n start_period: 20s\n test:\n - CMD-SHELL\n - pg_isready -h 127.0.0.1 -d authentik -U authentik\n timeout: 5s\n image: docker.io/library/postgres:16-alpine\n restart: unless-stopped\n volumes:\n - read_only: false\n source: database\n target: /var/lib/postgresql/data\n server:\n command: server\n depends_on:\n postgresql:\n condition: service_healthy\n environment:\n AUTHENTIK_POSTGRESQL__HOST: postgresql\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${GENERATED_PG_PASS}\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_SECRET_KEY: ${GENERATED_AUTHENTIK_SECRET_KEY}\n image: ghcr.io/goauthentik/server:2026.8.5\n ports:\n - 9000:9000\n - 9443:9443\n restart: unless-stopped\n shm_size: 512mb\n volumes:\n - read_only: false\n source: ./data\n target: /data\n - read_only: false\n source: ./custom-templates\n target: /templates\n worker:\n command: worker\n depends_on:\n postgresql:\n condition: service_healthy\n environment:\n AUTHENTIK_POSTGRESQL__HOST: postgresql\n AUTHENTIK_POSTGRESQL__NAME: authentik\n AUTHENTIK_POSTGRESQL__PASSWORD: ${GENERATED_PG_PASS}\n AUTHENTIK_POSTGRESQL__USER: authentik\n AUTHENTIK_SECRET_KEY: ${GENERATED_AUTHENTIK_SECRET_KEY}\n image: ghcr.io/goauthentik/server:2026.8.5\n restart: unless-stopped\n shm_size: 512mb\n user: root\n volumes:\n - read_only: false\n source: ./data\n target: /data\n - read_only: false\n source: ./certs\n target: /certs\n - read_only: false\n source: ./custom-templates\n target: /templates\nvolumes:\n database: {}\n"
},
"compose_stack": {
"project_name": "authentik",
"deployment_model": "one-native-oci-lxc-per-compose-service",
"user_experience": "single-application-install",
"main_service": "server",
"service_count": 3,
"services": [
{
"name": "postgresql",
"image": "docker.io/library/postgres:16-alpine",
"is_main": false,
"role": "dependency",
"vmid_offset": 1,
"depends_on": [],
"frontend_network": false,
"private_network": true,
"compose": {
"environment": {
"POSTGRES_DB": "authentik",
"POSTGRES_PASSWORD": "${GENERATED_PG_PASS}",
"POSTGRES_USER": "authentik"
},
"healthcheck": {
"interval": "30s",
"retries": 5,
"start_period": "20s",
"test": [
"CMD-SHELL",
"pg_isready -h 127.0.0.1 -d authentik -U authentik"
],
"timeout": "5s"
},
"image": "docker.io/library/postgres:16-alpine",
"restart": "unless-stopped",
"volumes": [
{
"source": "database",
"target": "/var/lib/postgresql/data",
"read_only": false
}
]
}
},
{
"name": "worker",
"image": "ghcr.io/goauthentik/server:2026.8.5",
"is_main": false,
"role": "dependency",
"vmid_offset": 2,
"depends_on": [
"postgresql"
],
"frontend_network": true,
"private_network": true,
"compose": {
"command": "worker",
"depends_on": {
"postgresql": {
"condition": "service_healthy"
}
},
"environment": {
"AUTHENTIK_POSTGRESQL__HOST": "postgresql",
"AUTHENTIK_POSTGRESQL__NAME": "authentik",
"AUTHENTIK_POSTGRESQL__PASSWORD": "${GENERATED_PG_PASS}",
"AUTHENTIK_POSTGRESQL__USER": "authentik",
"AUTHENTIK_SECRET_KEY": "${GENERATED_AUTHENTIK_SECRET_KEY}"
},
"image": "ghcr.io/goauthentik/server:2026.8.5",
"restart": "unless-stopped",
"shm_size": "512mb",
"user": "root",
"volumes": [
{
"source": "./data",
"target": "/data",
"read_only": false
},
{
"source": "./certs",
"target": "/certs",
"read_only": false
},
{
"source": "./custom-templates",
"target": "/templates",
"read_only": false
}
]
}
},
{
"name": "server",
"image": "ghcr.io/goauthentik/server:2026.8.5",
"is_main": true,
"role": "frontend",
"vmid_offset": 0,
"depends_on": [
"postgresql"
],
"frontend_network": true,
"private_network": true,
"compose": {
"command": "server",
"depends_on": {
"postgresql": {
"condition": "service_healthy"
}
},
"environment": {
"AUTHENTIK_POSTGRESQL__HOST": "postgresql",
"AUTHENTIK_POSTGRESQL__NAME": "authentik",
"AUTHENTIK_POSTGRESQL__PASSWORD": "${GENERATED_PG_PASS}",
"AUTHENTIK_POSTGRESQL__USER": "authentik",
"AUTHENTIK_SECRET_KEY": "${GENERATED_AUTHENTIK_SECRET_KEY}"
},
"image": "ghcr.io/goauthentik/server:2026.8.5",
"ports": [
"9000:9000",
"9443:9443"
],
"restart": "unless-stopped",
"shm_size": "512mb",
"volumes": [
{
"source": "./data",
"target": "/data",
"read_only": false
},
{
"source": "./custom-templates",
"target": "/templates",
"read_only": false
}
]
}
}
],
"top_level": {
"name": "authentik",
"volumes": {
"database": {}
}
},
"networking": {
"frontend": "selected-proxmox-bridge",
"private_required": true,
"private_creation": "automatic-create-if-missing",
"private_address_allocation": "automatic-static-address-per-service",
"service_discovery": "private-addresses-with-compose-service-host-aliases",
"dependency_external_access": "worker-through-selected-proxmox-bridge; postgresql-private-only",
"prompt_user_for_private_network": false
},
"storage": [
{
"id": "postgresql-volume-0",
"service": "postgresql",
"container_path": "/var/lib/postgresql/data",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "server-volume-0",
"service": "server",
"container_path": "/data",
"mode": "host-bind",
"user_selectable": true,
"backup": false,
"shared_with_other_lxc": true,
"source_path": null,
"source_path_prompt": "Host directory for authentik:/data"
},
{
"id": "server-volume-1",
"service": "server",
"container_path": "/templates",
"mode": "host-bind",
"user_selectable": true,
"backup": false,
"shared_with_other_lxc": true,
"source_path": null,
"source_path_prompt": "Host directory for authentik:/templates"
},
{
"id": "worker-volume-0",
"service": "worker",
"container_path": "/data",
"mode": "host-bind",
"user_selectable": true,
"backup": false,
"shared_with_other_lxc": true,
"source_path": null,
"source_path_prompt": "Host directory for authentik:/data"
},
{
"id": "worker-volume-1",
"service": "worker",
"container_path": "/certs",
"mode": "managed-volume",
"user_selectable": false,
"backup": true,
"shared_with_other_lxc": false,
"source_path": null,
"source_path_prompt": null
},
{
"id": "worker-volume-2",
"service": "worker",
"container_path": "/templates",
"mode": "host-bind",
"user_selectable": true,
"backup": false,
"shared_with_other_lxc": true,
"source_path": null,
"source_path_prompt": "Host directory for authentik:/templates"
}
],
"orchestration": {
"reserve_vmids_atomically": 3,
"start_order": [
"postgresql",
"worker",
"server"
],
"stop_order": [
"server",
"worker",
"postgresql"
],
"dependency_readiness": "compose-healthcheck-then-port-or-process-fallback",
"rollback_on_failure": "remove-new-rootfs-preserve-created-persistent-volumes"
},
"installer_inputs": {
"prompted": [
"stack_name",
"base_vmid",
"rootfs_storage",
"persistent_data_destinations",
"frontend_bridge",
"frontend_ipv4_mode"
],
"automatic": [
"dependent_vmids",
"private_bridge",
"private_subnet",
"private_service_addresses",
"compose_service_aliases",
"generated_secrets",
"dependency_start_and_stop_order"
],
"generated_secrets": [
{
"id": "pg-pass",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "postgresql",
"environment_variable": "POSTGRES_PASSWORD"
},
{
"service": "server",
"environment_variable": "AUTHENTIK_POSTGRESQL__PASSWORD"
},
{
"service": "worker",
"environment_variable": "AUTHENTIK_POSTGRESQL__PASSWORD"
}
]
},
{
"id": "authentik-secret-key",
"strategy": "generate-cryptographically-random-at-install",
"bindings": [
{
"service": "server",
"environment_variable": "AUTHENTIK_SECRET_KEY"
},
{
"service": "worker",
"environment_variable": "AUTHENTIK_SECRET_KEY"
}
]
}
]
}
},
"first_run": {
"endpoints": [
{
"label": "Web interface",
"scheme": "http",
"port": 9000,
"path": "/",
"source": "official-compose"
}
],
"credentials": []
},
"proxmox": {
"runtime": "native-oci-lxc",
"technology_status": "proxmox-technology-preview",
"defaults": {
"unprivileged": true,
"ostype": "auto-from-image",
"cores": 2,
"memory_mb": 1024,
"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": true,
"features": [
"nesting=1"
],
"shutdown_timeout_seconds": 30
},
"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": {
"stack_driver": "generic-multi-lxc-stack",
"volume_preparations": [
{
"container_path": "/data",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/templates",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/certs",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
},
{
"container_path": "/var/lib/postgresql/data",
"remove_lost_found": true,
"owner_strategy": "mapped-application-user",
"only_when_mount_type": "managed-volume"
}
]
},
"adaptations": [
{
"id": "worker-docker-socket-removed",
"upstream_behavior": "The official Compose mounts the Docker socket into the worker for automatic deployment and management of separate outposts.",
"native_lxc_behavior": "The Docker socket mount is omitted. Authentik itself runs as server, PostgreSQL and worker in native OCI LXCs.",
"reason": "The ProxMenux native OCI stack does not run Docker Engine or provide a Docker daemon socket.",
"behavioral_impact": "Use the embedded outpost for a simple proxy-provider deployment, or deploy and manage an outpost separately.",
"validation": "passed-ms03-2026-10-30"
},
{
"id": "postgres-healthcheck-normalized",
"upstream_behavior": "The official PostgreSQL healthcheck expands Compose environment variables in its command.",
"native_lxc_behavior": "The check uses the recipe’s fixed database and username with pg_isready against localhost.",
"reason": "The native stack healthcheck runs in the database LXC and does not evaluate Compose variable interpolation.",
"behavioral_impact": "It checks the same local database readiness before dependent services start.",
"validation": "passed-ms03-postgresql-readiness-2026-10-30"
},
{
"id": "server-worker-shared-data",
"upstream_behavior": "Authentik server and worker both mount /data and /templates from the same Compose source directories.",
"native_lxc_behavior": "ProxMenux uses shared host directories for these two paths across the server and worker LXCs.",
"reason": "The same data and custom templates must be visible to both services; the stack driver shares named Compose sources through host paths.",
"behavioral_impact": "These shared host directories are not included in native LXC backups and need a separate backup.",
"validation": "passed-ms03-2026-10-30"
}
],
"custom_compose_stack": true,
"custom_compose_interpolated": false,
"stack_image_entrypoints": {},
"stack_completion_notes": [
"Open the web address and create the password of the akadmin user in the first-run setup."
]
},
"compatibility": {
"automatic_install_candidate": true,
"validated": false,
"supported_compose_keys": [
"cap_add",
"command",
"container_name",
"cpu_shares",
"deploy",
"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": "Official Authentik Compose translated to three native OCI LXCs. The Docker socket mount is deliberately removed; the embedded outpost remains available."
},
"validation": {
"schema": "passed-local-2026-10-30",
"image_pull": "passed-ms03-skopeo-and-OCI-integrity-server-worker-postgresql-2026-10-30",
"default_install": "passed-ms03-three-LXCs-started-PostgreSQL-healthy-2026-10-30",
"advanced_install": "pending",
"credentials": "pending-user-first-run-and-login",
"web_ui": "pending-user-first-run-and-login",
"storage_modes": "pending",
"restart_persistence": "pending",
"backup_restore": "pending",
"update_preserves_data": "pending",
"rollback": "pending",
"modification": "pending",
"removal": "pending",
"oci_engine_tests": "pending",
"offline_i18n_tests": "pending",
"runtime_architecture": "amd64-ms03; Skopeo manifests include amd64-and-arm64",
"database_health": "passed-pg_isready-2026-10-30"
},
"lifecycle": {
"update_strategy": "resolve-selected-tag-and-architecture-digest-then-apply-reviewed-native-lxc-update",
"registry_state": {
"resolved_architecture": null,
"resolved_digest": null,
"image_version_label": "2026.8.5",
"image_created": null
},
"change_detection": "compare-compose-sha256-and-resolved-image-digest",
"automatic_unattended_updates": false,
"dependency_lifecycle": {
"implementation": "proxmox-hookscript",
"trigger": "main-lxc-pre-start",
"waits_for_dependency_healthchecks": true,
"stops_dependencies_with_main": false
}
}
}