Files

9.7 KiB

AssetManager installation guide

This guide describes a Docker image based installation and the first-start behavior of AssetManager.

1. Prepare the installation directory

Create a dedicated directory and the persistent data directories:

mkdir -p /srv/docker/assetmanager
cd /srv/docker/assetmanager
mkdir -p data/config data/uploads data/logs data/backups data/scripts data/postgres

Create a .env file. Use strong, unique values for all secrets:

ASSETMANAGER_VERSION=0.5.5.47
APP_PORT=8088
POSTGRES_DB=assetmanager
POSTGRES_USER=assetmanager
POSTGRES_PASSWORD=CHANGE_ME
SESSION_SECRET=CHANGE_ME_LONG_RANDOM
LOCAL_ADMIN_USERNAME=emergency-admin
LOCAL_ADMIN_PASSWORD=CHANGE_ME_MIN_12_CHARS
MESHCENTRAL_PASSWORD=
LDAP_BIND_PASSWORD=
BACKUP_INTERVAL_HOURS=8
BACKUP_RETENTION_DAYS=3

Keep .env private. Do not commit it to a public repository.

2. Docker Compose file for a registry image

Use the published image instead of building the application locally:

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:
    image: git.jusaro.de/roland/assetmanager:${ASSETMANAGER_VERSION:-0.5.5.47}
    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
      APP_CONFIG: /app/config/config.json
      APPINFO_PATH: /app/config/APPINFO.json
      BACKUP_DIR: /data/backups
      BACKUP_INTERVAL_HOURS: ${BACKUP_INTERVAL_HOURS:-8}
      BACKUP_RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-3}
      MESHCENTRAL_PASSWORD: ${MESHCENTRAL_PASSWORD:-}
      SYNC_LOG_DIR: /app/data/logs/sync
      DIAGNOSTIC_DIR: /app/data/logs/diagnostics
      LDAP_BIND_PASSWORD: ${LDAP_BIND_PASSWORD:-}
      SESSION_SECRET: ${SESSION_SECRET:-}
      LOCAL_ADMIN_USERNAME: ${LOCAL_ADMIN_USERNAME:-}
      LOCAL_ADMIN_PASSWORD: ${LOCAL_ADMIN_PASSWORD:-}
    ports:
      - "${APP_PORT:-8088}:8000"
    volumes:
      - ./data/config:/app/config
      - ./data/uploads:/app/app/static/uploads
      - ./data/logs:/app/data/logs
      - ./data/backups:/data/backups
      - ./data/scripts:/scripts

If the registry is private, sign in once on the Docker host:

docker login git.jusaro.de

3. First start

Pull and start the containers:

docker compose pull
docker compose up -d
docker compose ps

On the first start, the container creates the following files only when they do not already exist:

data/config/config.json
data/config/APPINFO.json

Existing files are preserved during subsequent container starts and updates.

4. Important: authentication is initially disabled

A fresh default configuration starts with authentication disabled. This is intentional so the initial configuration can be completed, but the installation must not be exposed to an untrusted network in this state.

The web interface displays a warning banner while authentication is disabled. To enable local authentication:

  1. Open data/config/config.json.
  2. Locate the authentication section.
  3. Set mode to local.
  4. Restart only the application container:
docker compose restart app
  1. Sign in using LOCAL_ADMIN_USERNAME and LOCAL_ADMIN_PASSWORD from .env.

The local administrator is the protected emergency account and should remain available even when LDAP/Active Directory is configured later.

5. Configure the callback base address

Remote jobs call back to AssetManager after execution. In Software settings, configure the callback base address when clients must reach AssetManager through DNS, a reverse proxy, VPN, or the Internet.

Examples:

https://assetmanager.example.org
https://assetmanager.example.org:8443
http://192.168.1.40:8088

For Internet-facing use, HTTPS through a properly configured reverse proxy is strongly recommended. The callback endpoint must be reachable from the managed client.

If no callback base address is configured, AssetManager derives the address from the current request.

