System administration guide for tirreno
Welcome to the tirreno administration guide. This document covers installation, configuration, security hardening, updating, and troubleshooting for tirreno deployments.
This guide is for system administrators who want to install, configure, secure, update, and maintain tirreno deployments.
- PHP 8.0–8.3 with PDO_PGSQL, cURL, mbstring
- PostgreSQL 12+
- Apache with mod_rewrite
Hardware: 512 MB RAM for PostgreSQL (4 GB recommended), ~3 GB storage per 1M events.
- Download the latest version of tirreno: tirreno-master.zip
- Extract the ZIP file to the location where you want it installed on your web server
- Configure your web server to point to the tirreno directory
- Run the web installer
git clone https://github.com/tirrenotechnologies/tirreno.git
cd tirrenoAfter cloning, configure your web server to point to the tirreno directory and run the web installer.
tirreno is published on Packagist and can be installed with Composer.
Create a new project:
composer create-project tirreno/tirrenoOr add to an existing project:
composer require tirreno/tirrenoAfter installation, configure your web server to point to the tirreno directory and run the web installer.
One line Docker:
curl -sL tirreno.com/t.yml | docker compose -f - up -d
Manual Docker:
# Create network
docker network create tirreno-network
# Start PostgreSQL
docker run -d \
--name tirreno-db \
--network tirreno-network \
-e POSTGRES_DB=tirreno \
-e POSTGRES_USER=tirreno \
-e POSTGRES_PASSWORD=secret \
-v ./db:/var/lib/postgresql/data \
postgres:15
# Start tirreno
docker run -d \
--name tirreno-app \
--network tirreno-network \
-p 8585:80 \
-v tirreno:/var/www/html \
tirreno/tirreno:latestCompose:
services:
tirreno-app:
image: tirreno/tirreno:latest
ports:
- "8585:80"
volumes:
- tirreno:/var/www/html
networks:
- tirreno-network
depends_on:
- tirreno-db
tirreno-db:
image: postgres:15
environment:
POSTGRES_DB: tirreno
POSTGRES_USER: tirreno
POSTGRES_PASSWORD: secret
volumes:
- ./db:/var/lib/postgresql/data
networks:
- tirreno-network
networks:
tirreno-network:
volumes:
tirreno:Run: docker compose up -d
Access http://localhost:8585/install/ and use database URL postgresql://tirreno:secret@tirreno-db:5432/tirreno.
Click here to launch Heroku deployment.
Access the installer at https://your-domain.com/install/ (for Docker: http://localhost:8585/install/) and provide PostgreSQL database credentials.
Input options:
You can enter credentials in two ways:
-
Database URL (recommended for Docker):
postgresql://tirreno:secret@tirreno-db:5432/tirrenoThe URL will be automatically parsed into individual fields.
-
Individual fields:
- Database username
- Database password
- Database host
- Database port
- Database name
- Admin email (optional)
Testing the database connection:
Before running the full installation, click the Test button to verify your database connection:
- Green button = connection successful
- Red button = connection failed (check credentials)
This allows you to validate credentials without applying the schema.
Installation steps:
When you click Connect, the installer runs these steps:
| Step | Checks |
|---|---|
| Version check | Verifies you have the latest tirreno version |
| Compatibility | PHP version (8.0–8.3), mod_rewrite, PDO PostgreSQL, config folder permissions, .htaccess, cURL, memory limit (128MB) |
| Database params | Validates all required fields are provided |
| Database setup | Tests connection, checks for existing installation, applies schema |
| Config build | Writes config/local/config.local.ini with your settings |
After successful installation:
- Delete the
/installdirectory - Visit
/signupto create your admin account
- Delete the
/installdirectory - Create your admin account at
/signup - Configure the cronjob (see Cronjob setup)
- Apply security hardening (see Security)
After installation, configuration is stored in config/local/config.local.ini.
tirreno can be configured via environment variables or config file settings. Environment variables take precedence over config file settings and are useful for Docker/Heroku deployments.
Required settings:
| Setting | Env Variable | Config Key | Description |
|---|---|---|---|
| Database | DATABASE_URL |
DATABASE_URL |
PostgreSQL connection string (e.g., postgres://user:pass@host:5432/dbname) |
| Site URL | SITE |
SITE |
Base URL for the application (e.g., https://tirreno.example.com) |
| Pepper | PEPPER |
PEPPER |
Password pepper for secure hashing (random string, keep secret) |
Optional settings:
| Setting | Env Variable | Config Key | Default | Description |
|---|---|---|---|---|
| Admin email | ADMIN_EMAIL |
ADMIN_EMAIL |
— | Administrator email address |
| SMTP login | MAIL_LOGIN |
MAIL_LOGIN |
— | SMTP username for sending emails |
| SMTP password | MAIL_PASS |
MAIL_PASS |
— | SMTP password |
| Enrichment API | ENRICHMENT_API |
ENRICHMENT_API |
https://api.tirreno.com |
Enrichment API endpoint |
| Force HTTPS | FORCE_HTTPS |
FORCE_HTTPS |
false |
Force HTTPS redirects |
| Forgot password | ALLOW_FORGOT_PASSWORD |
ALLOW_FORGOT_PASSWORD |
false |
Enable forgot password feature |
| Show email/phone | ALLOW_EMAIL_PHONE |
ALLOW_EMAIL_PHONE |
false |
Enable email/phone display |
| Logbook limit | LOGBOOK_LIMIT |
LOGBOOK_LIMIT |
3000 |
Maximum logbook entries to retain |
Config file only settings (config/config.ini):
| Config Key | Default | Description |
|---|---|---|
DEBUG |
0 |
Debug mode (0=off, 1-3=verbosity levels) |
SEND_EMAIL |
1 |
Enable email sending |
SMTP_DEBUG |
0 |
SMTP debug output |
MIN_PASSWORD_LENGTH |
8 |
Minimum password length |
tirreno uses a built-in cron system. Jobs are configured in config/crons.ini and invoked through a single cron entry:
System crontab entry (run every 10 minutes):
*/10 * * * * /usr/bin/php /absolute/path/to/tirreno/index.php /cronBuilt-in cron jobs (config/crons.ini):
| Job | Schedule | Description |
|---|---|---|
| enrichmentQueueHandler | Every minute | Process IP/email/phone enrichment |
| riskScoreQueueHandler | Every minute | Calculate user risk scores |
| batchedNewEvents | Every minute | Process new incoming events |
| blacklistQueueHandler | Every minute | Process blacklist updates |
| deletionQueueHandler | Every minute | Handle data deletion requests |
| notificationsHandler | Every minute | Send alert notifications |
| totals | Every minute | Update dashboard statistics |
| logbookRotation | 0-10 * * * * | Rotate logbook entries |
| retentionPolicyViolations | 0-10 0 * * * | Check retention policy daily |
| queuesClearer | 0-10 0 * * 2 | Clear stale queues weekly |
Verify cron is running:
# Check cron service
systemctl status cron
# View tirreno cron logs
tail -f /var/log/tirreno-cron.log
# Run cron manually to test
/usr/bin/php /absolute/path/to/tirreno/index.php /cron1. Remove the install directory:
rm -rf /path/to/tirreno/install/The install directory contains setup scripts that could be exploited if left accessible.
2. Set proper file permissions:
# Restrict config directory
chmod 750 config/
chmod 640 config/*.ini
# Restrict sensitive files
chmod 640 composer.json composer.lock
chmod 640 .htaccess
# Ensure logs are not world-readable
chmod 750 assets/logs/
# Make rules directories writable only by web server
chown -R www-data:www-data assets/rules/
chmod 755 assets/rules/core/ assets/rules/custom/3. Verify .htaccess protection:
Ensure your Apache configuration allows .htaccess overrides:
<Directory /path/to/tirreno>
AllowOverride All
Require all granted
</Directory>4. Verify settings file is inaccessible:
# Should return 403 Forbidden or 404 Not Found
curl -I https://your-tirreno.com/config/local/config.local.ini- Use HTTPS with valid SSL/TLS certificates (Let's Encrypt or commercial CA)
- Redirect all HTTP traffic to HTTPS and use HSTS headers
- Place tirreno in a private subnet; database should not be directly accessible from the internet
- For internal deployments, restrict sensor access to known IPs:
<Location /sensor/>
Require ip 10.0.0.0/8
Require ip 192.168.0.0/16
</Location>1. Admin account security:
- Use strong, unique passwords
- Limit the number of admin accounts
- Review access logs regularly
2. Session management:
- Sessions expire after inactivity (default: 30 minutes)
- Sessions invalidated on password change
- Secure session cookies (HttpOnly, Secure, SameSite)
1. Application log files:
tirreno writes logs to the assets/logs/ directory:
| Log file | Description |
|---|---|
error.log |
Application errors and exceptions |
blacklist.log |
Blacklist events — records when users are automatically blacklisted by rules |
sql.log |
SQL queries (disabled by default, enable with PRINT_SQL_LOG_AFTER_EACH_SCRIPT_CALL = 1) |
Monitor blacklist.log to track automatic fraud detection:
tail -f assets/logs/blacklist.log2. Logbook (UI):
- Monitor the Logbook page for API request patterns
- Check failed events, verify your security settings
- Review error rates and unusual activity
3. Monitor for suspicious activity:
- Failed login attempts (brute force detection)
- Unusual API request patterns
- Error rate spikes
- Database query anomalies
4. Log retention:
- Retain logs for compliance requirements (typically 90 days to 1 year)
- Secure log storage (separate from application)
- Regular log review and alerting
Use this checklist for production deployments:
- Install directory removed
- File permissions restricted
- Settings file inaccessible from web
- Database user has minimal privileges
- HTTPS enforced with valid certificate
- Admin passwords strong and unique
- Logging enabled and monitored
- Error messages don't expose sensitive information
When moving tirreno to a new domain or URL, update the SITE configuration:
Option 1: Configuration file
Edit config/local/config.local.ini:
[globals]
SITE = https://new-domain.comOption 2: Environment variable
Set the SITE environment variable:
export SITE=https://new-domain.comFor Docker deployments, update the environment in docker-compose.yml:
environment:
- SITE=https://new-domain.comMultiple domains:
tirreno supports multiple domains (comma-separated):
SITE = https://primary.com,https://secondary.comAfter changing the URL:
- Clear any cached sessions
- Update your application's tracker endpoint to point to the new URL
- Verify the Logbook receives events at the new location
Exporting the database:
# Full database backup
pg_dump -U tirreno_app -d tirreno -F c -f tirreno_backup.dump
# Schema only
pg_dump -U tirreno_app -d tirreno --schema-only -f tirreno_schema.sql
# Data only
pg_dump -U tirreno_app -d tirreno --data-only -f tirreno_data.sqlImporting to new server:
# Create database on new server
createdb -U postgres tirreno
# Restore from backup
pg_restore -U tirreno_app -d tirreno tirreno_backup.dump
# Or restore from SQL
psql -U tirreno_app -d tirreno < tirreno_schema.sql
psql -U tirreno_app -d tirreno < tirreno_data.sqlVerify migration:
# Check table counts
psql -U tirreno_app -d tirreno -c "SELECT COUNT(*) FROM event_account;"
psql -U tirreno_app -d tirreno -c "SELECT COUNT(*) FROM event;"To check if a new version is available:
- Go to Settings in the left menu
- Find the Check for updates section showing your current version
- Click Check to see if updates are available
tirreno periodically releases updates with new features and security patches.
- Backup your database before any update
- Check the changelog for breaking changes at github.com/tirrenotechnologies/tirreno/releases
- Test in staging if possible before updating production
cd /path/to/tirreno
git fetch origin
git pull origin mainIf you have local changes, stash them first:
git stash
git pull origin main
git stash popcomposer update tirreno/tirrenodocker pull tirreno/tirreno:latest
docker-compose down
docker-compose up -d- Remove the installation folder:
rm -rf /path/to/tirreno/install - Clear any application cache if applicable
- Run database migrations if required (check release notes)
- Verify the application is working correctly
- Check the Logbook for any errors
Common installation errors:
| Error | Solution |
|---|---|
| "Connection refused" | PostgreSQL not running or wrong port |
| "Authentication failed" | Wrong database credentials |
| "Database does not exist" | Create database first: createdb tirreno |
| "Permission denied" | Grant permissions: GRANT ALL ON DATABASE tirreno TO tirreno_app |
| "PDO PostgreSQL driver" | Install: apt install php-pgsql |
| "Config folder permission" | chmod 755 config && chown www-data:www-data config |
| "Memory limit" | Set memory_limit = 128M in php.ini |
| Invalid hostname (TN8001) | The application was accessed using a hostname that doesn't match the configured allowed host(s). This is a security measure to prevent host header attacks. The user must access the application through the correct URL defined in the configuration. |
| Failed DB connect (TN8002) | The application cannot establish a connection to the PostgreSQL database. This could be caused by incorrect database credentials, the database server being down, network issues, or misconfigured connection parameters in the config file. |
| Incomplete config (TN8003) | The application's configuration file (config/local/config.local.ini) is missing required settings or environment variable overrides are not properly set. The application cannot start without complete configuration. |
PHP version check:
tirreno requires PHP 8.0–8.3. Verify your PHP version:
# Check PHP CLI version
php -v
# Check PHP version used by web server
php -r "echo PHP_VERSION;"
# Check all required extensions
php -m | grep -E "pdo_pgsql|curl|json|mbstring"If using multiple PHP versions, ensure Apache/Nginx uses the correct one:
# Check PHP module loaded by Apache
apachectl -M | grep php
# For PHP-FPM, check the socket path in your nginx/apache config
ls -la /run/php/Note: The API uses form-urlencoded format, not JSON.
Events not appearing in tirreno:
- Check API key: Ensure your API key matches the one in tirreno settings
- Verify endpoint: Confirm you're posting to
/sensor/(with trailing slash) - Check Logbook: Look for failed requests in the Logbook page
- Test with curl:
curl -v -X POST https://your-tirreno.com/sensor/ \
-H "Api-Key: your-api-key" \
-d "userName=test" \
-d "ipAddress=1.2.3.4" \
-d "url=/test" \
-d "eventTime=2024-12-08 01:01:00.000" \
-d "eventType=page_view"Check response codes:
| Code | Meaning |
|---|---|
| 200 | Success |
| 401 | Invalid or missing API key |
| 400 | Missing required parameters |
| 429 | Rate limited |
| 500 | Server error |
The Logbook shows all incoming API requests:
- Access: Navigate to Logbook in the left menu
- Columns:
- Source IP: Where the request came from
- Timestamp: When the request was received
- Endpoint: Which API endpoint was called
- Status: HTTP response code
- Filtering: Use the search box to filter by any column
- Chart: Shows request volume over time
What to look for:
- 401 errors: API key issues
- 400 errors: Missing or invalid parameters
- Gaps in traffic: Network or integration issues
- Unexpected IPs: Verify your application servers
Manual cron:
php /home/user/tirreno/index.php /cron
Common cron issues:
| Issue | Solution |
|---|---|
| Jobs not running | Check system cron is enabled: systemctl enable cron |
| "No jobs to run" | Normal if no jobs scheduled for current minute |
| Permission denied | Ensure www-data can read config files |
| Database errors | Check config/local/config.local.ini is readable |
| Resource | URL |
|---|---|
| Live Demo | play.tirreno.com (admin/tirreno) |
| Documentation | docs.tirreno.com |
| Resource center | tirreno.com/bat |
| Developers Guide | github.com/tirrenotechnologies/DEVELOPMENT.md |
| GitHub | github.com/tirrenotechnologies/tirreno |
| GitLab Mirror | gitlab.com/tirreno/tirreno |
| Docker Hub | hub.docker.com/r/tirreno/tirreno |
| Docker Repo | github.com/tirrenotechnologies/docker |
| PHP Tracker | github.com/tirrenotechnologies/tirreno-php-tracker |
| Python Tracker | github.com/tirrenotechnologies/tirreno-python-tracker |
| Node.js Tracker | github.com/tirrenotechnologies/tirreno-nodejs-tracker |
| Community Chat | chat.tirreno.com |
| Support Email | ping@tirreno.com |
| Security Email | security@tirreno.com |
If you have found a mistake in the documentation, no matter how large or small, please let us know by creating a new issue in the tirreno repository.
tirreno and this documentation are licensed under the GNU Affero General Public License v3 (AGPL-3.0).
The name "tirreno" is a registered trademark of tirreno technologies sàrl.
tirreno Copyright (C) 2026 tirreno technologies sàrl, Vaud, Switzerland.
't'