9 directories, 58 files

tinai

Home / tinai
# TinAI

Self-hosted AI chat application built with plain PHP 8, JavaScript and CSS — no frameworks, no build step, no Composer. Users, sessions and all configuration (including provider API keys) live in a single SQLite database at `db/app.db` and are managed through the built-in admin panel.

Requires PHP 8 with PDO SQLite.

## Deployment

Deploys run through GitHub Actions (`.github/workflows/deploy.yml`). A deploy mirrors a chosen commit to the web server over FTPS (explicit TLS on port 21): changed files are uploaded first, then files that are not part of the commit are deleted from the server, so the server always ends up matching the commit.

The mirror never touches:

| Path | Reason |
|---|---|
| `db/` | SQLite database (users, sessions, config, API keys) |
| `php_sessions/` | PHP session data, so logins survive deploys |
| `.htaccess` | server-side Apache config, not in the repository |
| `php.ini` | server-side PHP config |
| `resources/`, `AGENTS.md`, `TASKS.md` | development-only files |

### One-time setup

Add four secrets under **Settings → Secrets and variables → Actions → Repository secrets**:

| Secret | Value |
|---|---|
| `FTP_HOST` | Your domain, e.g. `example.com` (no scheme, no port). The workflow resolves the server's certificate-matching hostname automatically via reverse DNS |
| `FTP_USER` | FTP username — cPanel-style hosts want the email form, `user@example.com` |
| `FTP_PASSWORD` | FTP password |
| `FTP_DIR` | Directory to deploy into, e.g. `public_html/tinai` (relative to the FTP login directory) |

### Running a deploy

1. Open the **Actions** tab, select the **Deploy** workflow, click **Run workflow**.
2. Paste the full 40-character commit SHA (or a tag/branch name) into the `ref` field and run.
3. Check the log: uploads happen first, deletions of obsolete files last.

Before the first run, back up `db/app.db` on the server.

### Notes

- The workflow speaks explicit FTPS: the plain `ftp://` scheme plus `ftp:ssl-force`. The `ftps://` scheme must NOT be used — lftp treats it as implicit TLS (TLS before the banner), which shared-host FTP servers such as Pure-FTPd reject with a TLS handshake error. Certificate verification is left fully enabled: before connecting, the workflow resolves your domain's IP, reverse-resolves it to the server's real hostname (the name shared-host certificates are issued for), and verifies that name still points at the same IP. If the server has no reverse DNS entry, the deploy fails certificate verification.
- Everything else on the server that is not part of the commit is deleted. To protect additional paths, add more `--exclude` entries to the `mirror` command.
- The `resources/deepseek/` proxy sub-app is inside the excluded `resources/` tree: it is neither uploaded nor deleted by the workflow, so a copy already on the server stays as-is and does not receive updates.
- To automate deploys later (on push to main or on tags), replace the `on: workflow_dispatch` block in the workflow.
❓
README.md ×
Type: Unknown, text/plain
2.94 Kilobytes
Last Modified 2026-11-04 09:48:28
⬇ Download File