Updating to a new version

Replace the files, run one command, and know which three things must survive.

The three things that must survive

Everything else in the package can be overwritten. These cannot:

PathHoldsIf you lose it
.envYour database credentials and application key.The site cannot connect to its own database.
public/uploadsEvery image anybody has ever uploaded.Every dish photograph, logo and cover, gone.
Your databaseEverything else.Everything.

The procedure

  1. Back up the database and public/uploads. Not optional, and not worth skipping on the grounds that it is a small update.
  2. Turn maintenance mode on, so nobody orders halfway through — see Maintenance mode & backups.
  3. Replace the application files with the new release, keeping the two paths above.
  4. Run the database upgrade:
php artisan migrate
  1. Turn maintenance mode off and check the storefront, a dashboard, and one order.

No command line? Use the installer

Most shared hosting has no SSH, so step 4 has a second route that does the same thing. Open the installer again after replacing the files:

https://your-site.com/installer/

Once a site is installed the installer no longer offers to install anything. It shows you which database changes have not been applied yet, and applies them when you sign in with your super admin account. It asks for that account because the page changes the database of a running site — it is not something a passer-by should be able to trigger.

If there is nothing outstanding it simply says your database is up to date. Both routes use the same migration steps and leave the same record, so it does not matter which you use, and running one after the other is harmless.

What the upgrade command does

It brings an older database up to the new release's schema by applying the migration steps that release ships. Four properties are worth knowing, because they decide how safe a bad moment is:

PropertyMeaning
It only ever addsNothing is dropped and no row is deleted. An upgrade cannot lose your data.
It is idempotentEvery step checks the database before changing it. Running it twice changes nothing.
It records what it appliedA step cannot double-apply.
A failed run is re-runnableFix the cause and run it again. It picks up where it stopped.

On a fresh install it reports there is nothing to do — the installer creates the database at the current schema, so every step is already applied.

Replacing files without running the migration is the failure mode. New code against an old database fails on a column that does not exist yet, and the error rarely says which half is missing. If something breaks immediately after an update, run the migration before investigating anything else.

What survives and what does not

SurvivesDoes not
Everything set in the dashboard — settings, branding, page wording, menus, plans.Edits you made to PHP, CSS or JavaScript files.
All your data.Changes to the shipped language files.
Uploaded images, if you preserved the folder.Anything you added inside a folder the release replaces.

If you have customised code, keep a record of what and where. A diff against the previous release is the reliable way to reapply it.

Afterwards

  • Check the scheduled tasks screen. A new release may add a job, and new jobs follow their own default rather than inheriting a decision you never made.
  • Look at Settings → Payment and confirm webhooks are still arriving.
  • Place one test order end to end. It exercises more of the product than any amount of reading does.

When it doesn't work

A blank page or a database error straight after updating

The migration has not been run. That is the first thing to try.

The site sends you back to the installer

Your .env configuration file or the storage/installed marker was overwritten or removed. Restore them from your backup — this is why step one exists.

Every image is missing

public/uploads was replaced. Restore it from the backup.

A customisation disappeared

It was in a file the release replaced. Reapply it from your record.

The migration reports nothing to do

The database is already current. That is a pass, not a failure.