# Installation

> Step-by-step installation and trigger setup

---

1. Copy the module folder to `modules_v4/cronjob/` (ZIP install works too). The cron library ships inside the module — nothing to fetch.
2. Open webtrees once (any page as an admin) so the module's `boot()` creates its tables.
3. Install the trigger (classic cron, systemd timer, or Windows Task Scheduler — the module's admin page generates the block for your OS with the paths of *this* installation already filled in).
4. Trigger installation (once) — see below.
5. Create your first job in the admin UI or configure and activate registered jobs.

## Trigger installation (once)

![Installation](img/cj/installation.png)

> **Important — PHP CLI binary:** the admin page's *Installation* accordion shows which PHP CLI interpreter is currently resolved (badge: *auto-detected* / *manual path*) and lets you pin a manual path. The chosen binary is used for the watch daemon spawn and in all generated trigger commands.

It is important to check whether your web server provides a PHP-CLI binary (SAPI) and whether the module is configured correctly to use it. Otherwise, **tick** will not work.

The tick is designed to run every 60 seconds. It makes an inventory of cron jobs, commands and events, triggers events and processes the task queue.

Pick **one** of the options shown in the module's admin page:

### Option A — classic cron

One line in the web server user's crontab, runs every minute:

```
* * * * * cd "/path/to/webtrees" && mkdir -p data/cronjob && "/usr/bin/php" modules_v4/cronjob/cli/tick.php cron:tick >> "/path/to/webtrees/data/cronjob/tick.log" 2>&1
```

### Option B — systemd timer

Two unit files (also shown in the admin page):

```ini
# /etc/systemd/system/cronjob-tick.service
[Unit]
Description=webtrees cronjob module tick (runs due maintenance jobs)

[Service]
Type=oneshot
User=<webserver-user>
WorkingDirectory="/path/to/webtrees"
ExecStart="/usr/bin/php" ./modules_v4/cronjob/cli/tick.php cron:tick
```

```ini
# /etc/systemd/system/cronjob-tick.timer
[Unit]
Description=Run the webtrees cronjob tick every minute

[Timer]
OnBootSec=1min
OnCalendar=*:*:00
Persistent=true

[Install]
WantedBy=timers.target
```

```bash
sudo systemctl daemon-reload
sudo systemctl enable --now cronjob-tick.timer
```

### Option C — watch daemon (no OS timer)

Click *Start watch* on the admin page. A resident process runs the tick every 60 seconds, and a page-load watchdog respawns it if it dies. Use it when the host has no cron and no systemd access, or for testing — on Windows hosts this is the simplest option.




<pre class="mermaid">stateDiagram-v2
    [*] --&gt; Stopped: (initial)
    Stopped --&gt; Running: Start watch (Admin-UI)
    Running --&gt; TickLoop: tick every 60 s
    TickLoop --&gt; TickLoop: run job
    TickLoop --&gt; Dead: ⚠ process dies
    Dead --&gt; Running: 🔄 Watchdog respawn&lt;br/&gt;(next page load&lt;br/&gt;Cooldown 5 min)
    Running --&gt; Stopped: Stop watch
    Dead --&gt; Stopped: Stop watch&lt;br/&gt;(no respawn)

    note right of Running
        🔒 holds data/cronjob/watch.lock
        🆔 PID visible in Admin-UI
        🛡 survives FPM-Worker-Recycle (setsid)
    end note
</pre>

### Option D — Windows Task Scheduler

The admin page generates the XML with paths already filled in. Save it as `wt-cronjob-tick.xml` (UTF-8) and run `schtasks /Create /F /XML wt-cronjob-tick.xml` once in an elevated prompt.
