---
title: "Installation"
manual: "Content Repurpose"
version: "0.11"
permalink: "https://docs.typo3.org/permalink/netresearch/nr-repurpose:installation@0.11"
source: "Installation/Index.rst"
rendered: "2026-10-08T11:54:23+00:00"
---

# Installation {#installation}

## Requirements {#installation-requirements}

| Requirement | Notes |
| --- | --- |
| PHP | `^8.3` |
| TYPO3 | `^14.3` (v14.3 LTS only) |
| [`netresearch/nr-llm`](https://packagist.org/packages/netresearch/nr-llm) | `^0.35 \|\| ^0.36 \|\| ^0.37 \|\| ^0.38 \|\| ^0.39` — AI access (completion, TTS, image), budget enforcement and one-click configuration presets. |
| [`netresearch/nr-vault`](https://packagist.org/packages/netresearch/nr-vault) | `^1.1` — holds the provider keys nr-llm reads; its technical-actor API lets the worker read them (see [Extension settings](https://docs.typo3.org/permalink/netresearch/nr-repurpose:configuration-extension-settings@0.11)). |
| PHP extension `curl` | Fetching `url` and `pdf_url` sources and sending the social webhook. The worker connects to the addresses the host was checked with, and the time limit covers the whole transfer including the response headers. Without it these requests are refused. |
| `poppler-utils` | `pdftoppm` / `pdftotext` for PDF ingestion (Vision OCR and layout tiers). |
| `ffmpeg` / `ffprobe` | Concatenate the podcast MP3 segments and measure segment durations for the WebVTT cue timing. |
| `chromium` | Headless browser the Node renderer drives to turn HTML into PNGs. |
| Node.js | `>=22.18.0 <25.0.0` to run the bundled `render.cjs` (uses `playwright-core`). |

The version ranges are the ones `composer.json` requires; that file is
authoritative.

> [!NOTE]
> The system binaries (`poppler-utils`, `ffmpeg`, `chromium`) are not
> PHP dependencies — they must be present on the host (and on the worker host).
> In the bundled DDEV environment they are baked into the web image.

## Composer installation {#installation-composer}

**Install via Composer**

```bash
composer require netresearch/nr-repurpose
```

This pulls in nr-llm and its own dependencies. After installation, set up the
extension's database tables and activate it:

**Set up the extension**

```bash
vendor/bin/typo3 extension:setup nr_repurpose
vendor/bin/typo3 cache:flush
```

The extension creates two tables:

| Table | Purpose |
| --- | --- |
| `tx_nrrepurpose_domain_model_job` | One row per generation run (source, selected artifacts, theme, status, progress). |
| `tx_nrrepurpose_domain_model_artifact` | One row per produced artifact (type, variant, FAL file references, transcript, metadata, status). |

## Classic mode (TER) is not supported {#installation-classic}

> [!WARNING]
> nr_repurpose requires a Composer-based TYPO3 installation. Installing it
> through the Extension Manager (classic mode) is not supported.

The extension needs code that only a Composer installation provides:

-   **A PHP library.** PDF ingestion uses [`smalot/pdfparser`](https://packagist.org/packages/smalot/pdfparser), which
    `composer.json` requires. The TER package contains no
    `vendor/` directory, so the library is missing in classic mode.
-   **The Node renderer's dependencies.** The TER package ships only
    `Resources/Private/NodeRenderer/render.cjs`, without the
    `package.json` and `package-lock.json` that
    [Install the Node renderer](https://docs.typo3.org/permalink/netresearch/nr-repurpose:installation-node-renderer@0.11) installs `playwright-core` from. Without
    them the Schaubild, story, slide deck and handout cannot be rendered.

The extension is listed in the TYPO3 Extension Repository as
[nr_repurpose](https://extensions.typo3.org/extension/nr_repurpose) so it
can be found there. Install it with Composer as described in
[Composer installation](https://docs.typo3.org/permalink/netresearch/nr-repurpose:installation-composer@0.11).

## Install the Node renderer {#installation-node-renderer}

The image renderer is a small Node script under
`Resources/Private/NodeRenderer/`. Install its single dependency
(`playwright-core`) and rely on the system `chromium` instead of letting
Playwright download its own browser:

**Install the renderer (skip the Playwright browser download)**

```bash
cd Resources/Private/NodeRenderer
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm ci
```

The renderer starts the Chromium binary at `/usr/bin/chromium`. For another
path, see [Renderer environment](https://docs.typo3.org/permalink/netresearch/nr-repurpose:configuration-rendering@0.11).

## Hand the provider key to nr-llm {#installation-openai-key}

nr_repurpose never reads an API key — it owns no provider credentials at all.
Give the key (the examples use OpenAI, the tested default) to nr-llm, which
stores it and hands back the identifier its records reference.

The normal route is nr-llm's setup wizard in the TYPO3 backend: enter the key,
and nr-llm stores it securely and generates the key identifier for you. How it
keeps the secret is nr-llm's business and documented there.

Two places then refer to that identifier, both of them nr-llm's: the **Provider**
record carries it for the chat and vision completions, and nr-llm's extension
configuration carries it as `providers.openai.apiKeyIdentifier` for the
specialized text-to-speech and image services. The Configuration records
nr_repurpose ships as presets bake in no provider, model or key at all. See
[nr-llm wiring: providers, models, Configurations](https://docs.typo3.org/permalink/netresearch/nr-repurpose:configuration-nr-llm@0.11).

> [!NOTE]
> For scripted installs where no one can operate the wizard, nr-llm's storage
> backend can also be filled from the command line — that is what the bundled
> DDEV setup does, seeding the identifier `nr_repurpose_openai`. See
> [Local development with DDEV](https://docs.typo3.org/permalink/netresearch/nr-repurpose:installation-ddev@0.11).

## Run the generation worker {#installation-worker}

Generation runs asynchronously: job submission only dispatches a message, and a
Symfony Messenger worker does the actual work. Run a long-lived consumer on a
host that has the system binaries and the Node renderer installed:

**Consume the generation transport**

```bash
php -d memory_limit=1G vendor/bin/typo3 messenger:consume doctrine --time-limit=3600 --memory-limit=512M
```

Restart the consumer in a loop (systemd, a container restart policy, or a
supervisor) so it survives the deliberate time/memory limits that recycle the
process. The transport routing is configured in [Messenger routing](https://docs.typo3.org/permalink/netresearch/nr-repurpose:configuration-messenger@0.11).

> [!IMPORTANT]
> The PHP `memory_limit` must exceed Messenger's `--memory-limit` soft
> restart threshold, with headroom for GD image compositing — otherwise PHP
> fatals before Messenger can recycle the process, and the unacknowledged
> message is redelivered into the same crash (re-running paid AI calls). The
> compositor pre-flights its memory need and fails the single artifact
> gracefully, but only within the limit PHP actually has.

> [!NOTE]
> The worker host runs `chromium` and `ffmpeg` and reaches the configured
> AI providers — bound the outbound HTTP timeout (see [HTTP timeouts](https://docs.typo3.org/permalink/netresearch/nr-repurpose:configuration-http@0.11))
> so a stalled provider response cannot hang the worker indefinitely.

## Local development with DDEV {#installation-ddev}

The repository ships a DDEV setup whose web image already contains
`poppler-utils`, `ffmpeg` and `chromium`, and a sidecar worker container:

**Bring up the DDEV environment**

```bash
cp .ddev/.env.dist .ddev/.env     # then set OPENAI_API_KEY=sk-…
ddev start                        # builds the web image
ddev setup                        # composer install + TYPO3 setup into .Build/Web
```

`ddev setup` installs TYPO3 v14.3 into `.Build/Web`, seeds the OpenAI
key into nr-vault under `nr_repurpose_openai`, wires the nr-llm provider and
the messenger routing in `config/system/additional.php`, and installs the
Node renderer. The backend is then at `https://nr-repurpose.ddev.site/typo3/`.
