How to back up and restore a PrestaShop store
A PrestaShop backup needs three things: a dump of the MySQL or MariaDB database, an archive of the store directory with img/, download/, upload/, modules and themes, and app/config/parameters.php, which holds the database password and the cookie keys. The back office's DB Backup page covers only the database and leaves the file on the same server. To restore, load all three, clear var/cache, and update the domain if it changed.
What to back up, and what to skip
PrestaShop is free, open-source software under the OSL 3.0. This guide covers PrestaShop 8.2 and 9 (the newest releases are 8.2.8 and 9.2.0, from August and September 2026). The store lives in /var/www/shop, PHP runs as www-data, and the back office folder carries the random name it got at install; here admin123abc. ls -d /var/www/shop/admin*/backups shows yours.
| Part | Where | Back it up? |
|---|---|---|
| Database | MySQL or MariaDB, named in parameters.php | Yes. Products, customers, orders, configuration. |
| Images | img/ (img/p for products, img/c for categories) | Yes. Thumbnails can be regenerated, originals cannot. |
| Virtual products and attachments | download/ | Yes. Files customers paid for, stored under md5 names. |
| Customer uploads | upload/ | Yes. Files sent for customizable products. |
| Modules, themes, overrides | modules/, themes/, override/ | Yes. Paid and edited ones cannot be downloaded again. |
parameters.php | app/config/ | Yes, on its own and encrypted. |
| Back office folder | admin123abc/ | Yes, without backups/ and autoupgrade/. |
| Cache and logs | var/cache/, var/logs/ | No. Keep the folders. |
The release package ships vendor/, and translations and mail templates may be edited in place, so back up the whole directory minus caches, as PrestaShop's own backup guide does.
parameters.php and the cookie keys
The installer writes app/config/parameters.php with the database settings and values generated for this store alone. PrestaShop 8.2 and 9.2 write the same set:
cookie_key: PrestaShop 8 and 9 hash passwords with bcrypt, which does not use it. A store upgraded from 1.6 can still hold MD5 hashes salted withcookie_keyfor customers and employees who have not logged in since; PrestaShop rehashes each one with bcrypt at its next login. Without the original key, those accounts getAuthentication failed.until they reset their password.new_cookie_keyencrypts the store's cookies andcookie_ivsalts their checksum. New values sign everyone out, customers and employees alike.secretis Symfony's secret, described in PrestaShop's template as "A secret key that's used to generate certain security-related tokens".api_public_keyandapi_private_keyare an RSA key pair the installer generates.
None of these can be regenerated to match data that already uses them, so keep the whole file:
install -d -m 700 /var/backups/prestashoptar -czf /var/backups/prestashop/shop-params-$(date +%F).tar.gz -C /var/www shop/app/config/parameters.phpA dump plus cookie_key is everything needed to test password guesses against legacy MD5 hashes offline. Store the parameters archive apart from the dumps and encrypt it. PrestaShop also caches a copy in var/cache/prod/appParameters.php, one more reason to leave var/cache out of file backups.
Dump the database with mysqldump
Read the connection settings from parameters.php, which returns a PHP array:
php -r '$p = (include "/var/www/shop/app/config/parameters.php")["parameters"]; echo $p["database_host"], " ", $p["database_port"], " ", $p["database_name"], " ", $p["database_user"], " ", $p["database_prefix"], PHP_EOL;'Put the user and password in an option file, so the password stays out of ps:
[client]
user=prestashop
password="your-password-here"
host=localhostchmod 600 /etc/mysql/prestashop-backup.cnfmysqldump --defaults-extra-file=/etc/mysql/prestashop-backup.cnf --single-transaction --no-tablespaces prestashop | gzip > /var/backups/prestashop/shop-db-$(date +%F).sql.gz--single-transactionreads InnoDB tables, PrestaShop's default engine, from one consistent snapshot without locking them, so checkout keeps working. PrestaShop's backup guide uses it too.--no-tablespacesavoids the globalPROCESSprivilege.database_enginein parameters.php names the engine PrestaShop creates tables with. MyISAM tables, from an old install or a module, are not covered by the snapshot; the mysqldump guide shows a query that lists them.
A complete dump ends with a -- Dump completed on line:
gunzip -c /var/backups/prestashop/shop-db-2026-10-04.sql.gz | tail -n 1The back office DB Backup, and its limits
Advanced Parameters > Database > DB Backup still exists in PrestaShop 8.2 and 9.2. It writes a .sql.bz2 file (.sql.gz if PHP lacks the bz2 extension), named after the time and a random number, into admin123abc/backups/. The source shows its limits:
- Database only. Its own disclaimer says "This function only backs up your database, not your files."
- Each table is read with a plain
SELECT, outside any transaction, so on a busy store the tables come from slightly different moments. - Only tables with the store's prefix are included. "Ignore statistics tables" leaves out the rows of
connections,connections_page,connections_source,guestandstatssearch. - The file stays on the store's own server. There is no schedule and no restore button; the page's help walks you through importing it with phpMyAdmin.
It is fine for a quick copy before a change. For the backups you depend on, use mysqldump and copy the result off the server.
Maintenance mode, and orders between backups
Nightly dumps need no maintenance mode. Close the store for the final backup before a move, so no order arrives between the last dump and the switch:
sudo -u www-data php /var/www/shop/bin/console prestashop:config set PS_SHOP_ENABLE --value 0That is the Enable store switch in Shop Parameters > General > Maintenance; visitors get a 503 maintenance page, and IP addresses in PS_MAINTENANCE_IP can still browse. Without --shopId it applies to all shops. The switch is stored in the configuration table, so a dump taken with the store closed restores closed; PrestaShop's post-restore checklist starts with turning maintenance mode off.
A restore loses every order placed after the dump it comes from. The WooCommerce guide works through how many orders each backup interval puts at risk and how to keep the ones in the gap; the reasoning is the same here. Before loading an older dump over a damaged store, save the current database and list the orders placed since the backup. date_add is in the store's time zone, set in International > Localization:
mysql --defaults-extra-file=/etc/mysql/prestashop-backup.cnf prestashop -e "SELECT id_order, reference, total_paid_tax_incl, date_add FROM ps_orders WHERE date_add > '2026-10-04 03:10:00' ORDER BY id_order" > /root/orders-since-backup.tsvArchive the store files
Dump the database first, then the files, so the database never points at an image the archive lacks:
tar -czf /var/backups/prestashop/shop-files-$(date +%F).tar.gz --exclude='shop/app/config/parameters.php' --exclude='shop/var/cache/*' --exclude='shop/var/logs/*' --exclude='shop/admin123abc/backups/*' --exclude='shop/admin123abc/autoupgrade/*' -C /var/www shop- parameters.php has its own archive.
var/cacheandvar/logsare rebuilt or disposable; the/*keeps the folders themselves. backupsholds the back office's database copies, andautoupgradeis the Update Assistant's scratch folder, which can hold full copies of the store.- Exclude patterns match the stored names and must come before the directory.
A large img/ makes a full archive every night heavy. restic or rsync send only changed files.
Restore on a new server
Install a web server, MySQL 5.7 or MariaDB 10.2 or later, and a PHP version your release supports: PrestaShop 9.0 runs on PHP 8.1 to 8.4 and 9.1 adds 8.5. Create an empty database and user:
CREATE DATABASE prestashop CHARACTER SET utf8mb4;
CREATE USER 'prestashop'@'localhost' IDENTIFIED BY 'your-password-here';
GRANT ALL PRIVILEGES ON prestashop.* TO 'prestashop'@'localhost';tar -xzf /var/backups/prestashop/shop-files-2026-10-04.tar.gz -C /var/wwwtar -xzf /var/backups/prestashop/shop-params-2026-10-04.tar.gz -C /var/wwwEdit database_host, database_name, database_user and database_password in parameters.php if they changed. Keep every key exactly as it is. Then delete the cache:
rm -rf /var/www/shop/var/cache/prod /var/www/shop/var/cache/devPrestaShop reads its parameters from var/cache/prod/appParameters.php and refreshes that copy only when parameters.php is newer. tar restores parameters.php with its old modification time, so a leftover cache from a fresh install would win. Load the dump and give the files to the PHP user:
gunzip -c /var/backups/prestashop/shop-db-2026-10-04.sql.gz | mysql --defaults-extra-file=/etc/mysql/prestashop-backup.cnf prestashopchown -R www-data:www-data /var/www/shopChange the domain
PrestaShop keeps its address in the database: domain, domain_ssl and physical_uri in the shop_url table, and PS_SHOP_DOMAIN and PS_SHOP_DOMAIN_SSL in configuration. The front office redirects any host name it does not know to the stored domain (a 302 with the default settings), while the back office answers on any host name.
So the simplest fix is in the back office: Shop Parameters > Traffic & SEO > SEO & URLs > Set shop URL. Saving it updates all four values and rewrites .htaccess, whose rewrite rules name the domain on Apache. From the command line, update the tables yourself, using your table prefix:
UPDATE ps_shop_url SET domain = 'shop.example.net', domain_ssl = 'shop.example.net' WHERE id_shop = 1 AND main = 1;
UPDATE ps_configuration SET value = 'shop.example.net' WHERE name IN ('PS_SHOP_DOMAIN', 'PS_SHOP_DOMAIN_SSL');With several shops, each has its own shop_url rows. Delete var/cache/prod again, then regenerate .htaccess, with the command below on PrestaShop 9.2 and later, or by saving Set shop URL on earlier versions:
sudo -u www-data php /var/www/shop/bin/console prestashop:htaccess:generate --forceVerify the restore
curl -sS -o /dev/null -w '%{http_code}\n' https://shop.example.net/Expect 200, or 503 while maintenance mode is on. Compare order counts and the newest order with the live store:
mysql --defaults-extra-file=/etc/mysql/prestashop-backup.cnf prestashop -e "SELECT COUNT(*), MAX(date_add) FROM ps_orders"Log in to the back office, open a product with images, sign in as a test customer, download a virtual product, and run a search. If thumbnails are missing, use Design > Image Settings > Regenerate thumbnails, or on 9.1 and later bin/console prestashop:thumbnails:regenerate all. Then reopen the store:
sudo -u www-data php /var/www/shop/bin/console prestashop:config set PS_SHOP_ENABLE --value 1Testing restores explains how to repeat this on a schedule.
Automate it with cron
This script writes under temporary names, checks the dump, and only then renames. tar exits with 1 when a file changed while it was read, so 1 counts as success.
#!/bin/bash
set -euo pipefail
SHOP_DIR="/var/www"
SHOP="shop"
ADMIN="admin123abc"
DB_NAME="prestashop"
BACKUP_DIR="/var/backups/prestashop"
KEEP_DAYS=14
STAMP="$(date +%Y-%m-%d_%H%M)"
DB="$BACKUP_DIR/$SHOP-db-$STAMP.sql.gz"
FILES="$BACKUP_DIR/$SHOP-files-$STAMP.tar.gz"
mkdir -p "$BACKUP_DIR"
trap 'rm -f "$DB.partial" "$FILES.partial"' EXIT
mysqldump --defaults-extra-file=/etc/mysql/prestashop-backup.cnf \
--single-transaction --no-tablespaces "$DB_NAME" | gzip > "$DB.partial"
gunzip -c "$DB.partial" | tail -n 1 | grep -q "Dump completed"
mv "$DB.partial" "$DB"
tar -czf "$FILES.partial" \
--exclude="$SHOP/app/config/parameters.php" \
--exclude="$SHOP/var/cache/*" --exclude="$SHOP/var/logs/*" \
--exclude="$SHOP/$ADMIN/backups/*" --exclude="$SHOP/$ADMIN/autoupgrade/*" \
-C "$SHOP_DIR" "$SHOP" || [ $? -eq 1 ]
mv "$FILES.partial" "$FILES"
find "$BACKUP_DIR" -type f \( -name "$SHOP-db-*" -o -name "$SHOP-files-*" \) -mtime +"$KEEP_DAYS" -deletechmod 755 /usr/local/bin/prestashop-backup.shPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
10 3 * * * root flock -n /run/lock/prestashop-backup.lock /usr/local/bin/prestashop-backup.sh >> /var/log/prestashop-backup.log 2>&1A store taking orders all day should dump the database far more often than it archives files, as the WooCommerce guide explains; binary log point-in-time recovery closes the gap further. Copy everything off the server, for example with rclone, and see the cron guide for logging and alerts.
Common errors
| Error | Fix |
|---|---|
The store shows Oops, something went wrong. and var/logs/ holds Link to database cannot be established: followed by the server's reason | The database settings in parameters.php are wrong for this server, or the user has no grant. Fix them and delete var/cache/prod. |
Unable to write in the "cache" directory followed by a path | PHP cannot write to var/cache. Give var/ to the PHP user. |
| Changes to parameters.php seem ignored | A stale var/cache/prod/appParameters.php wins. Delete var/cache/prod. |
| The store redirects to the old domain | Update shop_url and PS_SHOP_DOMAIN, PS_SHOP_DOMAIN_SSL, then clear the cache. |
| Every page but the home page returns 404 on Apache | .htaccess still names the old domain in its rewrite conditions. Regenerate it. |
Some customers get Authentication failed. with the right password | Legacy MD5 hashes need the original cookie_key. Restore the original parameters.php, or have them reset their password. |
| Everyone was signed out | new_cookie_key or cookie_iv changed, or the domain did. Expected after a domain change. |
| The front office shows the maintenance page | The dump was taken with the store closed. Set PS_SHOP_ENABLE to 1. |
Access denied; you need (at least one of) the PROCESS privilege(s) for this operation | Add --no-tablespaces to mysqldump. |
Moving the store to another provider? See moving a server to a new provider.
Frequently asked questions
- Does PrestaShop's DB Backup back up the whole store?
- No. Advanced Parameters > Database > DB Backup saves only the database, table by table without a transaction, into the back office folder on the same server. Images, downloads, modules, themes and parameters.php need a separate file backup.
- What happens if I lose the PrestaShop cookie key?
- Passwords hashed with bcrypt, which PrestaShop 8 and 9 use, keep working. Legacy MD5 hashes from 1.6-era accounts that have not logged in since fail until the person resets the password. A new new_cookie_key or cookie_iv signs everyone out.
- Do I need maintenance mode to back up PrestaShop?
- Not for mysqldump --single-transaction, which reads InnoDB tables from one snapshot while the store takes orders. Close the store only for the final backup before a move.
- Where does PrestaShop store product images and downloads?
- Product images are in img/p, category images in img/c, virtual products and attachments in download, and customer uploads for customizable products in upload.
How this was checked
Commands, limits and prices were checked against these official pages, on October 4, 2026:
- PrestaShop Developer Documentation 9: How to backup PrestaShop
- PrestaShop Developer Documentation 9: Post-restore checklist
- PrestaShop Developer Documentation 9: File structure
- PrestaShop Developer Documentation 9: Cache
- PrestaShop Developer Documentation 9: System requirements
- PrestaShop Developer Documentation 9: Migration (images, downloads, uploads, thumbnails)
- PrestaShop Developer Documentation 9: prestashop:config
- PrestaShop Developer Documentation 9: prestashop:htaccess:generate
- PrestaShop 9 user documentation: Database Backup
- PrestaShop 9 user documentation: SEO and URLs (Set shop URL)
- PrestaShop 9.2.0 release
- PrestaShop 9.2.0 source: installer (keys written to parameters.php)
- PrestaShop 8.2.8 source: installer (same keys)
- PrestaShop 9.2.0 source: Hashing (bcrypt, legacy MD5 salted with cookie_key; identical in 8.2.8)
- PrestaShop 9.2.0 source: Customer (rehash at login)
- PrestaShop 9.2.0 source: Cookie (new_cookie_key and cookie_iv)
- PrestaShop 9.2.0 source: config/bootstrap.php (parameters cached in var/cache)
- PrestaShop 9.2.0 source: PrestaShopBackup (DB Backup; identical logic in 8.2.8)
- PrestaShop 9.2.0 source: DB Backup page disclaimer
- PrestaShop 9.2.0 source: maintenance settings (PS_SHOP_ENABLE, PS_MAINTENANCE_IP)
- PrestaShop 9.2.0 source: Set shop URL (ps_shop_url, PS_SHOP_DOMAIN, .htaccess)
- PrestaShop 9.2.0 source: Shop::initialize (redirect to the stored domain)
- PrestaShop 9.2.0 source: PrestaShopException (error500.html, var/logs)
- PrestaShop 9.2.0 source: DbPDO (connection error)
- PrestaShop 9.2.0 source: CustomerLoginForm
- PrestaShop 9.2.0 source: config.inc.php (PS_TIMEZONE)
- PrestaShop 9.2.0 source: prestashop:thumbnails:regenerate
- Symfony 6.4 HttpKernel source: Kernel (cache directory errors)
- MySQL 8.4 Reference Manual: mysqldump
- MySQL 8.4 Error Message Reference: server errors