# Install Notifier On A New Server

Target assumption: Ubuntu 24.04 or similar, nginx, PHP 8.3 FPM, SQLite.

## 1. Install Packages

```bash
sudo apt update
sudo apt install -y nginx php8.3-fpm php8.3-cli php8.3-sqlite3 php8.3-curl php8.3-mbstring php8.3-gd php8.3-xml sqlite3 unzip certbot python3-certbot-nginx cron ufw
```

Required PHP modules observed on the current server:

- `curl`
- `mbstring`
- `gd`
- `sqlite3`
- `pdo_sqlite`
- `json`
- `openssl`
- `session`
- `fileinfo`
- `posix`

## 2. Place Files

```bash
sudo mkdir -p /workspace
sudo unzip notifier-full-migration-2026-06-12.zip -d /workspace
sudo chown -R agent:www-data /workspace/notifier
sudo find /workspace/notifier -type d -exec chmod 755 {} \;
sudo find /workspace/notifier -type f -exec chmod 644 {} \;
sudo chmod 600 /workspace/notifier/config.php
sudo chmod 664 /workspace/notifier/database.sqlite
sudo chmod -R 775 /workspace/notifier/uploads /workspace/notifier/logs
sudo chmod +x /workspace/notifier/scheduler.php /workspace/notifier/scripts/cron-health-check.sh /workspace/notifier/scripts/migrate.php
```

If the service user is different from `agent`, update ownership and the cron entries accordingly.

## 3. Restore Or Confirm Config

Important values live in `config.php`.

Required config keys:

- `telegram.bot_token`
- `telegram.chat_id`
- `telegram_test.bot_token`
- `telegram_test.chat_id`
- `auth.password`
- `auth.api_token`
- `display_timezone`
- `app_url`
- `upload_path`
- `database.path`
- `scheduler.lock_file`
- `scheduler.lock_timeout`
- `scheduler.batch_size`
- `scheduler.rate_limit_ms`
- `cron_health.*`
- `mailer_send.api_key`

For the current deployment, `app_url` is `https://www.tonki.dev/notifier`. On the new server, update it if the domain or path changes. Confirmation buttons in Telegram depend on this value.

## 4. Nginx Site

Current production routing serves `/workspace` as the web root and gives Notifier explicit clean URL/API routing.

Use this inside the HTTPS server block:

```nginx
root /workspace;
index index.php index.html index.htm;

location ~ ^/notifier/api(/.*)?$ {
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    fastcgi_param SCRIPT_FILENAME /workspace/notifier/api/index.php;
    include fastcgi_params;
    fastcgi_param REQUEST_URI $request_uri;
    fastcgi_param QUERY_STRING $query_string;
}

location /notifier/ {
    try_files $uri $uri/ /notifier/index.php$is_args$args;
}

location / {
    try_files $uri $uri/ =404;
    autoindex on;
}

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Robots-Tag "noindex, nofollow" always;
```

Then:

```bash
sudo nginx -t
sudo systemctl reload nginx
```

## 5. Database Migrations

The package includes the live SQLite DB, so migrations should already be applied. Verify:

```bash
cd /workspace/notifier
php scripts/migrate.php
php scheduler.php --status
```

Expected schema migrations count on this server: 6.

## 6. Cron

Install under the app user:

```cron
# notifier scheduler (runs every minute)
* * * * * /usr/bin/php /workspace/notifier/scheduler.php >> /workspace/notifier/logs/scheduler.log 2>&1
*/10 * * * * /workspace/notifier/scripts/cron-health-check.sh >> /workspace/notifier/logs/cron-health.log 2>&1
```

Install safely:

```bash
(crontab -l 2>/dev/null; cat <<'EOF'
# notifier scheduler (runs every minute)
* * * * * /usr/bin/php /workspace/notifier/scheduler.php >> /workspace/notifier/logs/scheduler.log 2>&1
*/10 * * * * /workspace/notifier/scripts/cron-health-check.sh >> /workspace/notifier/logs/cron-health.log 2>&1
EOF
) | crontab -
```

## 7. Firewall

The current server uses UFW with default incoming deny and allows:

- `22/tcp`
- `80/tcp`
- `443/tcp`

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
```

## 8. TLS

The current server uses Certbot/Let's Encrypt for `tonki.dev` and `www.tonki.dev`. On the new server, reissue certificates after DNS cutover:

```bash
sudo certbot --nginx -d tonki.dev -d www.tonki.dev
```

Do not rely on copied TLS private keys unless you intentionally migrate `/etc/letsencrypt` securely.
