name: assetmanager services: db: image: postgres:16-alpine container_name: assetmanager-db restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-assetmanager} POSTGRES_USER: ${POSTGRES_USER:-assetmanager} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change-me} volumes: - ./data/postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-assetmanager} -d ${POSTGRES_DB:-assetmanager}"] interval: 5s timeout: 5s retries: 10 app: build: . container_name: assetmanager-app restart: unless-stopped depends_on: db: condition: service_healthy environment: DATABASE_URL: postgresql+psycopg://${POSTGRES_USER:-assetmanager}:${POSTGRES_PASSWORD:-change-me}@db:5432/${POSTGRES_DB:-assetmanager} APP_TITLE: AssetManager ASSETMANAGER_CONTAINER_ROLE: app ASSETMANAGER_IMAGE_REF: ${ASSETMANAGER_IMAGE:-local-build} ASSETMANAGER_BUILD_DATE: ${ASSETMANAGER_BUILD_DATE:-} ASSETMANAGER_GIT_COMMIT: ${ASSETMANAGER_GIT_COMMIT:-} ASSETMANAGER_DATA_ROOT: /assetmanager-data APP_CONFIG: /assetmanager-data/config/config.json APPINFO_PATH: /assetmanager-data/config/APPINFO.json UPLOAD_DIR: /assetmanager-data/uploads STANDARD_IMAGE_DIR: /assetmanager-data/uploads/library BACKUP_DIR: /assetmanager-data/backups BACKUP_INTERVAL_HOURS: ${BACKUP_INTERVAL_HOURS:-8} BACKUP_RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-3} MESHCENTRAL_PASSWORD: ${MESHCENTRAL_PASSWORD:-} APP_LOG_DIR: /assetmanager-data/logs SYNC_LOG_DIR: /assetmanager-data/logs/sync DIAGNOSTIC_DIR: /assetmanager-data/logs/diagnostics SOFTWARE_PACKAGE_DIR: /assetmanager-data/software-packages ANALYZER_PROFILE_DIR: /assetmanager-data/analyzer-profiles SCRIPT_DIR: /assetmanager-data/scripts ANALYZER_PROFILE_REPOSITORY_URL: ${ANALYZER_PROFILE_REPOSITORY_URL:-} ANALYZER_PROFILE_MAX_BYTES: ${ANALYZER_PROFILE_MAX_BYTES:-2097152} ANALYZER_PROFILE_REPOSITORY_MAX_BYTES: ${ANALYZER_PROFILE_REPOSITORY_MAX_BYTES:-4194304} SOFTWARE_PACKAGE_IMPORT_MAX_MB: ${SOFTWARE_PACKAGE_IMPORT_MAX_MB:-8192} SOFTWARE_PACKAGE_IMPORT_MAX_FILES: ${SOFTWARE_PACKAGE_IMPORT_MAX_FILES:-20000} LDAP_BIND_PASSWORD: ${LDAP_BIND_PASSWORD:-} SESSION_SECRET: ${SESSION_SECRET:-} LOCAL_ADMIN_USERNAME: ${LOCAL_ADMIN_USERNAME:-} LOCAL_ADMIN_PASSWORD: ${LOCAL_ADMIN_PASSWORD:-} CALLBACK_PORT: ${CALLBACK_PORT:-8090} CALLBACK_BIND_IP: ${CALLBACK_BIND_IP:-127.0.0.1} ports: - "${APP_PORT:-8088}:8000" volumes: # One persistent host root. The entrypoint creates all required # subdirectories below ./data automatically on every start. - ./data:/assetmanager-data # Callback-only listener for Internet/DMZ scenarios. # Starts together with AssetManager and exposes only the callback POST endpoint # and callback health endpoint, never the AssetManager web interface. callback: build: . container_name: assetmanager-callback restart: unless-stopped depends_on: db: condition: service_healthy environment: DATABASE_URL: postgresql+psycopg://${POSTGRES_USER:-assetmanager}:${POSTGRES_PASSWORD:-change-me}@db:5432/${POSTGRES_DB:-assetmanager} APP_TITLE: AssetManager ASSETMANAGER_CONTAINER_ROLE: callback ASSETMANAGER_IMAGE_REF: ${ASSETMANAGER_IMAGE:-local-build} ASSETMANAGER_BUILD_DATE: ${ASSETMANAGER_BUILD_DATE:-} ASSETMANAGER_GIT_COMMIT: ${ASSETMANAGER_GIT_COMMIT:-} CALLBACK_BIND_IP: ${CALLBACK_BIND_IP:-127.0.0.1} CALLBACK_PORT: ${CALLBACK_PORT:-8090} ASSETMANAGER_DATA_ROOT: /assetmanager-data APP_CONFIG: /assetmanager-data/config/config.json APPINFO_PATH: /assetmanager-data/config/APPINFO.json UPLOAD_DIR: /assetmanager-data/uploads STANDARD_IMAGE_DIR: /assetmanager-data/uploads/library BACKUP_DIR: /assetmanager-data/backups APP_LOG_DIR: /assetmanager-data/logs SYNC_LOG_DIR: /assetmanager-data/logs/sync DIAGNOSTIC_DIR: /assetmanager-data/logs/diagnostics SOFTWARE_PACKAGE_DIR: /assetmanager-data/software-packages ANALYZER_PROFILE_DIR: /assetmanager-data/analyzer-profiles SCRIPT_DIR: /assetmanager-data/scripts MESHCENTRAL_PASSWORD: ${MESHCENTRAL_PASSWORD:-} LDAP_BIND_PASSWORD: ${LDAP_BIND_PASSWORD:-} SESSION_SECRET: ${SESSION_SECRET:-} command: ["uvicorn", "app.main:callback_app", "--host", "0.0.0.0", "--port", "8001"] ports: - "${CALLBACK_BIND_IP:-127.0.0.1}:${CALLBACK_PORT:-8090}:8001" volumes: - ./data:/assetmanager-data healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8001/api/software-callback/health', timeout=3).read()"] interval: 30s timeout: 5s start_period: 10s retries: 3