# CasaOS Dashboard "Derzeit nicht unterstützt" — Debugging Reference

## Key error from zimaos-app-management logs

When a container is registered as `v2app`, the app-management service tries to resolve it from the app store and fails:

```
error: "extension `x-casaos` not found", "composeAppID": "printvault"
error: "extension `x-casaos` not found", "composeAppID": "docmaster"
```

This is the smoking gun. If you see this in `sudo journalctl -u zimaos-app-management`, the container has `com.docker.compose.*` labels.

## app_type behavior confirmed by inspection

**Container started via docker compose:**
```
docker inspect --format '{{json .Config.Labels}}' <name>
```

Contains `com.docker.compose.project`, `com.docker.compose.service`, etc. → registered as `v2app`.

**Container started via docker run with casaos labels only:**
- NO `com.docker.compose.*` labels → registered as `container`
- Works. Same as `kiwi-browser` which has always been `container` type.

## JSON overwrite behavior

`zimaos-app-management` overwrites `/etc/casaos/app-management.json` on shutdown with its in-memory state. Any manual edits made while the service was running are lost.

**Correct order:**
1. `sudo systemctl stop zimaos-app-management`
2. Edit JSON
3. `sudo systemctl start zimaos-app-management`
4. `sudo systemctl restart zimaos-gateway` (gateway caches routes)

## API for verification

The app-management service port changes on every restart. Find it:
```bash
sudo ss -tlnp | grep zimaos-app-man | awk '{print $4}' | cut -d: -f2 | head -1
```

Query the app grid (internal API, not public):
```bash
curl -s http://127.0.0.1:$PORT/v2/app_management/web/appgrid
```

The response has `app_type` per entry. Look for `container` vs `v2app`.

## Compose file not found → container type (Legacy)

When `zimaos-app-management` can't find the compose file at the expected path, the app falls back to `container` type (Legacy) instead of `v2app`. The log shows:

```
error: "failed to load compose file" ... "no configuration file provided: not found"
path: "/DATA/AppData/<app>/casaos-compose.yml"
```

**Root cause:** The compose file lives at `/DATA/AppData/<app>/casaos-compose.yml` but `zimaos-app-management` resolves from `/var/lib/casaos/apps/<store_app_id>/docker-compose.yml`. The `/DATA/AppData/` path is NOT scanned.

**Fix:** Stop the container, deploy from the standard CasaOS path:
```bash
docker stop <container> && docker rm <container>
cd /var/lib/casaos/apps/<AppName>
DOCKER_CONFIG=/tmp/docker-config docker compose up -d
sudo systemctl restart zimaos-app-management
sudo systemctl restart zimaos-gateway
```

Verify with the appgrid API — `app_type` should now be `v2app` with `port`, `scheme`, `index`, `icon` fields populated.

## Working reference: kiwi-browser

kiwi-browser has always worked because it was started via `docker run` without compose:
```json
{
    "app_type": "container",
    "image": "kiwi-browser:v2",
    "name": "ce7d9a5d4d8a88f703df2e86d89ddaf3099147fd0ff6c1b8d2df103e0ccd1639",
    "status": "running",
    "title": {"en_US": "kiwi-browser"}
}
```

Note: no `port`, `scheme`, `index`, `icon` in the JSON — they're read from Docker labels at runtime.

## Caddy gateway route inspection

```bash
sudo curl -s --unix-socket /run/caddy-admin.sock http://localhost/config/
```

All app routes go through `zimaos-app-management` on a dynamic port. The gateway doesn't directly proxy to containers — it proxies to app-management, which resolves based on labels.

## Reboot persistence

`docker run --restart unless-stopped` survives reboots. The labels are preserved. No compose file needed. The app-management service re-discovers containers on startup from Docker daemon state, not from compose files.

## VPN / Remote Access: hostname field is the key

All CasaOS official apps (Plex, Immich, Komga, Audiobookshelf) ship with `hostname: ""` (empty string). The frontend uses `window.location.hostname` to build the iframe URL when hostname is empty — so it uses whatever host the dashboard was accessed through.

**Hardcoded LAN IPs (`hostname: "192.168.178.171"`) break over VPN** because the client browser tries to reach the LAN IP directly, which isn't routed through the VPN tunnel.

**The fix:** set hostname to empty string in both the Docker `casaos.hostname` label and the compose `x-casaos.hostname` field. The app icon URL (`casaos.icon`) is the only field that still needs the LAN IP — and that's cosmetic (a missing icon doesn't block app access).
