# Websites and apps

> Source: https://test-allsweb.allsweb.net/sixpanel/docs/websites-and-apps
> Markdown for agents: https://test-allsweb.allsweb.net/sixpanel/docs/websites-and-apps.md
> Publisher: AllsWeb (www.allsweb.com)

Part of: SixPanel documentation

**What this page is for:** host something other than 6amMart on this server — a
static website, a Node.js app, a PHP website, a WordPress site, or a website an AI
model builds from your description. Each one is a **project** in the Projects list, with
its own menu. Nothing about your 6amMart projects changes when you add one.

**You need**

- A web address for it — a name on a domain in your Cloudflare account, or any
  domain you can point at this server. It is optional when you create the project:
  give it there and the panel connects it as soon as the project is set up, or
  leave it empty and connect it afterwards on **Domain & HTTPS**.
- The code: a folder on your computer, a ZIP, or a git repository (an `https://`
  address). WordPress and Create with AI need no code.

---

## The five kinds

| Kind | For | What runs | Database |
|---|---|---|---|
| **Static website** | HTML/CSS/JS, or a React / Vite / Astro site built to files | nginx alone — no process | none |
| **Node.js app** | Next.js, Nuxt, SvelteKit, Remix, Express, NestJS… | one Node.js process (none at all for a static build) | None or MariaDB |
| **PHP website** | Laravel, Symfony, CodeIgniter, plain PHP | its own PHP-FPM pool, started on demand | None or MariaDB |
| **WordPress** | a WordPress site | PHP-FPM with a page cache in nginx | MariaDB, created for you |
| **Create with AI** | a website an AI model writes in Next.js | like a Node.js app | None or MariaDB |

Each project gets only what its kind needs. A static website has no PHP pool, no
process and no database; a PHP website has no Node.js process. This server runs
one PHP version and one Node.js version, shown on the pages that use them.

Every project runs as its own Linux account (`site-<short id>`) in its own folder
(`/var/www/_sites/<short id>`), so one website cannot read another's files, and a
Node.js app only ever listens on the server itself — visitors reach it through
nginx and Cloudflare, never directly.

## Create one

1. Open **Projects** and press **Create a new project**. On a server with no
   project yet the page shows the choices straight away, and **New project** on
   **Home** opens the same dialog.
2. Choose the kind.
3. Everything else is on one screen:
   - **Name** — the label you will recognise it by. The short id it derives is
     shown under it (`kevins-blog`): it names the project's account and folder,
     and never changes.
   - **Web address** — optional. The address the project should answer on, like
     `blog.example.com`; leave it empty to add it later on **Domain & HTTPS**. The
     dialog suggests names on the domains this server already uses, and says
     straight away when a name sits too deep for Cloudflare's free certificate
     (offering the spelling that works), when the domain is not on Cloudflare, or
     when it is on a Cloudflare account this panel cannot edit — in those two
     cases with the A record to create yourself, proxied when it is on
     Cloudflare.
   - Node.js, PHP and Create with AI: **Database** — **No database** (the default)
     or **MariaDB** if the app stores data. You can add one later on the
     **Database** page.
   - WordPress: the **site title** (it follows the name), the **administrator
     username**, the **administrator email** and the **language**. The username
     is suggested from your email address — never `admin`, the first name login
     bots try; if you type a guessable one, the dialog says so and offers the
     suggestion with one press. The email is filled in with the one this server
     has under **Settings → General**, and the language follows the panel's.
   - Create with AI: **describe the website**. If no AI provider is set up yet,
     the dialog says so, with a link to **AI → Providers**. You can create the
     project anyway: the description is kept, and Tia starts on it once a
     provider is added and the site has its address.
