Install from a shell

Ten steps, in order, stopping at the first problem - and a dry run that changes nothing.

One script prepares the machine: the system user, the file layout and its modes, the systemd units, TLS, a dedicated PHP-FPM pool and a validated vhost. Then it hands over to the setup wizard and waits for real documents before telling you it worked.

git clone https://github.com/phpcip/loghound.git
cd loghound

# Look before you leap. This changes nothing at all.
sudo ./install/install.sh --dry-run

sudo ./install/install.sh
Run the dry run first, and read it

This script creates a user, writes to /etc/systemd/system, writes a vhost and reloads your web server. It cannot do those things without root, and you should not run any script as root on a production box without looking at it first. --dry-run prints every command it would execute and every file it would write, and changes nothing.

01 · What it does, in order

It stops at the first problem, and everything is logged in plain text to /var/log/loghound-install.log.

1 PREFLIGHTnothing has changed2-4 LAY OUTuser, files, modes, verify5-6 UNITS, TLShardened; cert verified7-8 SERVEpool, vhost9 SETUP WIZARDshell, or the browser10 PROVE ITwaits for real documents

Figure 1 — the installer’s flow. Nothing on the machine has changed until step two, and the last step refuses to declare success just because a unit happens to be active.

  1. Preflight, before a single change. PHP version and every required extension, systemd or cron, the adm group, write access to the target, a complete source tree, the web server and its runtime user, the FPM pool directory, the Apache modules it needs, and a check for any file it would collide with. Prints a PASS/FAIL table and exits non-zero on any failure.
  2. The system user. loghound: system account, no login shell, no home directory, added to adm for read access to /var/log. If the user already exists it is left alone, and usermod -aG only ever adds a group.
  3. Files and permissions. The single most common cause of a broken install, so they are verified rather than assumed. The permission model is its own page.
  4. Verification, as the actual users. Three checks, all printed — the web server user must be able to traverse the prefix and read public/index.php, and must fail to read config. Plus a test, with a real process rather than by reading /etc/group, that the service user can actually read your access logs.
  5. systemd units. The tail service plus the score and retention services and timers, hardened with NoNewPrivileges, ProtectSystem=strict, ProtectHome, PrivateTmp, an empty CapabilityBoundingSet and a memory cap. Both timers are enabled.
  6. TLS. It looks for an existing certificate in the usual places and checks every candidate four ways: does the private key match the certificate by public key so it works for EC keys too, is it valid for at least another day, does it list your hostname, and does it chain to a trusted root.
  7. PHP-FPM pool. A dedicated pool running as the service user on its own socket — never the shared pool, which would make every other site on the box execute as a user that can read your API key. Validated with php-fpm -t before anything is reloaded.
  8. Vhost. Generated with your hostname, prefix, certificate paths and socket filled in, written as zzz-loghound.conf so it sorts last, then validated with apache2ctl configtest or nginx -t before being enabled. If validation fails, the files this run created are removed and validation is re-run to prove your host is back where it started.
  9. The setup wizard. Hands over to bin/loghound-setup running as the service user. Pass --skip-setup to stop here and finish in a browser instead.
  10. Start, and prove it. Starts the daemon, then waits up to sixty seconds for the first documents to reach Solr, rather than declaring success because a unit is running.
Why the vhost filename starts with zzz

Apache treats the first vhost matching an address and port as the default for unmatched requests. A Loghound file sorting ahead of an existing catch-all would silently hijack every unmatched request on the machine.

02 · What it never does
  • Modify an existing vhost, FPM pool, cron entry, systemd unit or any file it did not write.
  • restart — as opposed to reload — your web server or PHP-FPM.
  • Deploy a TLS certificate it has not verified.
  • Write to, truncate, rotate or delete any log file it reads.
  • Overwrite config/loghound.php.
03 · The options
OptionWhat it does
--dry-runPrint every action and change nothing. Do this first.
--upgradeRefresh code in place; the configuration and var/ are untouched. See upgrading.
--uninstallReverse everything, prompting before deleting any data. See uninstalling.
--prefix DIRInstall root; the default is /opt/loghound. --prefix=DIR works too.
--user NAMESystem user to run as. Default loghound.
--hostname FQDNThe panel’s hostname.
--webserverapache, nginx or none.
--tls-modeexisting, certbot, selfsigned or none.
--tls-cert PATH
--tls-key PATH
Used with --tls-mode existing.
--skip-setupPrepare the machine and stop; configure in the browser.
--skip-testsDo not run the test suite.
--non-interactiveAnswer every prompt from the environment or the default. See unattended installs.
--yes, -yAssume yes for confirmations. It still refuses to overwrite files.

An install somewhere other than the default, with everything — the vhost document root, the pool’s open_basedir, the unit paths, the deny rules — following it:

sudo ./install/install.sh --prefix=/var/www/loghound

Loghound is open source and MIT licensed. Questions about the Opensolr half — the account, the indexes, the plan — go to opensolr.com/contact; questions about the software itself belong on GitHub.

Loghound Documentation