362 lines
12 KiB
Markdown
362 lines
12 KiB
Markdown
# 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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```env
|
|
ASSETMANAGER_VERSION=0.5.5.65
|
|
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
|
|
CALLBACK_BIND_IP=127.0.0.1
|
|
CALLBACK_PORT=8090
|
|
```
|
|
|
|
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:
|
|
|
|
```yaml
|
|
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.65}
|
|
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:-}
|
|
CALLBACK_BIND_IP: ${CALLBACK_BIND_IP:-127.0.0.1}
|
|
CALLBACK_PORT: ${CALLBACK_PORT:-8090}
|
|
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
|
|
|
|
callback:
|
|
image: git.jusaro.de/roland/assetmanager:${ASSETMANAGER_VERSION:-0.5.5.65}
|
|
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
|
|
APP_CONFIG: /app/config/config.json
|
|
APPINFO_PATH: /app/config/APPINFO.json
|
|
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/config:/app/config
|
|
- ./data/logs:/app/data/logs
|
|
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
|
|
```
|
|
|
|
If the registry is private, sign in once on the Docker host:
|
|
|
|
```bash
|
|
docker login git.jusaro.de
|
|
```
|
|
|
|
## 3. First start
|
|
|
|
Pull and start the containers:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```bash
|
|
docker compose restart app
|
|
```
|
|
|
|
5. 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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```env
|
|
ASSETMANAGER_VERSION=0.5.5.65
|
|
```
|
|
|
|
Then update:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```yaml
|
|
- ./data/uploads:/app/app/static/uploads
|
|
```
|
|
|
|
Create the host directory before the first start if desired:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```text
|
|
./data/uploads/library
|
|
```
|
|
|
|
The library is a subdirectory of the already existing uploads volume. No additional Docker mount is required. The existing Compose mapping:
|
|
|
|
```text
|
|
./data/uploads -> /app/app/static/uploads
|
|
```
|
|
|
|
therefore exposes the library as:
|
|
|
|
```text
|
|
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:
|
|
|
|
```bash
|
|
docker compose down
|
|
docker compose pull
|
|
docker compose up -d
|
|
```
|
|
|
|
Images copied directly into `./data/uploads/library` are available in the AssetManager image library after reloading the page.
|
|
|
|
|
|
## Dedicated callback port / DMZ listener
|
|
|
|
AssetManager starts a separate callback-only Docker service together with the normal application. This is intended for remote devices that must return job results through an Internet-facing FQDN while the AssetManager web interface remains internal.
|
|
|
|
The callback 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.
|
|
|
|
Configure the host-side listener in `.env`:
|
|
|
|
```env
|
|
CALLBACK_BIND_IP=127.0.0.1
|
|
CALLBACK_PORT=8090
|
|
```
|
|
|
|
`127.0.0.1` is a good default when the reverse proxy runs on the same Docker host. If a reverse proxy or firewall on another system must reach the listener, bind it to the appropriate host interface or, when explicitly required, `0.0.0.0`.
|
|
|
|
The normal stack is started with the usual command; no Compose profile is required:
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
The internal callback container listens on port `8001`. Docker maps `CALLBACK_BIND_IP:CALLBACK_PORT` to that internal port. A public `https://callback.example.org` can therefore proxy only to the callback listener, while the normal AssetManager web interface remains on `APP_PORT` (default `8088`).
|
|
|
|
Configure the public URL under **Software and Jobs → Settings → Callback base URL**:
|
|
|
|
```text
|
|
https://callback.example.org
|
|
```
|
|
|
|
### Health checks from the GUI
|
|
|
|
The callback settings page provides two separate tests:
|
|
|
|
- **Internal health check** tests `http://callback:8001/api/software-callback/health` from the main AssetManager container. This verifies Docker networking and the callback-only service.
|
|
- **Public health check** tests the configured callback base URL through DNS/TLS/reverse proxy. This verifies the route that remote clients are expected to use.
|
|
|
|
The GUI displays reachability, HTTP status, response time, and the tested URL. The detailed callback diagnostic log remains available on the same settings page.
|
|
|
|
For image-based installations, use the same fixed AssetManager image version for both the `app` and `callback` services.
|