-
Notifications
You must be signed in to change notification settings - Fork 215
Manual Backup & Restore Guide
This guide covers what to back up, how to back it up, and how to safely restore or migrate a Cypht installation. Automated backup strategies will be covered in a separate guide.
- Cypht — Manual Backup & Restore Guide
Cypht keeps application code and user data strictly separated. The application files (PHP, JS, CSS, modules) contain no user data and can always be replaced from the official release. Everything that is specific to your installation lives in exactly four places:
| Location | Controlled by | Contains |
|---|---|---|
.env |
You | All environment/runtime configuration |
Database (hm_user, hm_user_settings, hm_user_session) |
DB_* settings in .env
|
User accounts, encrypted settings, active sessions |
USER_SETTINGS_DIR |
USER_SETTINGS_DIR in .env
|
Per-user settings stored as files (alternative to DB) |
ATTACHMENT_DIR |
ATTACHMENT_DIR in .env
|
Uploaded email attachments |
Which of these apply to you depends on two .env settings:
USER_CONFIG_TYPE=file # "file" → USER_SETTINGS_DIR is used
USER_CONFIG_TYPE=DB # "DB" → database tables are used
Both ATTACHMENT_DIR and .env are always relevant regardless of USER_CONFIG_TYPE.
What you need to back up depends on your goal.
When upgrading Cypht in place, only the application files are replaced. The database and data directories (USER_SETTINGS_DIR, ATTACHMENT_DIR) live outside the Cypht application directory by default and are never touched during an upgrade. The only file inside the application root that contains your data is:
-
.env— back this up before replacing the application files.
When moving to a different server or performing a full restore, you need all of the following:
-
.env— contains every runtime secret and configuration value for your instance. -
ATTACHMENT_DIR(default:/var/lib/hm3/attachments) — uploaded email attachments. Not strictly required if all emails still exist on the remote mail servers, but losing this directory means previously downloaded attachments are unrecoverable. -
Database (when
USER_CONFIG_TYPE=DBorAUTH_TYPE=DB):-
hm_user— usernames and password hashes (required for login) -
hm_user_settings— per-user encrypted settings (IMAP/SMTP accounts, preferences, etc.) -
hm_user_session— active sessions (not critical; sessions expire naturally)
-
-
USER_SETTINGS_DIR(default:/var/lib/hm3/users, whenUSER_CONFIG_TYPE=file) — one encrypted settings file per user. Losing this directory means all users lose their saved accounts and preferences.
Tip: You can find the exact paths configured for your installation by inspecting your
.envfile.
The .env file lives at the root of your Cypht installation (e.g. /var/www/html/cypht/.env).
# Copy to a secure off-site location
cp /var/www/html/cypht/.env /path/to/secure/backup/.env.$(date +%Y%m%d)Security note: The
.envfile contains database credentials and encryption-related settings. Store backups with restricted permissions (chmod 600) and never commit it to version control.
Applicable when USER_CONFIG_TYPE=DB (or when AUTH_TYPE=DB).
The three relevant tables are hm_user, hm_user_settings, and hm_user_session. Read the database connection settings from your .env:
DB_DRIVER=mysql # mysql | pgsql | sqlite
DB_HOST=127.0.0.1
DB_NAME=cypht_db
DB_USER=cypht_user
DB_PASS=secret
mysqldump -h 127.0.0.1 -u cypht_user -p cypht_db \
> cypht_db_backup_$(date +%Y%m%d).sqlpg_dump -h 127.0.0.1 -U cypht_user -d cypht_db \
-f cypht_db_backup_$(date +%Y%m%d).sql# DB_SOCKET in .env contains the path to the .sqlite file
cp /path/to/cypht.sqlite cypht_db_backup_$(date +%Y%m%d).sqliteOr use the SQLite CLI for a consistent snapshot:
sqlite3 /path/to/cypht.sqlite ".backup '/path/to/backup/cypht_db_backup_$(date +%Y%m%d).sqlite'"Applicable when USER_CONFIG_TYPE=file.
Using tar (compressed archive):
USER_SETTINGS_DIR=/var/lib/hm3/users # adjust to your configured path
tar -czf cypht_users_backup_$(date +%Y%m%d).tar.gz "$USER_SETTINGS_DIR"Using cp (plain directory copy):
USER_SETTINGS_DIR=/var/lib/hm3/users # adjust to your configured path
cp -a "$USER_SETTINGS_DIR" /path/to/secure/backup/users_$(date +%Y%m%d)Using tar (compressed archive):
ATTACHMENT_DIR=/var/lib/hm3/attachments # adjust to your configured path
tar -czf cypht_attachments_backup_$(date +%Y%m%d).tar.gz "$ATTACHMENT_DIR"Using cp (plain directory copy):
ATTACHMENT_DIR=/var/lib/hm3/attachments # adjust to your configured path
cp -a "$ATTACHMENT_DIR" /path/to/secure/backup/attachments_$(date +%Y%m%d)These steps also apply when migrating to a new server. The key principle: never delete USER_SETTINGS_DIR, ATTACHMENT_DIR, or your database — only replace the application files.
cp /path/to/secure/backup/.env /var/www/html/cypht/.env
chmod 640 /var/www/html/cypht/.env
chown www-data:www-data /var/www/html/cypht/.env # adjust to your web server userVerify that the DB_HOST, USER_SETTINGS_DIR, and ATTACHMENT_DIR values reflect the new server's paths/hostnames if you are migrating.
# Create the database on the new server if it does not exist
mysql -h 127.0.0.1 -u root -p -e "CREATE DATABASE IF NOT EXISTS cypht_db CHARACTER SET utf8mb4;"
# Restore
mysql -h 127.0.0.1 -u cypht_user -p cypht_db < cypht_db_backup_YYYYMMDD.sqlcreatedb -h 127.0.0.1 -U postgres cypht_db
psql -h 127.0.0.1 -U cypht_user -d cypht_db -f cypht_db_backup_YYYYMMDD.sqlcp cypht_db_backup_YYYYMMDD.sqlite /path/to/cypht.sqlite
chown www-data:www-data /path/to/cypht.sqlite
chmod 660 /path/to/cypht.sqliteUSER_SETTINGS_DIR=/var/lib/hm3/users
mkdir -p "$USER_SETTINGS_DIR"
tar -xzf cypht_users_backup_YYYYMMDD.tar.gz -C /
chown -R www-data:www-data "$USER_SETTINGS_DIR"
chmod 700 "$USER_SETTINGS_DIR"ATTACHMENT_DIR=/var/lib/hm3/attachments
mkdir -p "$ATTACHMENT_DIR"
tar -xzf cypht_attachments_backup_YYYYMMDD.tar.gz -C /
chown -R www-data:www-data "$ATTACHMENT_DIR"
chmod 700 "$ATTACHMENT_DIR"The recommended upgrade process preserves all user data and only replaces application code.
Same-server upgrade: Only .env needs to be backed up. The database and data directories are outside the application root and will not be affected.
cp /var/www/html/cypht/.env /path/to/secure/backup/.env.$(date +%Y%m%d)Migration to a new server: Follow all backup procedures in section 3 before proceeding.
cd /tmp
wget https://github.com/cypht-org/cypht/archive/refs/tags/vX.Y.Z.tar.gz
tar -xzf vX.Y.Z.tar.gz# Remove old application files
# Copy new application files
# Restore the backed up .env file
cp /path/to/secure/backup/.env.YYYYMMDD /var/www/html/cypht/.env
Replace YYYYMMDD with the actual date from the backup file you want to restore (e.g., 20260406).
Note:
USER_SETTINGS_DIRandATTACHMENT_DIRlive outside the application root by default (/var/lib/hm3/), so they are automatically preserved. If you customized these to be inside the application root, exclude them from thefindcommand above.
cp /path/to/secure/backup/.env "$CYPHT_ROOT/.env"cd "$CYPHT_ROOT"
composer install --no-dev --optimize-autoloaderCypht uses incremental SQL migration files located in database/migrations/. The setup_database.php script applies any new migrations that have not yet been run:
php scripts/setup_database.phpThe script reads your .env automatically. It is safe to run on an existing database — it only applies migrations that are not yet present and will not destroy existing data.
Check database/migrations/<driver>/ for new .sql files after each upgrade to understand what schema changes were made.
Log in and verify that your accounts, settings, and preferences are intact.
-
.envbacked up - New release downloaded
- Application files replaced
-
.envrestored -
composer installrun -
php scripts/setup_database.phprun - Login and functionality tested
-
.envbacked up - Database dump (when
USER_CONFIG_TYPE=DBorAUTH_TYPE=DB) -
USER_SETTINGS_DIRbacked up (whenUSER_CONFIG_TYPE=file, default:/var/lib/hm3/users) -
ATTACHMENT_DIRbacked up (default:/var/lib/hm3/attachments) - New server provisioned and Cypht installed
-
.envrestored and updated for the new server - Database restored
-
USER_SETTINGS_DIRandATTACHMENT_DIRrestored -
composer installrun -
php scripts/setup_database.phprun - Login and functionality tested