SM Windows to Linux migration experiment
Question asked by Sébastien Riccio - 6/14/2024 at 10:46 AM

I would like, with this thread, to share my experimentation at migrating domains and users accounts from a windows installation to a linux test box.

Some basic background stuff

  • Source server is a Windows 2019 VM on Hyper-V with 4 mail data storage disks attached (D, E, F, G)
  • Linux test server is a Ubuntu 24.04 VM hosted on our proxmox cluster
  • For the data replication I've used a network share we created on one of our full NVMe SAN/SAN (Huawei dorado 5000), exported with both NFS and CIFS.
The share is mounted:

  • On existing SM windows server, via CIFS, (mapped as letter Z: for later use with robocopy)
  • On the test Linux VM via NFS (as /mnt/mail_data). /etc/fstab entry on the Lifor it looks like this:
filer03:/mail_data  /mnt/mail_data  nfs     rw,fsc,async,ac,actimeo=300,noatime,nconnect=16,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys 0 0

On the Linux VM:

  • Installed unbound as local DNS resolver
  • Installed SmarterMail Linux BETA (without web server) and configured basic stuff (bindings, dns set to local unbound resolver and other general settings)
  • Installed caddy web server (for reverse proxy with automatic HTTPS certificates handling). /etc/caddy/Caddyfile content looks like this:
        grace_period 3s
        log {
                output file /var/log/caddy/caddy.log {
                        roll_size 250MiB
                        roll_keep_for 15d
                level ERROR
        email letsencrypt@swisscenter.com
        on_demand_tls {
                interval 2m
                burst 10000
        default_sni mail03.swisscenter.com

(common) {
        # Return server FQDN
        @sc_server_fqdn {
                path /_sc_get_server_fqdn
        respond @sc_server_fqdn "mail03.swisscenter.com" 200 {

        # Reverse proxy the request to SmarterMail endpoint

(ondemand) {
        tls {

# Host related endpoints
https://localhost, https://localhost.localdomain {
        tls internal

# Main host
mail03.swisscenter.com {
        import common
http:// {
        import common
https:// {
        import ondemand
        import common

I then: 

  • Checked that SmarterMail on the Linux VM is running and the web interface is answering through it's public IP bound to the caddy webserver.
  • Logged in as admin and disabled all retrieval services (IMAP, POP, EWS) to avoid importing any external stuff to this server.
  • Stopped the SmarterMail server on the linux host
  • Replaced /etc/smartermail/administrators.json with the one from source server
  • Exported anti-spam rules from source server and re-imported them in destination server
  • Copied current domains config-only files (well mostly all but without stats, indexing and GRP files)
Robocopy to the rescure for this, on the windows host:

robocopy "D:\SmarterMail\Domains\*" "Z:\domains" /E /R:1 /W:1 /XF *.stat* *.grp /XD FileStore IndexV2 /NP /LOG+:"%TEMP%\RoboCopy.log"
robocopy "E:\SmarterMail\Domains\*" "Z:\domains" /E /R:1 /W:1 /XF *.stat* *.grp /XD FileStore IndexV2 /NP /LOG+:"%TEMP%\RoboCopy.log"
robocopy "F:\SmarterMail\Domains\*" "Z:\domains" /E /R:1 /W:1 /XF *.stat* *.grp /XD FileStore IndexV2 /NP /LOG+:"%TEMP%\RoboCopy.log"
robocopy "G:\SmarterMail\Domains\*" "Z:\domains" /E /R:1 /W:1 /XF *.stat* *.grp /XD FileStore IndexV2 /NP /LOG+:"%TEMP%\RoboCopy.log"

  • Replaced /etc/smartermail/domains.json with the one from source server and replaced the domain paths with a sed oneliner:
sed -i 's/[DEFG]\:\\\\smartermail\\\\domains\\\\/\/mnt\/mail_data\/domains\//ig' domains.json

  • Started SmarterMail again on the Linux host and connected to the web interface.
  • At this point it started converting attached domains, probably to update some path and stuff (so they are compatible with Linux paths ?)
  • After a few minutes the login screen appeared and I was able to log-in and list the domains, log into some user accounts, etc. Seems quite a success so far.

The conversion log reported some conversion issue though and these domains seems to fail loading:

[2024.06.14] 03:56:09.810 [domain1.com] Could not find '/mnt/mail_data/domains/domain1.com/Archived Data/settings.json' this domain will now be converted.
[2024.06.14] 03:56:09.813 [domain1.com] Conversion started.
[2024.06.14] 03:56:09.817 [domain1.com][Error] Message: Unable to read important domain data file
[2024.06.14] Exception: SmarterMail.Standard.Files.Exceptions.SMNotFoundException: Could not find a part of the path '/mnt/mail_data/domains/domain1.com'.
[2024.06.14]  ---> System.IO.DirectoryNotFoundException: Could not find a part of the path '/mnt/mail_data/domains/domain1.com'.
[2024.06.14]    at System.IO.Enumeration.FileSystemEnumerator`1.Init()
[2024.06.14]    at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
[2024.06.14]    at System.IO.Enumeration.FileSystemEnumerableFactory.UserFiles(String directory, String expression, EnumerationOptions options)
[2024.06.14]    at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
[2024.06.14]    at System.IO.Directory.GetFiles(String path, String searchPattern, EnumerationOptions enumerationOptions)
[2024.06.14]    at SmarterMail.Standard.Files.DirectoryX.GetFiles(String path) in /build/SmarterMail/gitsrc/src/SmarterMail.Standard/Files/DirectoryX.cs:line 207
[2024.06.14]    --- End of inner exception stack trace ---
[2024.06.14]    at SmarterMail.Standard.Files.DirectoryX.GetFiles(String path) in /build/SmarterMail/gitsrc/src/SmarterMail.Standard/Files/DirectoryX.cs:line 218
[2024.06.14]    at SmarterMail.Data.Converters.DomainConverter.ReadSourceFiles() in /build/SmarterMail/gitsrc/src/SmarterMail/MailService/Data/Converters/DomainConverter.cs:line 534
[2024.06.14]    at SmarterMail.Data.Converters.DomainConverter.Convert(String domainPath, String domain, UpgradeStatus status) in /build/SmarterMail/gitsrc/src/SmarterMail/MailService/Data/Converters/DomainConverter.cs:line 76
[2024.06.14] 03:56:09.821 [domain1.com] Conversion finished in 0 seconds.
I noticed that the domain folder on the windows server was full caps DOMAIN1.COM, while in the domains.json it was all lowercase (strange ?) Renaming it to lowercase fixed the issue.

My next testing step will be to actually fully migrate some domains (personal, colleagues, family, friends) to the server and switch to it for real daily usage test.

I have some questions for ST Team:

  • Does the migration process seems correct to you ? Are there some stuff to be aware that I maybe missed ?
  • It looks like the web interface is a bit slower on the Linux VM, for example listing domains takes 4-5 seconds while it's quite instant on the windows VM. I thought it was the NFS mount which is was slowing this down, but I did a test copying the domains files locally and it's almost the same speed for listing domains.
Kind regards,

Sébastien Riccio
System & Network Admin

2 Replies

Reply to Thread
Zach Sylvester Replied
Employee Post
Hey Sébastien,

Unlike Windows, Linux is case-sensitive, which explains the issue with grabbing the domain info. If you could open a ticket with support so we can get some more details and get a development task escalated for this, that would be amazing.

Regarding the slowness issue, it is likely due to server hardware or disk read and write speeds. If you right-click, then click "inspect element" and go to the network tab, which API calls are taking the longest?

Zach Sylvester System/Network Administrator SmarterTools Inc. (877) 357-6278 www.smartertools.com
Tony Scholz Replied
Employee Post

Thank you for sharing your experience. This wil be helpfull for those getting ready to move over once we go public. 
Tony Scholz System/Network Administrator SmarterTools Inc. (877) 357-6278 www.smartertools.com

Reply to Thread