4. Press **Create the project**. The panel makes the account, the folder and — if
   you chose one — the database. Then:
   - **With a web address**, it connects it by itself: the DNS record (always
     proxied), the HTTPS certificate, and what the kind does once it has an
     address — WordPress installs itself, and Create with AI starts its first
     build (Tia's, when a provider is set up; a starter page otherwise). You
     land on **Domain & HTTPS** while it runs.
   - **Without one**, you land on the kind's next step: **Deploys** for code,
     **Domain & HTTPS** for WordPress, or **Build with AI**.

If another job is running — a backup, an install, an update — the create queues
behind it instead of being refused: the dialog says **Queued — starts as soon as
"…" finishes** and follows it when its turn comes. You can close the dialog, or the
browser tab: the project is on the Projects page meanwhile, and a web address you
gave it is connected as soon as the create finishes — the server starts that itself.

HTTPS needs an email address for its certificate. If this server has none yet, the
web address is still saved on the project and the dialog says where to set the
email (**Settings → General**); then press **Connect & get HTTPS** on **Domain &
HTTPS**.

Projects → the project's card opens its own menu. Only the pages its kind uses are
shown.

## Static website

1. **Deploys** — drop the folder or its ZIP anywhere on the page, or choose
   **Upload a folder** (no need to zip it), **Upload a ZIP** or **Connect git**.
2. The panel finds the first `index.html` and serves that folder. If it guessed
   wrong, change **Document root** on **Settings**.
3. **Domain & HTTPS → add the address.** The site is live on it with HTTPS.

What happens by itself:

- A single-page app (React Router, Vue Router…) is recognised and every unknown
  path is answered with `index.html`; otherwise a `404.html` is used for missing
  pages. Both are on **Settings**.
- A source folder with a `build` script (Vite, Create React App, Astro…) is built
  on the server, and only the output is published.
- Every deploy clears the Cloudflare cache for the site's addresses. **Empty the
  cache** on **Overview** does it by hand.

## Node.js app

1. **Deploys** — drop the folder or ZIP on the page, or connect git. Until the
   address answers over HTTPS the first version is only read: the panel finds the
   framework, imports your `.env` files and waits, and **Deploys** shows what is
   left as a checklist — **Files read**, **Environment**, **Domain**. There is
   nothing to tick: the build waits so that it sees your variables and the address
   the app runs at.
2. **Environment** — the variables your app reads. Any `.env`, `.env.production`,
   `.env.local` or `.env.production.local` in your files is imported
   automatically; `.env.example` shows what is still missing. **Import a .env
   file** takes a pasted or chosen file.
3. **Domain & HTTPS** — add the address. The moment it answers over HTTPS, the
   app is built and started by itself; the checklist on **Deploys** shows the
   build, and if it fails, where it stopped, with **View log** and **Build again**.

Once the address is connected, an upload or a push builds and goes live at once.

The panel detects the framework and the package manager (npm, pnpm, yarn or bun)
and fills in the install, build and start commands. All three are editable on
**Settings**.

A build that produces only files (a Vite or Create React App site, `next export`,
an Astro static site) is served by nginx with **no process running at all**.

A server app deploys **with no downtime**: the new version starts beside the old
one, must answer on the **Health check path**, and only then does nginx switch
visitors over. A version that fails to start never goes live — the old one keeps
serving.

The old version is then stopped the way a server expects: your app receives
`SIGTERM` — also when npm, pnpm or yarn started it — and has 15 seconds to finish
what it is doing before it is ended. **Stop** and **Restart** stop it the same way,
and a stop is never reported as a failure, whatever exit code your app answers it
with.

`NEXT_PUBLIC_…` and `VITE_…` values are written into the browser code at build
time, so changing one needs **Build again**; other variables need only a restart
(**Overview → Restart the app**).

When the app has a database, it receives `DATABASE_URL` and `DB_HOST`, `DB_PORT`,
`DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD` and `DB_SOCKET` in its environment.
There is nothing to copy.

`PORT` and `HOST` are the panel's: every version runs on its own port and nginx
sends visitors to it. A `PORT` in your `.env` is not imported, and **Environment**
lists both as set by the panel.

## PHP website

1. **Deploys** — folder, ZIP or git.
2. The document root is found from the framework (`public/`, `web/`, `webroot/`
   or the top folder). **Composer** runs when there is a `composer.json`.
3. **Domain & HTTPS** — add the address.

A PHP website is updated **in place**: files a new version no longer ships are
removed, and folders the app writes itself — list them under **Kept between
deploys** on **Settings** (uploads, `storage`) — are never touched.
**Commands after each deploy** runs your own lines as the site's account, for
example `php artisan migrate --force`.

For a database, the **Database** page shows the name, user and password, and
**Write these into the app's .env** puts them into the `.env` in the site folder in
one press — `DB_HOST`, `DB_PORT`, `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD` and
`DB_SOCKET` (plus `DB_CONNECTION=mysql` when the file had none, or had Laravel's
`sqlite` default). Every other line of the file stays as it was. Host `localhost`
uses the local socket — the fastest way in. **Change password** updates that `.env`
too, as long as it names this site's database.

The **PHP** page sets this site's limits (memory, upload size, execution time,
input variables, time zone, display errors, disabled functions, extra `php.ini`
lines) and its worker pool. Each field shows its default, and a field left empty
goes back to it. Extensions are server-wide: the list shows what is installed, and
searching finds one to add — installing it makes it available to every PHP site.
The ones SixPanel needs cannot be removed.

