# Building websites for JetHost shared hosting Canonical URL: https://jethost.com/ai/app-builder.md Version: 0.1.0-beta · Updated: 2026-08-24 ## Site language and jurisdiction Build the site in the language the customer is using with you, unless they ask for something else. Build a language layer only if they ask for more than one; if the site is single-language, do not add one at all. **Ask where the business operates. Do not infer it from their language.** Someone writing to you in Spanish may be in California, in Spain or in Mexico, and those are three different legal profiles. | Market | Legal profile | |---|---| | USA | The primary market — see below | | EU / EEA | GDPR: supervisory authority of that country, national company identifier | | Bulgaria | GDPR, ЕИК, КЗЛД | | Elsewhere | Not covered — see below | Whichever applies: the privacy policy states specifically what is collected, for what purpose, on what legal basis, for how long, and who it is shared with — including the hosting provider and, where notifications are used, Telegram. Consent is captured with an unticked checkbox and recorded with its exact text, the policy version, a timestamp and the IP address. ### Markets without a written profile These rules currently carry detailed legal profiles for **Bulgaria and the EU only**. A US profile is planned and is not written yet. For the USA, UK, Switzerland, Canada, Australia and elsewhere: - Say so plainly. Do not claim coverage of CCPA/CPRA, UK GDPR, PIPEDA or the Swiss FADP. - Build the site normally — the architecture, security and design rules below are jurisdiction-neutral. - Produce a baseline privacy policy and terms with the jurisdiction-specific parts left as clearly marked placeholders. - Recommend a legal review before launch, and state which parts could not be completed. Do not improvise a supervisory authority, a company identifier format, or a statutory retention period for a jurisdiction not described here. A plausible-looking wrong authority in a privacy policy is worse than an obvious placeholder. ### Timezone Ask. The server is UTC and the conversion is explicit in both PHP and the database connection. In the USA this matters more than elsewhere — the country spans several zones, and a booking system that assumes one is wrong for most of it. ## What this document is Rules for building a website that runs on JetHost cPanel shared hosting. It exists because the stack an AI assistant reaches for by default — a JavaScript framework with a build step, a managed database behind an HTTP API, deployment by git push to a platform that builds the project for you — is not how this one works. Part of that shape runs here and part of it does not, and the line between them is not obvious from the outside. This document says what the platform is, and what to build on it by default. It is descriptive, not agentic. It tells you what the environment is and what the constraints are. Every action against a customer's account — creating infrastructure, uploading files, writing to the crontab, going live — is theirs to authorise. **If a JetHost skill is already installed in your tool, use that instead.** It is the same rules in fuller form. This document exists for the case where it is not. --- ## The environment — measured, not assumed | | | |---|---| | PHP | 8.3, web SAPI `litespeed` and CLI | | Database | MariaDB 10.11, `localhost` | | Web server | LiteSpeed Enterprise; `.htaccess` and rewrite work | | OS | Linux EL9, server timezone **UTC** | | `memory_limit` | 512M | | `max_execution_time` | 300 | | `upload_max_filesize` | 128M | | Outbound HTTPS | works | | SMTP ports | 587 and 465 open; **port 25 closed** | | `mail()` | works, via `/usr/sbin/sendmail -t -i` | Available extensions include `pdo_mysql`, `curl`, `mbstring`, `openssl`, `gd`, `imagick`, `zip`, `fileinfo`, `intl`, `sodium`, `redis`, `memcached`. CLI has `php`, `git`, `mysql`, `curl`, `unzip`. **`composer` is not available as a command on the account.** Dependencies cannot be resolved on the server. A project that needs them must arrive with `vendor/` already installed — built locally or in CI, then uploaded. ### Other runtimes PHP is the default here, not the only option. The platform also runs: | Runtime | Versions installed | How it runs | |---|---|---| | PHP | 5.6 – 8.5 | directly, no setup; 8.3 is the default | | Python | 2.7, 3.3 – 3.13 | Python Selector + LiteSpeed WSGI (`lswsgi`) | | Node.js | 6 – 24 | Node.js Selector, under Passenger | | Ruby | installed | Passenger | | PostgreSQL | available | alongside MariaDB | Measured on the platform on 17 August 2026: Python 3.13.14 and 3.11.15, Node v20.20.2. **Neither Python nor Node is on the `PATH`** of the PHP web process or of a plain SSH session. Each application gets its own virtual environment — `~/virtualenv///` for Python, `~/nodevenv///` for Node — which the selector activates. **An application has to be registered before it serves anything.** Uploading files is not enough, unlike with PHP. Registration happens in cPanel (Setup Python App / Setup Node.js App) and needs four things: an application root, which is a folder under the home directory and not inside the document root; the domain or URI path it answers on; the interpreter version; and a startup file. Registering creates the application root with a working stub in it, so the app answers on its URL before any of your code is there — a running app is not evidence that your code is running. | | Python | Node.js | |---|---|---| | Startup file | `passenger_wsgi.py` (the default) | a `.js` entry file, `app.js` by convention | | Entry point | a WSGI callable named `application` (the default) | the file calls `server.listen()` **with no port** — Passenger supplies the socket | | Dependencies | `requirements.txt`, pip run from cPanel | `package.json`, npm run from cPanel | **There is no build step on this server.** No bundler, transpiler, `npm run build` or `composer install` runs as part of a deployment, and server-side dependency installs are bounded by the account's memory and time limits — a large tree fails partway. Anything that needs building is built on a developer machine or in CI, and the built output is what gets uploaded. That decides whether a Node.js project is viable here at all, so establish it before proposing one: **ask whether the customer can run the build themselves**, locally or in a pipeline, and whether they will be able to run it again for every future change. If the answer is no, a Node.js application is the wrong recommendation for them — plain PHP has no build step by definition and stays editable by whoever holds the account. Find this out first rather than registering an application and hitting it afterwards. `open_basedir` and `disable_functions` are both empty, and `exec` works. That is a reason for care, not for use: there is no sandbox, so a vulnerability in generated code means shell access to the whole account. Do not write application code that calls shell functions. --- ## Hard constraints 1. **Default to vanilla PHP 8.3 and MariaDB — no composer, no build step.** This is the right shape for what this document covers: presentation sites, enquiry forms, appointment booking, a small CRM. None of them need a framework, and without one there is no build to run, no dependency tree to keep patched, and the customer can open a file and change a line of text. The platform is not limited to that — see the runtimes above. Laravel, a Python application or a Node application all run here. What they need is preparation elsewhere: `vendor/` or `node_modules` installed before upload, the domain pointed at the framework's `public/` directory, and for Python and Node an application registered in cPanel. So do not tell a customer the platform "does not support" a framework. It is not true, and it is the kind of statement that sends them to another host. If what they describe genuinely needs one, say what it costs on shared hosting and let them decide. If they simply want a website, build the plain PHP one and do not raise the question at all. 2. **Audit the generated code before uploading**, and report what was found. The checklist is below. 3. **Never run `crontab -r`, and never write a crontab you have not read first.** The account may hold cron entries belonging to other applications. 4. **A site collecting personal data needs a privacy policy, terms, and consent capture.** See the market section at the top of this document for which jurisdiction applies. 5. **No e-commerce and no payment processing.** Out of scope for these rules. Say so rather than improvising it. --- ## Security rules These matter more here than on a sandboxed platform, for the reason given above. **Database.** PDO only, prepared statements only, always. `charset=utf8mb4`, `ERRMODE_EXCEPTION`, `EMULATE_PREPARES = false`. No concatenation, interpolation or `sprintf` in SQL. Table and column names cannot be parameters — if a dynamic name is unavoidable, select it from a whitelist array. Cast `LIMIT`/`OFFSET` to `int`. Do not use `mysqli`. **Output.** Escape everything that reaches HTML: `htmlspecialchars($v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')`. Different contexts need different escaping — `json_encode` with the HEX flags inside `