How to Manually Back Up Ghost CMS: Database, Files, and Config.
Learn how to back up and restore a self-hosted Ghost site, including its database, content files, and configuration. Covers MySQL and SQLite, with commands for a standard Ghost-CLI installation.
A reliable Ghost backup needs more than a copy of the content folder. A full recovery set should include the database, uploaded files and themes, Ghost’s configuration, and any server configuration needed to bring the site back online.
This guide covers a manual backup for a standard Ghost-CLI installation and the corresponding restore process. Ghost-CLI’s ghost backup command is simpler for many sites, but a manual backup can make each component explicit and easier to store or transfer independently.
Scope: These steps assume Ghost is installed with Ghost-CLI in/var/www/ghostand runs under theghostsystem account. Adapt paths and ownership for your installation. Docker deployments need volume- and container-specific steps.
What to back up
For a self-hosted Ghost installation, preserve:
- The database.
Ghost stores posts, users, settings, members, and other application data in its database. Production Ghost installations commonly use MySQL; SQLite is also used in some setups. - The content directory.
This includes uploaded images and files, themes, and other content files. Its path may be customized. - Configuration.
Saveconfig.production.json, which contains site and database settings. It includes secrets, so keep the backup private. - Related server configuration.
If you need to rebuild the same server, also save relevant Nginx or Apache configuration, custom scripts, and certificates that you manage yourself. Keep private keys and credentials protected.
Ghost’s Admin export is useful for moving content between Ghost sites, but it is not a complete disaster-recovery backup. Ghost’s manual backup guide recommends backing up the database and content directory directly for recovery or exact replication.
1. Prepare a protected backup directory
Choose storage with enough free space. Ideally, copy completed backups to a separate machine or storage service; a backup on the same server will not help if that server fails.
From the Ghost installation directory, create a dated backup folder outside the site directory. This example stores backups in /home/backup/ghost:
$ cd /var/www/ghost
$ sudo install -d -m 0700 -o "$USER" -g "$(id -gn)" "/home/backup/ghost/$(date +%F)"
The examples below use that dated folder. If you are running commands as a different account, adjust ownership and permissions so only trusted users can read the backup—especially the config file and database dump.
2. Stop Ghost for a consistent file backup
Stop the Ghost instance before copying its content directory and SQLite database:
$ cd /var/www/ghost
$ ghost stop
For a MySQL backup, mysqldump --single-transaction can produce a consistent snapshot for InnoDB tables while the database remains available. Avoid schema changes during the dump. Stopping Ghost for the complete backup window is the simpler approach when downtime is acceptable.
3. Back up the content directory and configuration
For a standard Ghost-CLI installation, the content directory is content/. Copy it and the production config into the dated backup directory:
$ sudo cp -a /var/www/ghost/content "/home/backup/ghost/$(date +%F)/"
$ sudo cp -a /var/www/ghost/config.production.json "/home/backup/ghost/$(date +%F)/"
If Ghost uses a custom contentPath, back up that directory instead. Check config.production.json for paths.contentPath and the database connection details. The SQLite database filename may also be customized; do not assume it is always content/data/ghost.db.
If you manage Nginx configuration or other local server files yourself, copy the relevant files as well. For example:
$ sudo cp -a /etc/nginx/sites-available/ghost "/home/backup/ghost/$(date +%F)/nginx-ghost.conf"
Adjust the path and filename for your system. Certificate renewal is often managed separately by the server’s certificate tooling; document how to restore or reissue certificates and protect any private keys you choose to back up.
4. Back up the database
Check config.production.json to see which database Ghost uses.
MySQL
Read the database name and username from the database.connection section of the config file. Create a logical SQL dump using mysqldump:
$ mysqldump --single-transaction --no-tablespaces -u ghost_user -p ghost_production > "/home/backup/ghost/$(date +%F)/ghost_database.sql"
Replace ghost_user and ghost_production with the configured database username and name. Enter the database password when prompted. Do not put the password directly in the command line, where it may be exposed in shell history or process listings.
--single-transaction is suitable for transactional InnoDB tables and avoids locking them for the duration of the dump. Do not run schema-changing statements such as ALTER TABLE, DROP TABLE, or RENAME TABLE during the dump. --no-tablespaces suppresses tablespace statements in the output; it may also avoid requiring the MySQL PROCESS privilege on supported versions. It is optional if your database server or client does not support it.
Check that the dump file exists and is non-empty:
$ sudo test -s "/home/backup/ghost/$(date +%F)/ghost_database.sql" && echo "Database dump created"
SQLite
If the site uses SQLite, find the database filename in config.production.json. For the common path content/data/ghost.db, copy the database while Ghost is stopped:
$ sudo cp -a /var/www/ghost/content/data/ghost.db "/home/backup/ghost/$(date +%F)/ghost.db"
If the configured filename differs, use that path. Stopping Ghost before copying avoids copying a database while it is being changed. The SQLite command-line tool also supports a database backup operation for making a consistent database copy, but the stopped-site file copy is straightforward for this procedure.
5. Compress the backup
After copying all required files, create an archive from the dated backup directory:
$ sudo tar -czf "/home/backup/ghost/ghost-backup-$(date +%F).tar.gz" -C "/home/backup/ghost" "$(date +%F)"
Check that the archive was created and list its contents:
$ sudo tar -tzf "/home/backup/ghost/ghost-backup-$(date +%F).tar.gz" | head
Store a copy somewhere separate from the Ghost server. Protect it as sensitive data because it may contain database credentials, member information, and other private data.
6. Start Ghost after the backup
Once the backup is complete, start the site again:
$ cd /var/www/ghost
$ ghost start
Check that the site loads and review logs if anything looks wrong:
$ ghost log
Restore a backup
Restoring replaces current site data. Confirm that you have the correct backup and that you are prepared to overwrite the current database and content before proceeding. Restore to a compatible Ghost installation, and keep the Ghost version in mind: database schema migrations may occur when Ghost starts under a different version.
1. Extract the archive
On the destination server, copy the archive into a protected backup directory and extract it. Replace the date with the date in your archive filename:
$ sudo mkdir -p /home/backup/restore
$ sudo tar -xzf /home/backup/ghost-backup-YYYY-MM-DD.tar.gz -C /home/backup/restore
The extracted files will be under a dated subdirectory such as /home/backup/restore/YYYY-MM-DD/.
2. Stop Ghost
$ cd /var/www/ghost
$ ghost stop
3. Restore the database
Restore into the database configured for the Ghost installation.
For MySQL, first confirm the database exists and that the configured Ghost database user has the required privileges. Then import the dump:
$ mysql -u ghost_user -p ghost_production < /home/backup/restore/YYYY-MM-DD/ghost_database.sql
Replace the username, database name, and directory date with your values. Enter the password when prompted.
For SQLite, preserve a copy of the current database before replacing it, then restore the saved database file to the configured path. For the common Ghost-CLI path:
$ sudo cp -a /var/www/ghost/content/data/ghost.db "/var/www/ghost/content/data/ghost.db.before-restore-$(date +%F)"
$ sudo cp -a /home/backup/restore/YYYY-MM-DD/ghost.db /var/www/ghost/content/data/ghost.db
If your SQLite database lives at a different path, use the filename configured in config.production.json.
4. Restore content and configuration
Restore the content directory. This replaces files at the destination, so check the source and destination paths carefully:
$ sudo rsync -a --delete /home/backup/restore/YYYY-MM-DD/content/ /var/www/ghost/content/
The --delete option removes files in the destination that are not present in the backup. Omit it if you want to preserve extra destination files, and review the paths before running the command.
Restore the production config only if appropriate for this server. A config from another host may contain an old URL, database password, SMTP credentials, or other environment-specific settings:
$ sudo cp -a /home/backup/restore/YYYY-MM-DD/config.production.json /var/www/ghost/config.production.json
Review and update the configuration for the destination server before starting Ghost. If you backed up Nginx configuration and intend to restore it, install it at the correct path, validate it, and reload Nginx:
$ sudo cp -a /home/backup/restore/YYYY-MM-DD/nginx-ghost.conf /etc/nginx/sites-available/ghost
$ sudo nginx -t
$ sudo systemctl reload nginx
5. Fix ownership and start Ghost
For a standard Ghost-CLI installation, the service account is commonly named ghost. Restore ownership of the content directory:
$ sudo chown -R ghost:ghost /var/www/ghost/content
If your installation uses a different account or path, use the values configured for that installation. Then start Ghost:
$ cd /var/www/ghost
$ ghost start
6. Verify the restored site
Open the site and Ghost Admin. Check representative posts, images, themes, members, and other data. Review the Ghost logs:
$ cd /var/www/ghost
$ ghost log
If you use Nginx, you can also verify its configuration before or after reloading it:
$ sudo nginx -t
A backup is only dependable if it can be restored. Periodically test the process on a separate staging installation and confirm that the database and content files work together.
Ghost Admin export vs. full backup
Ghost Admin’s export tools are useful when migrating content between sites. Depending on what you select, the export can include content and settings, members, analytics, themes, redirects, and routes. It does not replace a direct database and content-folder backup for disaster recovery or exact replication. Ghost’s documentation also notes that images and media require copying separately for a manual content migration.
Ghost-CLI provides a convenient ghost backup command that creates a ZIP containing key site data. Review the current Ghost-CLI documentation for the contents and limitations of that archive, and keep separate database and server-level backups if you need a complete recovery plan.
A useful Ghost backup includes the database, content directory, production configuration, and any server files needed to rebuild the site. Keep the backup private, store a copy away from the server, and test the restore process before you need it. Ghost Admin exports and ghost backup are convenient tools, but understand what each contains and choose the method that matches your recovery needs.
We hope you found these tips helpful and interesting.