# More than one project on this server

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

Part of: SixPanel documentation

**What this page is for:** run a second (or third) complete 6ammart install on
the same server, each with its own domain, database and code.

**You need**

- A server with room to spare. Plan roughly 2 GB more RAM and 1–2 more CPU
  cores for each additional busy project.
- Its 6ammart code — a zip or a git repository.
- A web address for the new project. You do **not** need it to create the
  project; the install asks for it while your code uploads. It has to exist
  before the install finishes, because it is written into the app's settings.
- Your first project already working. Nothing about it changes.

Each install is called a **project**. Your first one is the default project.

## What a project actually is

On this server, one project is a real boundary, not a folder convention:

- its own **Linux user** (`six-<short id>`), which owns its code and uploads;
- its own **PHP-FPM pool**, so one project's PHP cannot read another's files
  and a crash in one does not touch the other;
- its own **database** and database user;
- its own **cache and session store** (Redis), running as its own service on a
  private socket only that project's Linux user can open, with its own password;
- its own **queue worker**, **scheduler**, **websocket service** and **customer
  website**, each a separate systemd unit named after the project;
- its own web server configuration and its own certificates;
- its own **settings environment**. The background services of a project are
  started with nothing from the panel's own settings file except the server
  timezone, so a project's `.env` is the only thing that decides which database
  its queue worker, scheduler and websocket service talk to.

The web server and the database server are **shared** by every project on the
machine.

> **The cache used to be on that list too**, and it was the wrong
> place for it. Every project used one cache service behind one password, and
> that password has to be inside each project's own settings file for its own
> site to work — so any project on the server could read, and change, what every
> other project had put there. That is not a small thing: a 6ammart shop keeps
> its mail password, its Firebase and Maps keys, its SMS gateway key and its
> payment gateway secrets in the cache, along with everyone's signed-in
> sessions. Each project now has its own cache service on a socket the
> other projects' users cannot open, and each has its own password. **Updating
> does it for you**: your cache is copied across, so nothing goes cold and
> nobody is signed out.

> **On older servers the settings-environment point above was not true**, and it mattered: every
> project's background services were started with the FIRST project's database
> name, user and password in their environment, and Laravel does not let a
> project's own `.env` override something already set there. On a server with
> two or more projects, the second project's queue worker, scheduler and
> websocket service were talking to the first project's database — so its own
> queued work (emails, notifications, exports) never ran, and the work it did do
> landed in the wrong place. Updating fixes it on its own; nothing to
> change by hand, and no data is touched. If you have been running more than one
> project, look at the first project's failed jobs afterwards.

## 1. Create the project

1. Open **Projects** (in the **Panel** menu group) and press **Create a new
   project**. On a server with no project yet, the page opens on the choices
   themselves.
