Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .husky/pre-commit

This file was deleted.

1 change: 1 addition & 0 deletions docs/.vitepress/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const sidebar: DefaultTheme.SidebarItem[] = [
{ text: 'Curated Scripts', link: '/features/apps/install-scripts/curated/' },
{ text: 'Contributing', link: '/features/apps/install-scripts/contributing' },
{ text: 'Schema Reference', link: '/features/apps/install-scripts/reference/schema' },
{ text: 'Hooks Reference', link: '/features/apps/install-scripts/reference/hooks' },
{ text: 'Macros Reference', link: '/features/apps/install-scripts/reference/macros' },
{ text: 'Debugging', link: '/features/apps/install-scripts/advanced/debugging' },
]
Expand Down
33 changes: 29 additions & 4 deletions docs/features/apps/install-scripts/advanced/debugging.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
## Debugging Workflow : Troubleshooting Failed Installations

If an install scripts fails, this will help:
If an install script fails, this will help:

### 1. Check HexOS Task Failure
1. In the HexOS UI, check your notifications for an app install failure
2. Click the notification to view the error message

### 2. Check TrueNAS Job Failure
### 2. Check Hook Failures (V5 Scripts)

If your install script uses lifecycle hooks, hook tasks appear as children of the main install task in the HexOS activity center:

1. Open the **Activity Center** (bell icon) in the HexOS UI
2. Expand the install task to see individual hook steps
3. Each hook shows its checkpoints and current status
4. If a hook failed:
- Click **View Details** to see structured error context (endpoint, status code, etc.)
- Click **Retry** to re-run the hook from the failed checkpoint
- Click **Skip** to skip the hook and continue (if allowed)

**Common hook failure causes:**
- **App not ready** — the container hasn't finished starting. Increase the hook's `timeout` or add a longer delay in `waitForApp()`
- **Network unreachable** — the hook can't reach the app's HTTP endpoint. Check that the port is correct and the app binds to `0.0.0.0`
- **OAuth timeout** — the user didn't complete the OAuth flow within the time limit. Retry the hook to get a fresh OAuth prompt
- **Missing input** — a required hook input wasn't provided. Check your `inputs` declarations

### 3. Check TrueNAS Job Failure
1. Navigate to the TrueNAS web interface (e.g., `https://10.0.1.13`)
2. Go to **Jobs** section to view the installation job details
3. Look for error messages in the detailed job output

### 3. Check Application Logs (if app installed but won't start)
### 4. Check Application Logs (if app installed but won't start)
**Option A: TrueNAS Apps UI (if container is running)**
1. Navigate to `https://10.0.1.13/ui/apps/installed`
2. Click on the app, under `Workloads > Containers`, click the "View Logs" button
Expand All @@ -23,7 +41,7 @@ If an install scripts fails, this will help:
3. Copy the container ID
4. Run `sudo docker logs <container_id>` to view detailed logs

### 3. Common Issues and Solutions
### 5. Common Issues and Solutions

#### Permission Errors
- **Symptom**: App fails to start, logs show permission denied errors
Expand All @@ -38,5 +56,12 @@ If an install scripts fails, this will help:
- **Symptom**: TrueNAS job fails with validation errors
- **Solution**: Compare your `app_values` structure with the official TrueNAS app schema

#### Hook Script Errors
- **Symptom**: Hook task shows `AWAITING_RETRY` with an error message
- **Solution**: Check the error context details for the specific failure. Common fixes:
- Ensure the `entrypoint` function name matches what's exported in your script
- Verify the app's API endpoint path is correct
- Confirm all `await` keywords are present on async calls

### Future Improvements
The current debugging workflow requires accessing the TrueNAS interface directly, in the future we plan to expose more of this debugging workflow within HexOS's UI.
83 changes: 75 additions & 8 deletions docs/features/apps/install-scripts/contributing.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,77 @@
# Contributing a new app
# Contributing a New App