## WordPress

1. Create it (title, administrator, language) — and give its web address in
   the same dialog if you have it: WordPress then installs itself on that address
   as soon as it is connected, in the language you chose, with the database
   already connected.
2. No address yet? Add it later on **Domain & HTTPS**; the install starts then.
3. **WordPress → Open WordPress** signs you in as the administrator with a
   single-use link — no password needed. **Show the password** shows it if you
   want it.

The **Deploys** page is where WordPress changes:

- **Updates** for core, plugins and themes: the card says what waits (*WordPress
  6.9, 2 plugins*) and **Update everything** is its main button. A **restore
  point** (database and files) is taken before every update and every deploy; the
  last three are kept under **History & rollback**, and **Restore** puts the site
  back. Putting one back first keeps what is there now as a restore point of its
  own, the site's scheduled jobs wait while it runs, and a restore that stops part
  way puts that copy back — never a site that is half of each. A temporary login's
  restore points never push out yours. **Take a restore point now** takes one by
  hand.
- **Deploy your own theme or plugin** — from a ZIP (the same file WordPress takes
  under *Add New → Upload*), a folder, or git. See [Your own theme or plugin](#your-own-theme-or-plugin).

The **WordPress** page:

- **Plugins and themes** — activate, deactivate, install from wordpress.org,
  delete (a plugin is switched off first; its settings stay in the database for a
  reinstall), update one at a time, automatic updates.
- **Page cache** in nginx: visitors who are not signed in get a stored page;
  anyone signed in, commenting, or with a WooCommerce cart gets a fresh one. It
  is cleared the moment you publish or edit.
- **Security** — on by default: the file editor inside WP Admin is off,
  `xmlrpc.php` is blocked, PHP never runs from the uploads folder, sign-in is
  limited to one attempt a second per address, visitors cannot list who writes
  there (`?author=` and the REST API's user list, however the address is spelled —
  and the administrator's public name is the site's, never the login), and the
  WordPress version is hidden. The file editor, `xmlrpc.php`, the sign-in limit and
  the user listing are switches; the uploads rule and the hidden version always hold.
- **Tools** — debug log, maintenance mode, search and replace across the database
  (**Count matches** shows what would change before anything does), and a new
  administrator password.

Scheduled posts publish on time even when every page is cached: WP-Cron runs from
a server timer every five minutes (the first row on **Cron jobs**), not from
visitors.

### Your own theme or plugin

**Deploys → Deploy your own theme or plugin** puts the code you write yourself on
the site — a ZIP, a folder, or its git repository (**Connect git**, then one button
or every push deploys it). Every deploy:

1. reads what the files are, the way WordPress does: a `style.css` with a
   `Theme Name:` line is a theme, a PHP file with a `Plugin Name:` line is a
   plugin. A repository that holds `wp-content/` (or `themes/` and `plugins/`)
   deploys each theme and plugin in it — never `uploads/` or `mu-plugins/`. A full
   marketplace download (documentation, licence and the ZIP inside) is recognised,
   and the installable ZIP in it named; nothing is changed until a theme or plugin
   is found;
2. takes a restore point;
3. replaces that theme's or plugin's folder in `wp-content` as a whole, the way
   WordPress's own updater does. WordPress itself, the uploads and every other
   plugin stay as they are;
4. turns it on, unless you untick it: a plugin is activated, a theme becomes the
   site's theme (when the deploy brings exactly one);
5. loads WordPress with it and opens the site's address. If WordPress no longer
   loads, or the site answers with a server error it did not give before, the code
   that was there before is put back by itself and the deploy says why.

The folder is the one you name in the **Connect git** window, else the folder of
the theme or plugin already installed under the same name (so its settings stay
its own), else the ZIP's own folder, its Text Domain, or the repository's name.
The repository's files are used as they are — commit what a build produces.
## Create with AI

1. **Projects → Create a new project → Create with AI**: name it and, if you
   like, describe the website. The panel sets up a Next.js project and installs it straight away, so
   it is ready the moment it exists.
2. **Domain & HTTPS** — add the address. Every change is built and published there.
3. **AI** (in the main menu) — add the provider whose model builds the site (below).
   One list serves every project.
4. As soon as all three are in place — in any order — Tia writes the first
   version from your description, and the panel builds it and publishes it. A
   description saved at create starts by itself when the last piece arrives.
5. Ask for changes in the chat. Each message is one change: Tia edits the
   files, the panel builds and publishes, and the live site appears beside the
   chat. **Stop** ends a change while it is being made: nothing more is sent to
   Tia, and nothing further goes live. **Undo** puts back the files a change
   touched and builds again — a change that failed or was stopped half-way
   included. A change can be undone while no later change has touched the same
   files; undo the later one first.

### Working in the chat

- The chat says what is still missing — a domain, an AI provider — with the button
  that fixes it.
- **Attach** images, PDFs or text files, paste a screenshot, or drop files on the
  box. Send your logo and photos and say where they go ("use this as the logo"); send
  a screenshot of a design you like as a reference for colours and layout. Images
  are shrunk in your browser before they are sent, and one message's attachments
  may add up to 20 MB. Attached files stay private on this server — only what
  Tia puts into the site is published.
- After each change Tia offers up to three ideas for the next one. Press one to
  put it in the box, change it if you like, and send. **Ctrl + Enter** (⌘ + Enter
  on a Mac) sends.
- The preview beside the chat shows the live site at desktop, tablet and phone
  width.
- Claude (and Anthropic-compatible providers) read PDFs; an OpenAI-compatible
  provider takes images and text files.

If a build fails, the error goes back to Tia, who gets two tries to fix it
before the chat reports the failure — with the reason, under the change. When
Tia adds an npm package, the panel updates `package-lock.json` itself (every build
installs exactly what it lists), and a package or version that does not exist goes
back to Tia to fix. The source Tia works on is on **Files**, where you can
edit it too. Restoring that source from a backup ends **Undo** for the changes made
before it.

### AI providers

**AI** in the main menu keeps a list of providers; the one marked **in use** answers
every chat. Add one from a starting point, or type your own:

| API format | Use it for |
|---|---|
| **Anthropic (Claude)** | Claude with your own key from console.anthropic.com |
| **OpenAI-compatible** (`/chat/completions`) | OpenAI, OpenRouter, Google Gemini, DeepSeek, Groq, Mistral, xAI, a gateway such as LiteLLM or OmniRoute, or a model served on this server (Ollama) |
| **Anthropic-compatible** (`/messages`) | a gateway that speaks Anthropic's API |

- **Base URL** is the address before `/chat/completions` (or `/messages`) — for
  example `https://openrouter.ai/api/v1`. Pasting the whole endpoint also works.
  It must be `https://`; plain `http://` is accepted only for a model on this
  server, like `http://127.0.0.1:11434/v1`, which needs no key.
- The models load by themselves once the key is in (**Load models** loads them
  again), into a list you search by typing — a gateway can list hundreds — with one
  suggested. The one you pick is the provider's **default model**, used for every
  chat until you change it with **Edit**.
- **Save and check** asks that model one short question with your key. A wrong key,
  address or model is refused with what to do, and nothing is saved; a provider that
  is only out of credit or rate-limiting is saved with that warning. Before any
  provider exists, the same setup appears inside the site's **Build with AI**
  conversation — see **[Providers](https://test-allsweb.allsweb.net/sixpanel/docs/ai-assistant#providers)**.
- Choose a model that is good at writing code and at using tools (function calling):
  Tia works by calling tools that read and write the site's files. Small local
  models often cannot.
- **Max output tokens** is how much one answer may write. Empty means 64,000 for
  Anthropic's own API (never more than the chosen model allows) and 16,384 for
  every other provider. Raise it when a large page stops half-way; lower it if the
  provider refuses the value.

Each provider bills you for its own requests. Keys stay on this server, show only as
their last four characters, and are hidden in job logs. A saved key is only ever
sent to the address it was saved for: change a provider's base URL and the key must
be entered again. Each chat turn keeps the provider it started with, even if you
switch while it runs.

## Pages every project has

### Overview

The four questions a 6amMart project's Overview answers, each a tile that opens the
page that fixes it: **Is it live?**, **Can visitors reach it?** (an address, and
HTTPS on it), **Is anything failing?** (errors in the last 24 hours — nginx's for
every kind, PHP's for PHP and WordPress, the app's own for Node.js) and **When did
it last change?**. Until the website is live, the banner above them names the one
step still missing and has its button. Below: the address with **Open**, **Open
WordPress** (signs you in, no password), what the site runs on, and **Empty the
cache**, **Restart** and the latest jobs.

### Deploys

The top of the page says where the website stands — the same card as a 6amMart
project's Deploys page:

- **Nothing live yet** — *Put your website on this server*: drop a ZIP or a whole
  folder anywhere on the page, or choose **Upload a ZIP**, **Upload a folder** or
  **Connect git**. The text under it says what this kind of website expects.
- **Live now** — the version visitors get (the upload's name, or the commit and
  its message), since when and who put it live (*manual*, *git push*, *Tia* or
  *rollback*), the repository and branch it comes from, and what runs it, with
  **Open site** and **Deploy the latest commit** (or **Deploy a new version** for
  an upload). While something is missing, the missing step — **Add a domain**,
  **Connect & get HTTPS** — is the main button. **Automatic deploys** sits in the
  same card.
- **A Node.js app read but not built** — the checklist (see **Node.js app**).

A deploy, build or rollback shows as a card at the top of the page that ticks off
its steps, and the page updates itself when it ends; **Watch the log** opens the
log. A deploy that fails says so at the top — where it stopped and the last line
the command printed — with **View log**; the version that was live stays live.

Below that:

- **Deploy a new version** — the same three ways in. With git it shows the saved
  repository and **Deploy the latest commit**; **Change repository or branch**
  opens the **Connect git** window again.
- **Automatic deploys** — deploy on every push (see **Deploy on every git push**).
- **History & rollback** — every version with its state (*live*, *ready to
  restore*, *failed*) and **Make live** on any of the last three good ones:
  switching back is instant, and the version is live since that moment. A PHP
  website is updated in place, so its earlier versions show as *replaced* and
  **Backups** puts one back.
- **Background jobs and their logs** — this website's deploys, builds, address and
  database jobs, each with **View log**. Each project keeps its own newest eight,
  however busy the server is.

**Connect git** opens a window in three steps — it closes only from its own
buttons, never from a click beside it, and **Back** keeps what you typed:

1. **Repository** — the address from GitHub, GitLab or Gitea (`https://…` or
   `git@…`) and how the server reads it: nothing for a public repository, an
   **access token** over HTTPS, or a read-only **deploy key** over SSH. For a deploy
   key the panel makes one (ed25519 or RSA) or takes one you already have, shows
   its public half with **Copy** and a link to the repository's *Deploy keys*
   page; leave *Allow write access* unticked. The private half never leaves the
   server. **Continue** first tests the connection and lists the branches.
2. **Deploy** — what will happen, then **Connect only** or **Connect and deploy**.
3. **Automatic deploys** — turn on deploying on every push, right there (see
   [Deploy on every git push](#deploy-on-every-git-push)).

A Create-with-AI website gets its versions from **Build with AI**: the page names
each one by the request that made it, and **Make a change** opens the chat. There
is no upload form — Tia's next change would replace an upload. For WordPress the
page shows WordPress and its updates, restore points as the rollback, and your own
theme or plugin — see [WordPress](#wordpress).

### Environment

Node.js apps and Create with AI only. Variables are stored on this server, never
inside the site's folder, and never shown to a demo login.

### Domain & HTTPS

The page opens with one verdict — **Every address is set up and secure**, **One
thing needs your attention** (or how many), or **Give this website its address** —
with **Open** for the main address and **Re-check DNS**.

Below it, one card per address the website answers on, each with two facts:

- **Reaches this server** — **through Cloudflare**, which is the usual way (every
  record the panel makes is proxied, the orange cloud), or directly when the domain's
  DNS is somewhere else. A name in the Cloudflare account connected to the panel that
  skips Cloudflare — a DNS-only record — is marked, and connecting again turns the
  orange cloud on. When the panel cannot read where a proxied record goes — no
  Cloudflare token for the domain — the card says so instead of guessing. **Goes
  through Cloudflare to a different server** means the record points at another
  machine; change it, the panel never overwrites it.
- **Secure — the https padlock is on**: the free Let's Encrypt certificate, the day it
  is valid until, and that it renews by itself — the server checks every night. A certificate
  close to its end, expired, missing a name, or without renewal settings is marked
  here, and the verdict says what to press.

When a name does not reach this server yet, its card carries the fix: the exact
record to create — an A record for the name, pointing at this server's IP address,
proxied — with a **Copy** button for the address; or, when the Cloudflare account
connected to the panel holds the domain, **Create the DNS record**, which makes it and
gets the certificate in one go. The www / bare twin that sends its visitors to an
address is shown inside that address's card, with its own two facts.

**Add an address** (or **Add another address**): type the name, like
`shop.example.com`, and press **Add and connect**. The panel adds it, makes its
Cloudflare record when it can, checks it reaches this server, gets one certificate
for every address and starts serving on it — a WordPress site is installed on it at
the end. The steps show on the page while they run; **Watch the log** opens the full
log. Tick **Also answer on …** to add the www / bare twin as well. When something is
not secure and the panel can fix it, the verdict offers **Connect & get HTTPS** (or
**Get HTTPS again** once a certificate exists); when the last attempt stopped, the
page says at which step and why, with **View log**.

Under **More** on each card: **Make primary** — the address the app is told about,
and the one WordPress lives on — and **Remove**. Making another address primary, or
removing the primary, moves a WordPress site to the new one: every address WordPress
stored is rewritten, in a job the page shows. **How pointing a domain here works** at
the bottom explains DNS once, with this server's IP address to copy.

### Database

Name, user, password (**Show password**, **Change password** — the panel updates
the app's own settings for you; on a PHP website **Write these into the app's .env**
fills them in), size, **Export now** (a `.sql.gz`, the last five kept) and
**Import a .sql or .sql.gz**. The database user can reach only this database, and
only from this server.

**phpMyAdmin** is here too — one for the whole server, so it works on a server
that has only websites. **Start phpMyAdmin**, then **Open in a new tab** and sign
in with this website's database user and its password (**Show password**); signed
in that way it sees this website's database and nothing else. **Turn off
phpMyAdmin** when you are done. Only the owner can start it.

### PHP

PHP websites and WordPress. See [PHP website](#php-website).

### Cron jobs

Commands on a schedule, run as the site's account in the site folder: every 5 or
15 minutes, every hour, every day, every week, or your own cron expression
(**Custom**), read exactly as cron reads it. Each job has its own **Log** and a
**Run now** button. For Laravel, add `php artisan schedule:run` with the custom
schedule `* * * * *`. A job runs in the same sandbox as a Node.js app: it can
write the site's own folder and nothing of another website, 6amMart or the panel.

### Files

The same file manager as a 6amMart project's, inside this project's folder: tick
files to **Copy**, **Move**, **Compress** into a .zip, **Extract** a .zip or
.tar.gz, **Rename**, change **Permissions** or **Delete** them (right-click a row
for the same menu); **Upload** — or drag files onto the list, each with its own
progress bar; **New file**, **New folder**; search names below the folder you are
in; show or hide dotfiles; a picture opens as a preview, a text file in the editor
(**Ctrl+S** saves, and closing with unsaved changes asks first). It can never leave
the folder, and everything it does runs as the website's own account. For a static or
Node.js site these are the live version's files — the next deploy replaces them,
so change your source for anything lasting.

### Logs

**Errors** comes first, as on a 6amMart project: each failure of the last 24 hours
once, with how many times it happened, when it last did, and whether it came from
the web server, PHP or the app. A failure is the server failing a request — an
upstream that refuses, a PHP fatal error, a WordPress database error, the app
crashing or printing an error. Visitors asking for pages that do not exist, and a
rule or rate limit doing its job, are not failures; PHP warnings are listed after
them, notices and deprecations not at all. **Mark all as seen** starts the count
again (the **Is anything failing?** tile on Overview follows it); the log lines
themselves stay.

The other tabs are the logs themselves: visitor requests and errors (nginx) for
every kind; the app's own output for Node.js; PHP errors and slow requests for PHP
and WordPress; the WordPress debug log when it is on. **live** follows new lines
as they arrive.

### Backups

Every backup of the server carries every website: its database, and its files —
for a static site, a Node.js app or one made with AI the live version (without
`node_modules`, which a restore installs again) and Tia's workspace; for PHP and
WordPress the whole site folder, uploads included. Backups are set up once for the
whole server on the [Backups](https://test-allsweb.allsweb.net/sixpanel/docs/backups) page, and this page says whether they
are on, when the last one ran, and **Back up now**.

**Put this website back** lists the backups that hold it — on the storage that
holds it, when you have more than one (the page opens on the storage the newest
backup went to, or the next one that has this website). **Restore** asks what to
put back — **Files and database**, **Only the database** or **Only the files** —
and for the word RESTORE typed. Only this website changes; no other website and no
project is touched. Before anything is overwritten the panel keeps what is there
now: a WordPress restore point for WordPress, an export of the database for the
others. The files of a static site, a Node.js app or an AI site then install,
build and go live like a deploy, and the version that was live stays on
**Deploys**. Only the owner can restore. Over SSH it is the same job:
`sudo sixpanel backup restore latest --site NAME --what files` (or `db`, or `full`),
where `latest` is the newest backup that holds that website.

### Settings

How the project is built and served (filled in from what the panel found in your
files), its name, and **Delete**. The document root, the 404 page, the single-page
switch and the start command apply to the live version at once (the start command
at the next restart); the output folder and static-or-server wait for the next
build, so the live version keeps being served as it was built until then. Deleting asks you to type the project's short id
and removes its account, files, database, processes and web configuration — and
its DNS records on Cloudflare that point at this server, unless you untick the box
above **Delete** (the confirmation says which it will do). A record that points
somewhere else is never touched.

## Deploy on every git push

Connect the repository on **Deploys** (**Connect git**). **Automatic deploys**
(the last step of that window, and **Set up automatic deploys** on the page)
turns it on — once the address answers over HTTPS, because the webhook arrives at
the site's own address. Until then it says which is missing, with the button that
fixes it.

Turned on, the panel first checks the address itself: it sends a signed test
delivery to `https://<your address>/.sixpanel/deploy`, through Cloudflare, and says
whether it was accepted (or that the certificate is one a git host would refuse).
Then it shows the webhook address
(`https://<your address>/.sixpanel/deploy`) and the secret, each with **Copy**,
and the steps for GitHub, GitLab and Gitea / Forgejo — the tab of the forge your
repository is on opens first, and **Open the webhook page on GitHub** (or GitLab,
or Gitea) goes straight to the form. In short, add a webhook with that address,
content type `application/json`, the secret, and push events:

- **GitHub** — Settings → Webhooks → Add webhook.
- **GitLab** — Settings → Webhooks; paste the secret as the **Secret token**.
- **Gitea / Forgejo** — Settings → Webhooks → Add webhook → Gitea.

Only pushes to the branch you chose deploy; others are ignored. The card shows
the last delivery, when it arrived and what came of it — *deployed*, *deploying
now*, a deploy that failed, a push to another branch, or the forge's test delivery.
A delivery with a wrong secret is refused, recorded on **Activity**, and the card
asks for attention. **New secret** replaces the secret (paste the new one into the
webhook straight away); **Turn off** stops deploying on push.

The window notices the forge's first delivery by itself. A private repository
needs an **access token** with read access to it (GitHub: a fine-grained token with
*Contents: read*) — or the website's **deploy key**, and then the `git@…` address
works too.

## What a temporary login can do

A temporary login ([Share access](https://test-allsweb.allsweb.net/sixpanel/docs/share-access)) can deploy, build, roll
back, restart, purge the cache, edit files, run and edit cron jobs, update
WordPress and its plugins, deploy a WordPress theme or plugin, and take restore
points. It cannot see or change
secrets — environment variables, the database password, the git token, the
deploy key, the webhook secret, `.env` and `wp-config.php` — and it cannot create or delete
projects, change addresses, restore over the live database, put a website back
from a backup, or use your AI provider keys.

## How to check it worked

- The project's card on **Projects** says **live**, and **Overview → Open the
  website** opens it over HTTPS.
- **Overview** shows the version you just deployed, and **Deploys → Live now**
  names it and says since when.
- For a Node.js app, **Logs → the app's output** shows it started without errors.

## If it went wrong

- **The build failed.** **Deploys** says where it stopped, and **View log** shows
  the whole log; the site kept serving the previous version, with its own
  settings. Fix the source, or the command on **Settings**, and deploy again.
- **"a web server cannot serve from a name like that".** The page the site starts
  from is in a folder whose name has a space or another character nginx cannot
  carry. Rename the folder with letters, digits, dots, dashes and underscores.
- **The app starts but the page shows an error.** Check **Environment** against
  `.env.example`, then **Logs**.
- **"Access denied" from the database** in a Node.js app. Use `DATABASE_URL` or
  `DB_HOST` as the panel sets them — a hand-typed host or password does not match.
- **The address does not open.** **Domain & HTTPS** says what is missing; see
  **[Domain and SSL](https://test-allsweb.allsweb.net/sixpanel/docs/domain-ssl)** and **[Cloudflare](https://test-allsweb.allsweb.net/sixpanel/docs/cloudflare)**.
- **A push did not deploy.** **Deploys → Automatic deploys** shows the last
  delivery. A push to another branch and a wrong secret are the usual answers;
  the repository's webhook page shows the response too.