6. Verify the installation

Check the application status and logs:

docker compose ps
docker compose logs --tail=100 -f

After signing in, verify at least:

  • application version
  • database connection
  • local emergency administrator login
  • MeshCentral connectivity, if used
  • one test inventory or remote job
  • successful callback processing

7. Persistent data and backups

The following paths contain persistent runtime data and must survive image replacement:

data/config/
data/postgres/
data/uploads/
data/logs/
data/backups/
data/scripts/
.env

Back up .env and the complete data/ directory before significant updates.

8. Updating an image-based installation

Set the desired fixed image version in .env, for example:

ASSETMANAGER_VERSION=0.5.5.47

Then update:

docker compose pull
docker compose down
docker compose up -d
docker compose ps
docker compose logs --tail=100 -f

Using a fixed version tag is recommended for controlled production updates.

9. Log files

Application logs are stored below data/logs/. The main files include errors.log and, when LDAP is used, ldap.log.

Starting with version 0.5.5.45, these file loggers detect if their active log file was deleted or replaced externally. On the next log event, the file is reopened and created again automatically; an application container restart is no longer required.

For normal log maintenance, rotation/truncation mechanisms are preferable to manually deleting active log files. Docker container output remains available through:

docker compose logs --tail=100 -f

10. Troubleshooting

The web interface logs in as guest

The default configuration still has authentication disabled. Set authentication.mode to local in data/config/config.json and restart the app container.

A remote job remains at “callback pending”

Check:

  • whether the callback base address is reachable from the client
  • reverse proxy/firewall rules
  • application logs under data/logs/
  • docker compose logs --tail=100 -f

A configuration file is missing

If config.json or APPINFO.json is absent, restart the application container. The entrypoint creates a missing default file without overwriting an existing one.

Persistent standard image library

Add the following persistent volume to the application service:

- ./data/uploads:/app/app/static/uploads

Create the host directory before the first start if desired:

mkdir -p data/uploads/library

Images uploaded through the AssetManager standard image library are stored there. You can also copy PNG, JPG/JPEG, WEBP or GIF files directly into this directory. They are then offered for selection in asset and category forms after the page is reloaded.

Standard image library

Reusable asset/category images are stored persistently on the Docker host in:

./data/uploads/library

The library is a subdirectory of the already existing uploads volume. No additional Docker mount is required. The existing Compose mapping:

./data/uploads -> /app/app/static/uploads

therefore exposes the library as:

Host:      ./data/uploads/library
Container: /app/app/static/uploads/library

Images may be uploaded from the AssetManager forms or copied directly into ./data/uploads/library on the Docker host. They remain persistent because data/uploads is already part of the standard AssetManager volume layout.

For image-based installations use:

docker compose down
docker compose pull
docker compose up -d

You can verify the active mount with:

Images copied directly into ./data/uploads/library are available in the AssetManager image library after reloading the page.

Optional dedicated callback port / DMZ listener

AssetManager can expose software-job callbacks through a separate, callback-only Docker service. This is useful when remote devices must send callbacks through an Internet-facing FQDN while the normal AssetManager web interface remains internal.

The optional service exposes only:

  • GET /api/software-callback/health
  • POST /api/software-jobs/{job_id}/callback

It does not expose the AssetManager UI, login, assets, settings, static files, or administration routes.

Set the desired host port in .env:

CALLBACK_PORT=8090

Start the additional service:

docker compose --profile callback up -d callback

The internal callback container listens on port 8001; Docker maps the configured host port to it. A reverse proxy or firewall can therefore publish only this port/service. For example, a public https://callback.example.org can proxy to the Docker host on port 8090. Configure that public URL under Software and Jobs → Settings → Callback base URL.

The standard AssetManager application continues to run on APP_PORT (default 8088). The dedicated callback service is optional; installations that do not enable the callback profile behave as before.

For image-based installations, use the same AssetManager image for both the app and callback services instead of build: .. The callback service must always run the same version as the main application.