Migration: parextour → parexservice ¶
Context ¶
Migrating WordPress sites (parextour.it, parextour.com) and mail for all 4 domains (parextour.it, parextour.com, parexincoming.com, parextour.ir) from the legacy parextour host (Ubuntu 18.04, native services) to parexservice (Ubuntu 20.04, Docker-based). Databases move from RDS parextour-db-01 (MariaDB 10.11) to RDS parex-01 (MySQL 8.4). Webmail is NOT migrated.
Current State ¶
Source: parextour (35.157.52.171) ¶
- Apache + PHP 7.2, native Postfix + Dovecot
- WordPress: parextour.it (2GB), parextour.com (116MB) under
/var/www/html/ - Mail: parextour.it (14GB, 16 users), parexincoming.com (347MB, 2 users), parextour.ir (183MB, 12 users), parextour.com (1.4MB, 11 users) — Maildir at
/var/vmail/<domain>/<user@domain>/ - Mail auth: MySQL
postfixDB on RDS parextour-db-01, Dovecot MD5 password scheme - WP DBs:
parextourit,parextourcomon same RDS
Destination: parexservice (18.184.20.117) ¶
- Docker: nginx-proxy + acme-companion, docker-mailserver v15, 5 WP containers (xaossystems/php8.3-fpm-apache2)
- Mail config: file-based accounts in
/data/dms/config/postfix-accounts.cf, SHA512-CRYPT - Compose:
/root/docker/mailserver/docker-compose.yml - Disk: /data at 84% — only 2.3GB free. Needs ~20GB expansion.
Phase 0: Preparation ¶
0.1 Expand /data EBS volume on parexservice ¶
- Identify EBS volume for
/dev/nvme1n1on instancei-07bc758b42735b8ec - Snapshot for safety, then resize from 15GB → 35GB (online, no downtime)
growpart+resize2fson the host
0.2 Clean up stale data on parexservice ¶
- Remove
/data/html/parexservice.deleteand/data/html/wordpress.delete(~536MB)
0.3 Extract mail accounts and aliases from source ¶
- Query
postfixDB on parextour-db-01 for active mailboxes and aliases - This gives the definitive list for creating accounts on destination
Phase 1: WordPress Migration ¶
1.1 Migrate databases (MariaDB → MySQL) ✅ DONE 2026-03-06 ¶
- Dumped
parextourit(173 MB),parextourcom(2.1 MB),postfix(33 KB) from parextour-db-01 - Created databases + users on parex-01; users set to
mysql_native_password(PHP 7.2 compat) - Imported all 3 — row counts verified exact match
- Added SG rule
sgr-0d1c699e832778683: sg-87f5fcef → sg-06f0ee714339d2de6 port 3306 (temporary) - Updated
wp-config.php(x2), 5 postfix SQL maps,dovecot-sql.conf.ext→ parex-01 endpoint - Reloaded postfix + dovecot — both active
- parex-01 admin password reset to
Parex2026!RDS(was unknown) - parextour-db-01 ready to decommission after a few days monitoring
1.2 Copy WordPress files ✅ DONE 2026-03-07 ¶
- Transferred via tar pipe through local (servers in different AWS accounts, no direct connectivity)
--strip-components=3needed to land files at correct depth- Ownership fixed to
www-data:www-data
1.3 Update wp-config.php ✅ DONE 2026-03-07 ¶
- DB_HOST already pointed to parex-01 from Phase 1.1
- Added reverse-proxy SSL detection (required for nginx-proxy):
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') $_SERVER['HTTPS']='on';
1.4 Create WordPress Docker containers ✅ DONE 2026-03-07 ¶
- Image:
wordpress:php7.4-apache(NOT xaossystems/php8.3 — WP 4.7.5 is incompatible with PHP 8) - Bind mount:
/data/html/parextour.{it,com}:/var/www/html - Env:
VIRTUAL_HOST,LETSENCRYPT_HOST,LETSENCRYPT_EMAIL,TZ=Europe/Rome - Networks:
mailserver_proxy-tier,mailserver_db-tier,mailserver_mail-tier - Limits: 2GB RAM, 1 vCPU
1.5 Test with /etc/hosts override ✅ DONE 2026-03-07 ¶
- Both sites verified loading via
curl --resolve
1.6 Switch DNS A records ✅ DONE 2026-03-07 ¶
parextour.it→ 18.184.20.117 (www is CNAME → apex, no change needed)parextour.com→ 18.184.20.117- Let's Encrypt certs issued by acme-companion automatically
- Mail records (mail., mailadmin., webmail.*) left on 35.157.52.171 — mail not migrated yet
1.7 Final sync ¶
- Skipped — no active uploads during migration window
Phase 2: Mail Migration ¶
2.1 Create mail accounts on docker-mailserver ¶
docker exec mailserver setup email add <user@domain> <password>for each of the 41 mailboxes- Users will need new passwords (MD5 → SHA512-CRYPT, not convertible)
2.2 Configure aliases ¶
- Add aliases to
/data/dms/config/postfix-aliases.cfbased on extracted alias data
2.3 Generate DKIM keys ¶
docker exec mailserver setup config dkim domain <domain>for all 4 domains- Add DKIM TXT records to DNS (can be done before MX switch)
2.4 Configure Dovecot master user on parextour ¶
- Add to
/etc/dovecot/conf.d/10-auth.conf:auth_master_user_separator = * - Create
/etc/dovecot/master-userswith a master user entry (e.g.imapsync:{PLAIN}secretpassword) - Add master passdb in Dovecot config pointing to that file
- Reload Dovecot
- Test:
openssl s_client -connect parextour:993→A LOGIN user@domain*imapsync secretpassword
2.5 Run imapsync ¶
For each of the 41 mailboxes:
imapsync --host1 parextour --user1 <user@domain> --authuser1 <user@domain>*imapsync \
--password1 <master_pwd> \
--host2 parexservice --user2 <user@domain> --password2 <new_pwd> --ssl2
Script this in a loop using the account list from Phase 0.3.
2.6 Final imapsync run (just before MX switch) ¶
- imapsync is incremental — re-run to catch any mail received since initial sync
2.7 Switch MX records ¶
- All 4 domains MX →
mail.parexservice.it - Update SPF records to include 18.184.20.117
- Add DMARC records
2.8 Add autoconfig containers (optional) ¶
- Follow existing pattern for mail client autoconfiguration
Phase 3: Post-Migration ¶
- Monitor mail logs for bounces/issues
- Notify users of new passwords
- Keep parextour running ~2 weeks to catch MX-cached deliveries
- Decommission parextour + parextour-db-01 after stabilization
Verification ¶
- WordPress: test all pages, admin login, uploads, forms
- Mail: send/receive test for each domain, check DKIM/SPF headers
- SSL: verify Let's Encrypt certs issued for all new domains
docker logs mailserverfor errors
Comments
Please login to leave a comment.
No comments yet. Be the first to comment!