2. Choose **6amMart**. The same dialog creates a static website, a Node.js app,
   a PHP website, WordPress, or a website built with AI — those are covered in
   [Websites and apps](https://test-allsweb.allsweb.net/sixpanel/docs/websites-and-apps).
3. Type the new project's **name** — the label you will recognise it by, like
   `Grocery Two`.
4. Press **Create the project**.

For 6amMart that is the whole form. Under the name the dialog shows the **short
id** it derives — `grocery-two` — so you can see what its folders and services
will be called; there is nothing to decide about it. A name already in use gets
`-2`, `-3` added, and a name that derives nothing usable (written entirely in
another script, or only in digits) becomes `project-` and four characters.

There is **no address question for 6amMart here**, and no Advanced section. The
web address, its DNS records and its certificates are asked for in **Put
6amMart on this project** on the **Deploys** page, while your code uploads —
see step 2. One question, one place: while the create dialog also asked, the
two drifted, and an owner who followed the newer flow ended up with a
registered hostname, no DNS record and no certificate.

> **The short id can never be changed.** It is used in the name of the Linux
> user, the PHP pool, the database, the systemd units, the web-server files and
> the folder your code sits in. It must be 3 to 20 characters: lowercase
> letters, digits and hyphens, starting with a letter. The **project name**
> above it is only a label and can be changed at any time — see [Rename a
> project](https://test-allsweb.allsweb.net/sixpanel/docs/project-name).

The job has one step, shown as it runs: it creates the Linux user, the folders,
the PHP pool, this project's own cache service, its services and a new empty
database. It takes a minute or two, and your other projects keep running the
whole time. It ends on **Continue to install the app**, which takes you to the
new project's **Deploys** page.

**If another job is running** — a backup, an install, an update — you do not
have to wait for it: the create **queues**. The dialog says **Queued — starts
as soon as "…" finishes**, naming the job ahead of it, and follows the create
the moment its turn comes. You can close the dialog; the project waits on the
Projects page as **queued** until then, and its name is held for it, so nothing
created meanwhile can take it. Asking for the same project twice is refused
rather than queued twice. Deleting a project, restoring one and **Finish
setting up** still wait until nothing else is running, because they take apart
or rebuild what the running job may be using.

New projects share ports 80 and 443, so there is **no new firewall change**.

## 2. Then install its code, and answer the address there

The new project's card and its Overview page list what is still missing. Work
down it:

1. **The admin app, and the project's address in the same pass** — press **Put
   6amMart on this project** on **Deploys**. It asks whether this is a
   brand-new shop or one that already runs elsewhere, takes the zip or the git
   repository, and while that uploads it asks **what address will this project
   answer on?** One domain: the admin, website and websocket names are derived
   from it and shown, never asked. Saving it registers the addresses, creates
   the DNS records — always proxied — and gets the certificate for the admin
   panel and for the website, each step shown as it completes. If the records
   are not visible yet, the HTTPS rows are skipped with a reason and a button
   to check again, rather than failing slowly. See [Install your 6ammart
   code](https://test-allsweb.allsweb.net/sixpanel/docs/install-app).
2. **If that domain is on a Cloudflare account this panel cannot manage**, the
   same screen offers the two real ways through: hand it that account's own API
   token, or add the records yourself — kept orange (proxied) — and press
   check again. It never asks you for a DNS-only record. See
   [Cloudflare](https://test-allsweb.allsweb.net/sixpanel/docs/cloudflare).
3. **The customer website** — optional. See [The customer
   website](https://test-allsweb.allsweb.net/sixpanel/docs/customer-website).
4. **Automatic deploys** — optional. Each project has its own webhook
   addresses, built from **its own** domain, and each repository has its own
   secret. Switch to the project first, then copy the address from its
   **Deploys** page. See [Deploy and update your code](https://test-allsweb.allsweb.net/sixpanel/docs/deploy-update).
5. **Backups** — one schedule covers every project. See
   [Backups](https://test-allsweb.allsweb.net/sixpanel/docs/backups).

## 3. Moving between projects

Once you have more than one project, a switcher appears in the top bar. It
shows only while you are on a Project page — on a Panel page there is nothing
to switch, so it is hidden. Choose a project and every Project page — Overview,
Deploys, Domain & SSL, Database, Logs, App .env, SixPreflight, Advanced — acts
on that one.

The web address tells you where you are. A **Panel** page is a whole-server
page. A **Project** page carries the project in its address.

Over SSH, add `--project` to almost any command:

```
sudo sixpanel project list
sudo sixpanel project show shop2
sudo sixpanel logs php --project shop2 -f
sudo sixpanel db dump --project shop2
```

Without `--project`, commands act on the default project.

## 4. Sizing the server

Every project runs its own PHP workers, its own cache service, its own queue
worker and its own scheduler. The database and the web server are shared.

The cache is the one to understand, because it has a memory limit. The server
has ONE cache memory budget — six per cent of its RAM — and adding a project
**divides** that budget rather than adding to it: on a 4 GB server, one project
may hold 245 MB of cache, and three projects may hold 81 MB each. That is
deliberate. Giving every project the full budget would promise more memory than
the machine has, and the first busy hour would take it from the PHP workers.
Each extra cache service itself costs about 3 MB, which is charged against the
worker budget so the arithmetic stays honest.

You do not have to do anything about this — the panel re-divides it whenever
you add or remove a project, without restarting anything. It is here so that
"why did my cache limit go down when I added a shop?" has an answer.

A 2-core / 4 GB server is a one-project server. After you resize the server,
open **Settings** → **Auto-tune** and press **Apply tuning**, so memory and
worker counts are recalculated for the new hardware. The affected services pick
up the new sizes.

The panel's own sizing already knows how many projects there are: adding one
lowers the PHP workers each project gets, rather than promising memory the
machine does not have. That is deliberate and it was measured rather than
assumed — on a 2-core server with three projects, giving one busy shop 16 PHP
workers instead of 4 served **no more requests per second** and made the slowest
one-in-a-hundred page 57% slower, because four workers already keep two
processors busy. The extra workers only take turns, and each one costs memory.

The same arithmetic decides the database's open-table cache, which does grow
with the number of projects, since each project has its own set of tables.

## 5. Backups with several projects

Every backup run covers **every** project: one database dump per project, plus
each project's uploaded files and settings, all in one snapshot.

Restoring from the panel puts back the default project. If you need to restore
one of the others, contact support first — do not restore over a
several-project server on a guess.

## 6. Deleting a project

Deleting has two settings, and they mean very different things. The delete box
has a tick-box labelled **also delete the data**. Leave it alone and you get a
**seven-day window** in which the project can be brought back. Tick it and the
database and the files go immediately, for good.

> **Take a backup first, either way.** Nothing takes one for you, and the
> seven-day window is a second chance, not a backup — it lives on the same
> server and dies with it.
>
> ```
> sudo sixpanel backup run full
> ```

### Delete it

1. **Projects** → the project's card → the delete link.
2. Decide about **also delete the data**. Leave it unticked unless you truly
   want everything gone; ticking it shows a warning.
3. There is a second tick-box for its **DNS records**. That one is separate and
   off by default.
4. Type the project's short id into the confirmation box. The delete button
   stays inactive until what you type matches exactly.
5. Delete.

Your other projects keep serving customers the whole time. The default project
cannot be deleted.

### What a delete keeps, and what goes at once

Either way, the project **stops serving immediately**. These go straight away
and are rebuilt if you restore it:

- its services — PHP workers, queue worker, scheduler, websocket service and
  customer website;
- its PHP pool, its cache service and its Linux user;
- its web-server configuration, so its addresses stop answering;
- **its certificates.** They are removed at delete time, not held for the
  week. A certificate for an address that no longer serves would show up as a
  stray in every renewal check from then on, so it is cleaner to remove it and
  request a new one if the project comes back.

With **also delete the data** left unticked, these are **kept for seven days**:

- the project's **database**, exactly as it was, with its password untouched;
- the project's **files** — its code, its settings file and all of its customer
  uploads.

With **also delete the data** ticked, both of those are destroyed as part of the
delete job. There is nothing to restore afterwards, and no copy anywhere except
your own backup.

Either way, the panel re-divides the server's cache memory across the projects
that remain, so the shops still running get the departed one's share.

### Getting it back

For seven days the **Projects** page carries a **Recently deleted** card under
the project cards. Each row shows the project, its address, and how many days
are left before the panel deletes it for good.

1. Open **Projects**.
2. Find the project under **Recently deleted**.
3. Press **Restore**.
4. Watch the job log, the way you watch a create.

The restore rebuilds everything the delete removed and points it back at the
data that was kept: the Linux user, the file ownership, the PHP pool, the cache
service and its new password, the services, the web-server configuration, and
then it **requests the certificates again** — an address that was on HTTPS
before should be on HTTPS after.

Two things are worth knowing about that last step:

- **A certificate that does not come back does not fail the restore.** The shop
  is already up and serving with its data by then. Certificate authorities have
  rate limits and DNS takes its own time, so if one address is not secured the
  job says which one, and **Get free SSL** for that name on the project's
  **Domain & SSL** page finishes it — see [Domains and
  HTTPS](https://test-allsweb.allsweb.net/sixpanel/docs/domain-ssl).
- If no **certificate email address** is set on this server, the job says so and
  leaves the project serving over plain http. Set one under **Settings** and
  then get the certificate from **Domain & SSL**.

The short id and the internal ports stay **reserved** for the whole seven days.
You cannot create a new project using the short id of one that is still
restorable — which is deliberate, so nothing can be built on top of a shop you
might still want back.

> **This is a new feature, so treat the restore as a recovery route and not as a
> substitute for a backup.** It rebuilds a lot in one job. Take the backup
> before you delete, and if the shop matters, restore it at a quiet moment and
> check it over — the storefront, a sign-in, one order — rather than assuming.

### After seven days

Once a project's window runs out, the panel finishes the job: it deletes the
database and the files, exactly as **also delete the data** would have. The
sweep runs about once an hour, so a row may still be listed for a little while
after its last day — it shows as **Being deleted now** and has no Restore link.
Pressing Restore on an expired project is refused rather than handing you an
empty shop; restore it from a backup instead.

A row that says **Retention unreadable — kept** is a deliberate safety net. If
the panel cannot read when a project was deleted, it never treats it as expired
and never destroys its data. Contact support rather than trying to clear it.

Over SSH, `sudo sixpanel project list` shows the projects this server is
serving. Deleted ones are not on it — the **Recently deleted** card on the
Projects page is where they are.

## How to check it worked

- **Projects** lists the new project, and its card reaches a finished state.
- `sudo sixpanel project list` shows the short id, the domain and how many of
  its services are up.
- Open the new project's domain in a browser and log in to its admin panel.

## If it went wrong

- **Creating the project failed** — read the job log on the **Projects** page.
  Disk space and memory are the usual causes; check with `sudo sixpanel disk`.
- **The new project shows the old one** — the domain is pointed at the wrong
  project. Check **Domain & SSL** with the right project selected in the
  switcher.
- **The server became slow after adding a project** — run `sudo sixpanel top`,
  and see the slow-server section in [When something is
  broken](https://test-allsweb.allsweb.net/sixpanel/docs/troubleshooting). Usually the answer is more RAM, then **Apply
  tuning**.
- **`sixpanel project create` refuses** — that is on purpose. Creating a
  project builds a Linux user, a database, a cache service, a PHP pool, a
  service set, web-server files and their configuration as one operation, so it
  stays in the panel. A half-made project is worse than none.
- **Can one project read another's cache?** No. Each project's cache listens on
  a file (a "unix socket") inside a folder that only that project's Linux user
  may open, so another project is refused by the operating system before it can
  even offer a password. **Health** checks that folder's permissions on every
  run and reports it as a fault if it is ever widened.