Want to add your app curation to the official HexOS catalog? Follow these steps to contribute your install script, or share it in our forums first to get community feedback:
Want to add your app curation to the official HexOS catalog? Install scripts now live in the [hexos-app-catalog](https://github.com/eshtek/hexos-app-catalog) repository — this is the single source of truth for all curated and community install scripts.

1. Test your custom curation in HexOS and verify it works reliably
2. Click [Here](https://github.com/eshtek/hexos-docs/new/main/docs/public/install-scripts) to start the contribution process
3. Click the green "Fork this repository" button
4. Paste the contents of your install script into the editor and press the green "Commit Changes"
5. Click the green "Create pull request" on the following page
6. In your PR description, include any special requirements (unique mounts, GPU usage, special environment variables, etc.)
## Contribution Steps

1. **Test your install script** in HexOS using Custom Install (Expert Mode) and verify it works reliably
2. **Fork** the [hexos-app-catalog](https://github.com/eshtek/hexos-app-catalog) repository
3. **Add your install script** as a JSON file named after the TrueNAS app (e.g., `myapp.json`)
4. **If your script includes hooks** (V5), add the hook `.ts` files in a subdirectory (e.g., `myapp/myapp_hook.ts`) — or use inline `scriptContent` for simpler hooks
5. **Submit a Pull Request** with a description of:
- What the app does
- Any special requirements (unique mounts, GPU usage, special environment variables)
- What the hooks do (if V5)

## Repository Structure

```
hexos-app-catalog/
├── _lib/
│ └── hook_context.ts # HookContext type stubs (import for autocompletion)
├── myapp.json # Your install script (V4 or V5)
├── myapp/ # Hook scripts directory (V5 only, optional)
│ └── myapp_hook.ts # Hook implementation
├── plex.json # Example: first-party V5 with hooks
├── plex/
│ └── plex_hook.ts
├── jellyfin.json # Example: V4 script (no hooks)
└── ...
```

## Script Format

- **V4**: Standard install scripts without hooks. Set `"version": 4`.
- **V5**: Install scripts with lifecycle hooks. Set `"version": 5` and add a `hooks` array. See the [Hooks Reference](/features/apps/install-scripts/reference/hooks) for details.

Both formats are fully supported. Use V5 only if your app benefits from post-install automation.

## Using Inline Hooks (`scriptContent`)

Community contributors who don't need separate `.ts` files can embed hook code directly in the JSON using the `scriptContent` field. This keeps everything in a single file:

```json
{
"version": 5,
"custom": true,
"metadata": { "name": "My App", "description": "...", "icon": "...", "version": "1.0.0" },
"hooks": [
{
"id": "health-check",
"event": "onAfterInstall",
"scriptContent": "export async function setup(ctx) {\n await ctx.waitForApp('/health');\n await ctx.emitCheckpoint('ready');\n}",
"entrypoint": "setup",
"timeout": 60,
"description": "Post-install health check",
"optional": true
}
]
}
```

::: tip Testing with Custom Install
You can test inline hook scripts using **Custom Install in Expert Mode** — paste your V5 JSON with `scriptContent` hooks directly into the editor and run it. This is useful for development and testing before submitting a PR. Inline scripts should not be part of a PR submission for testing purposes only — submit them when they're ready for production use.
:::

## Best Practices

- Use the [Schema Reference](/features/apps/install-scripts/reference/schema) and [Macros Reference](/features/apps/install-scripts/reference/macros) to understand all available fields and template variables
- Browse existing scripts in the [hexos-app-catalog](https://github.com/eshtek/hexos-app-catalog) for real-world examples
- Test thoroughly before submitting — both fresh installs and upgrades
- Keep hooks focused and use `optional: true` for non-critical automation
- Use `$LOCATION()` macros instead of hardcoded paths
- Declare `owner` on directories that need specific permissions

## Sharing Before Contributing

Not ready for a PR? Share your install script JSON in the [HexOS Community Forums](https://forums.hexos.com) to get feedback from other users first.
47 changes: 15 additions & 32 deletions docs/features/apps/install-scripts/curated/index.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,17 @@
# Apps (Curated Scripts)

<!-- curated:index:start -->
| App | Download | Size | Last Modified |
|---|---|---:|---|
| `bazarr` | [bazarr.json](/install-scripts/bazarr.json) | 1.4 KB | 2026-05-15 |
| `blinko` | [blinko.json](/install-scripts/blinko.json) | 1.3 KB | 2026-05-20 |
| `dozzle` | [dozzle.json](/install-scripts/dozzle.json) | 614 B | 2026-05-18 |
| `drawio` | [drawio.json](/install-scripts/drawio.json) | 634 B | 2026-05-15 |
| `emby` | [emby.json](/install-scripts/emby.json) | 2.3 KB | 2026-05-15 |
| `excalidraw` | [excalidraw.json](/install-scripts/excalidraw.json) | 614 B | 2026-05-18 |
| `fladder` | [fladder.json](/install-scripts/fladder.json) | 566 B | 2026-05-24 |
| `handbrake` | [handbrake.json](/install-scripts/handbrake.json) | 1.9 KB | 2026-05-15 |
| `home-assistant` | [home-assistant.json](/install-scripts/home-assistant.json) | 1.4 KB | 2026-05-15 |
| `immich` | [immich.json](/install-scripts/immich.json) | 1.6 KB | 2026-05-15 |
| `jellyfin` | [jellyfin.json](/install-scripts/jellyfin.json) | 2.3 KB | 2026-05-15 |
| `jellystat` | [jellystat.json](/install-scripts/jellystat.json) | 1.6 KB | 2026-05-28 |
| `lidarr` | [lidarr.json](/install-scripts/lidarr.json) | 1.4 KB | 2026-05-15 |
| `lubelogger` | [lubelogger.json](/install-scripts/lubelogger.json) | 1.5 KB | 2026-05-18 |
| `mkvtoolnix` | [mkvtoolnix.json](/install-scripts/mkvtoolnix.json) | 2.2 KB | 2026-06-05 |
| `navidrome` | [navidrome.json](/install-scripts/navidrome.json) | 5.1 KB | 2026-05-18 |
| `nextcloud` | [nextcloud.json](/install-scripts/nextcloud.json) | 3.4 KB | 2026-05-20 |
| `peanut` | [peanut.json](/install-scripts/peanut.json) | 911 B | 2026-05-15 |
| `plex` | [plex.json](/install-scripts/plex.json) | 3.4 KB | 2026-05-15 |
| `portracker` | [portracker.json](/install-scripts/portracker.json) | 894 B | 2026-05-18 |
| `prowlarr` | [prowlarr.json](/install-scripts/prowlarr.json) | 781 B | 2026-05-15 |
| `qbittorrent` | [qbittorrent.json](/install-scripts/qbittorrent.json) | 1.0 KB | 2026-05-15 |
| `qui` | [qui.json](/install-scripts/qui.json) | 865 B | 2026-06-05 |
| `radarr` | [radarr.json](/install-scripts/radarr.json) | 1.3 KB | 2026-05-15 |
| `scrutiny` | [scrutiny.json](/install-scripts/scrutiny.json) | 1.4 KB | 2026-05-15 |
| `seerr` | [seerr.json](/install-scripts/seerr.json) | 924 B | 2026-05-22 |
| `sonarr` | [sonarr.json](/install-scripts/sonarr.json) | 1.3 KB | 2026-05-15 |
| `syncthing` | [syncthing.json](/install-scripts/syncthing.json) | 2.6 KB | 2026-05-15 |
<!-- curated:index:end -->
Curated install scripts are maintained in the [hexos-app-catalog](https://github.com/eshtek/hexos-app-catalog) repository. This is the single source of truth — scripts are synced from this repo to HexOS automatically.

::: info Repository Migration
Install scripts have moved from this documentation site to the dedicated [hexos-app-catalog](https://github.com/eshtek/hexos-app-catalog) repository. All contributions, bug fixes, and new scripts should be submitted there. See [Contributing](/features/apps/install-scripts/contributing) for details.
:::

## Browse Scripts

**[Browse hexos-app-catalog on GitHub](https://github.com/eshtek/hexos-app-catalog)**

Each `.json` file in the repository root is an install script. Apps with lifecycle hooks (V5) also have a subdirectory containing their hook `.ts` files (e.g., `plex/plex_hook.ts`).

## Want to Contribute?

See the [Contributing Guide](/features/apps/install-scripts/contributing) for how to submit your own install script to the catalog.
22 changes: 17 additions & 5 deletions docs/features/apps/install-scripts/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,23 @@ Install scripts are a curated, turnkey solution for installing applications thro
- **Best practices built-in** - All configurations follow recommended settings
- **One-click installation** - Simplified installation process
- **Curated experience** - Apps are pre-tested and optimized
- **Post-install automation** - Lifecycle hooks can handle app setup after installation (V5)

### Current Capabilities
- Configures all fields that TrueNAS exposes during app installation
- Automatically sets up directory structures and permissions
- Configures resource allocation (CPU, memory, GPU)
- Sets up networking and port mappings
- Manages storage mounts and paths
- **Lifecycle hooks** — run automated setup steps before or after install and upgrade (V5)

### Future Capabilities (Local UI)
Once the Local UI feature is complete, these install scripts are able to do much more; ultimately bypassing any post-installation setup of these apps entirely.
### What's New in V5: Lifecycle Hooks

V5 install scripts introduce **lifecycle hooks** — TypeScript functions that execute at specific points during app install and upgrade. Hooks enable post-install automation like health checks, service configuration, OAuth login, and more — all without the user needing to open the app's own UI.

V5 is a strict superset of V4. The only new field is `hooks`. An existing V4 script can be promoted to V5 by changing `"version": 4` to `"version": 5` and optionally adding a `hooks` array.

For full details, see the [Hooks Reference](/features/apps/install-scripts/reference/hooks).

## How to Use Install Scripts

Expand All @@ -34,6 +41,7 @@ For supported applications, the installation process is streamlined:
- Allocate appropriate system resources
- Mount required storage paths
- Handle any app-specific requirements
- Run lifecycle hooks for post-install setup (V5 apps)

### Custom Installation
For apps not yet curated or when you need to customize the configuration:
Expand All @@ -49,17 +57,21 @@ For apps not yet curated or when you need to customize the configuration:
### Best Practices and Common Pitfalls

#### Best Practices
- **Use V4 format** — all new install scripts must use `"version": 4`
- **Use V5 format for new scripts with hooks**, or **V4 for scripts without hooks** — both are fully supported
- **Always use `$LOCATION()` macros** for paths instead of hardcoded paths
- **Use `$HOST_PATH()` and `$MOUNTED_HOST_PATH()`** for storage configuration instead of manual object creation
- **All directory entries must be objects** — bare strings in `ensure_directories_exists` are no longer supported in V4
- **All directory entries must be objects** — bare strings in `ensure_directories_exists` are no longer supported
- **Declare ownership** with the `owner` field for apps that require specific user/group ownership (e.g., `"postgres"`, `"apps"`)
- **Add `snapshot` config** on data and config directories to enable automatic pre-update ZFS snapshots
- **Use `$MEMORY()` for dynamic memory allocation** to ensure apps work across different system configurations
- **Reference TrueNAS app schemas** from the [official apps repository](https://github.com/truenas/apps) for `app_values` structure
- **Keep hook scripts focused** — each hook should do one thing (health check, configuration, library setup)
- **Use `optional: true`** on hooks that are nice-to-have but shouldn't block app installation if they fail

#### Common Pitfalls
- **Permission issues** are the most common cause of failures - both during installation and at runtime
- **Hardcoded paths** break when users have custom location preferences
- **Missing directory creation** can cause apps to fail during installation
- **Incorrect `app_values` structure** for the specific TrueNAS app version
- **Incorrect `app_values` structure** for the specific TrueNAS app version
- **Missing `await`** in hook scripts — all `ctx` methods are async and must be awaited
- **Hook timeout too short** — apps can take 30-60 seconds to become responsive after container creation; use `ctx.waitForApp()` with appropriate timeouts
Loading
Loading