Skip to content

Manual file replacement.

Update by uploading files via FTP or SFTP. The fallback method for shared hosting and environments without exec().

Oct 2, 2026
On this page

Use this method when your host cannot run dashboard updates, or when you prefer to upload the files yourself. You'll need your hosting file manager or an FTP/SFTP client.

Follow the steps in order and keep a current backup. If you're unsure about replacing files on a live site, ask your hosting provider or installer to help. Dashboard updates need fewer manual steps when your host supports them.

Before you start

Create a recoverable backup before changing files. Keep the backup outside the public web directory. Include:

  • Your .env file (environment configuration)
  • Everything in public/files/ (user uploads and media)
  • storage/app/ (private files and integration credentials)
  • A database backup: database/database.sqlite for SQLite, or an export from MySQL/MariaDB
  • Custom translation files and other files you changed (translations edited in Languages & translations live in the database and are covered by the database backup)

Update steps

This approach keeps your production site running while you prepare the update. If you don't have a staging environment yet, see Staging Installation for setup guidance.

1. Upload the new version to a temporary subdomain (like staging.yourdomain.com).

2. Copy your data from your current production installation to the staging installation:

Copy the uploads, private storage, and a database backup. Before opening the staging site, set its own APP_URL and database connection. For MySQL/MariaDB, restore the backup into a separate database. Never point staging at the live database. Keep the original APP_KEY so copied encrypted settings remain readable.

Route staging email to a test mailbox and disable outbound integrations and scheduled jobs until you have isolated them. A copied .env can otherwise send real mail or change live services.

To see hidden files like .env on macOS, press Cmd + Shift + . in Finder.

3. Run database migrations by signing in as admin at /en-us/admin/. If migrations are pending, you'll see a message: "An update is required for your database. Click here to apply the update." If you have terminal access, you can also run php artisan migrate --force instead.

4. Clear caches by deleting the .php files inside bootstrap/cache/. Use the file manager in your hosting panel or your FTP client: open the bootstrap/cache/ folder, delete the .php files in it, and keep the folder itself in place.

If you have terminal access, this one command does the same:

rm -f bootstrap/cache/*.php

With terminal access you can also run php artisan optimize:clear instead.

5. Test everything. Verify login works, member data is intact, and uploaded files display. Open Languages in the admin sidebar once: the translation editor then records which texts the update added, changed, or removed. With terminal access, php artisan languages:sync does the same.

6. Update production with the tested package using the in-place steps below. Take a fresh backup first. Do not replace the live database with the old staging copy: it will omit activity recorded since you made that copy.

Option B: In-place update

If you prefer not to use a staging subdomain:

1. Back up everything as described above.

2. Stop writes and background jobs. Use a hosting or web-server access rule that stays active while you replace application files. Allow only your own access for the update checks. Pause any scheduled jobs and queue workers you have configured. After writes stop, take a final database backup and copy of public/files/ and storage/app/. Use these final copies for restoration. Move the old application files to a backup outside the public web directory. Ask hosting support to set up this access rule if needed.

3. Upload the new version by opening the extracted package root and uploading every top-level file and directory. Do not upload only the package's internal public directory.

4. Restore your files: .env, public/files/, storage/app/, and custom files. For SQLite, restore database/database.sqlite. Keep the existing production database connection for MySQL/MariaDB.

5. Run migrations and clear cache as described above. Check sign-in, member data, and uploaded files. Then resume any jobs you paused and remove the temporary hosting access rule.

The new version includes an empty public/files/ directory. Depending on your upload method, this may overwrite your existing uploads. Always back up first and restore after.

Clearing caches after update

After replacing files, you should clear cached configuration to prevent 500 errors:

  1. Delete bootstrap cache files: Remove all .php files in bootstrap/cache/
  2. Clear framework cache: If you have terminal access, run php artisan optimize:clear
  3. Reload the page: Your admin dashboard should load with the new version

If your site shows a 500 error after updating, clearing bootstrap/cache/ resolves it in most cases.

Protecting custom files

During a manual update, you manage protected paths yourself by backing up and restoring any custom files. To protect these same files during future automated updates, add them to your .env file:

PROTECTED_TRANSLATIONS="de_DE,fr_FR"
PROTECTED_PATHS="custom/branding/"

See What Gets Preserved for the complete list of core protected paths.

Translations edited in Languages & translations need no protection: they live in the database. Only translation files you changed by hand under lang/ need a PROTECTED_TRANSLATIONS entry.

Consider automated updates

Dashboard methods save manual work when your host supports them. They create a file rollback; keep your own database backups too:

  • Dashboard Update: One click, automatic. Requires active support + exec().
  • Install from Package: Place the zip on your server, dashboard handles the rest. Requires exec(), but no active support.

Use an automatic method when the host allows the background process and has enough disk I/O for package extraction and file replacement. Automatic updates use a low-I/O rollback backup.