Urgent Help Needed: Migrating Ghost Blog to New VPS

Hello Ghost community,
I’m in desperate need of assistance migrating my Ghost blog from one VPS to another (larger) VPS. I’ve been struggling with this for over 12 hours and have encountered numerous issues. I’m hoping an experienced IT professional or Ghost expert can provide guidance.

Current situation:
• Source and destination servers are both running Ubuntu (same version)
• I only have SSH access to both servers
• My hosting provider doesn’t offer a migration option

What I’ve tried:
1. Following various online migration guides, but they don’t seem to work for my specific setup
2. Using Ghost’s backup options, but I’ve had issues with documentation and implementation
3. Attempting to copy the entire installation 1:1
4. Fresh installation on the new server and importing data
5. Using Perplexity Pro AI assistance for hours, which led to circular solutions

Issues encountered:
• MySQL configuration problems
• Nginx setup issues
• Systemd conflicts

I’m comfortable following step-by-step guides and have a basic understanding of what I’m doing, but I lack the expertise to troubleshoot these complex issues.

Questions:
1. Is there a reliable, straightforward method to migrate a Ghost blog between VPS servers?
2. Are there any specific tools or scripts designed for Ghost migrations that I might have overlooked?
3. What precautions should I take to ensure I don’t lose any data during the migration process?

I’m at my wit’s end and would greatly appreciate any insights, tips, or step-by-step instructions from someone who has successfully performed this kind of migration before.

Thank you in advance for your help!

This doc is the migration guide for Ghost → Ghost.

The import end is written from the POV of importing into Ghost(Pro), but the general idea is there and it is solid from the POV of getting your content from your current host.

This guide will cover you for:

Be aware that if you follow those docs you will lose member comments and mess up newsletter signups if you have more than one. I did it recently and wish I had made a database backup via sqldump instead.

Yes that’s the point I tried all docs but they don’t work even when I’m fine losing members and comments the guidelines just don’t work or are not properly documented. I find that this is a big lack in the docs. It can’t be that hard to transfer from one server to the other. But I can’t find anything useful :/
Also the Backup function is not properly documented just manual but CLI import is not documented at all from my research. Or I’ve missed something
Really frustrating after hours of trying hard

The docs Jon linked above should accomplish what you need, if you don’t care about comments or newsletters.

(@Jon - looks like the part about using the admin panel importer needs to be updated to say there’s a dedicated import/export section, instead of it being in Labs still.)

Other docs - more on backing up here: How to reinstall Ghost

A commentary on my recent move: I moved servers!

Can you add some details about what you’ve done from those linked directions, and where you’re stuck?

AI is sometimes not a great way to get help as a novice, because you can’t spot the hallucinations.

Aside: If you’re migrating within the same host, you might ask them if they can move/upgrade the whole vps image, unless you’re also upgrading distros or something at the same time.

Thanks for the fast reply I will look into it further and get back with (hopefully) a success message :)

1 Like

Hey Ghost People,
thank you very much for the guides you’ve sent to me. I wish I had them 24hrs earlier.

I managed to Migrate my entire Ghost Installation (Blog, no members) from my old VPS to my New VPS without any problems.

This guide How to reinstall Ghost sent to me by @Cathy_Sarisky made it possible.

I don’t know why I didn’t find it before. I suggest extending this Doc a little with some SEO content for what and when this is useful.

This I would add as well:

  1. IP, what the user has to do with the DNS settings when migrating. I did it like in the installation and pointed my Domain to the new Server when I was ready for the Ghost installation. But that was not pointed out clearly in the guide, as it’s just a “Reinstall Guide”.
  2. How to get the Backup File from one VPS to the other. I did it with SFTP “get” and “put” but i know there is also a way with wget. It is also needed to have the right permission before putting the BackupFile.zip in the /content folder. So I changed it to my current user and after the UnZip back to the ghost. I only knew this from fails I had before. But this part would help as well.
  3. In General, the Doc could be more structured and explain a little more but it works somehow.

Thank you very much for your help <3

I will now tackle the next topic:
How to run daily backups and saving them to G-Drive if you have any suggestions, I’m happy to NOT waste hours before asking :slight_smile:

Here some SEO content for people to find this Post:

Summary

Migrating your self-hosted Ghost blog to a new server without losing any data is crucial for anyone wanting a smooth transition. This guide offers a step-by-step approach to fully migrate your server, reinstall it, and transfer your Ghost blog to a new VPS. Whether you’re changing servers or upgrading your existing setup, we provide detailed instructions to ensure your data remains safe ,and your blog operates seamlessly. It’s ideal for anyone looking for thorough guidance on relocating their Ghost blog between servers.

1 Like

Hey,
one last problem just revealed…
I can’t get the Mail config back to work. I’ve rewritten the config.production multiple times and the mail gun keys in the /ghost admin panel, but when I try to send an invitation it says check mail config. I think it might be from the Backup Import, but I don’t want to break the server by trying to much :)

This comes when sending invite:

This comes when resending the invite:
Please verify Email settings

Thank you in advance :slight_smile:

You’re on Docker? It takes environment variables, not a config file, typically. You have a docker compose file? Changes go there.

If that’s not it, trying to send the email and then looking in your logs (content/logs) is going to be helpful.

I’m on an normal Ubuntu Ghost Installation.
I’ve tried now Ghost log in the CLI but cant really figure out what is going on the Instruction about mail i already followed.

Here is the Log i’ve got:

ubuntu:/var/www/insights$ ghost log

Love open source? We’re hiring JavaScript Engineers to work on Ghost full-time.
https://careers.ghost.org


+ sudo systemctl is-active ghost_insights-gaido-world
? Sudo Password [hidden]
[2025-02-15 14:38:44] INFO "GET /ghost/api/admin/incoming_recommendations/?limit=5&order=created_at+desc" 200 85ms
[2025-02-15 14:38:44] INFO "GET /ghost/api/admin/stats/referrers/" 200 85ms
[2025-02-15 14:38:44] INFO "GET /ghost/api/admin/newsletters/?include=count.active_members%2Ccount.posts&limit=50" 200 90ms
[2025-02-15 14:38:44] INFO "GET /ghost/api/admin/recommendations/?include=count.clicks%2Ccount.subscribers&order=created_at+desc&limit=5" 200 97ms
[2025-02-15 14:38:44] INFO "GET /ghost/api/admin/integrations/?include=api_keys%2Cwebhooks" 200 94ms
[2025-02-15 14:38:45] INFO "GET /ghost/assets/admin-x-settings/modals-81dd574e.mjs" 200 94ms
[2025-02-15 14:38:57] INFO "DELETE /ghost/api/admin/invites/67b011aa946dc905a4dde85d/" 204 14ms
[2025-02-15 14:39:02] WARN Missing mail.from config, falling back to a generated email address. Please update your config file and set a valid from address
[2025-02-15 14:39:02] WARN Missing mail.from config, falling back to a generated email address. Please update your config file and set a valid from address
[2025-02-15 14:39:03] WARN Error sending email: Failed to send email. Reason: 0058DD3E1B7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:355:
. Please check your email settings and resend the invitation.
[2025-02-15 14:39:03] ERROR "POST /ghost/api/admin/invites/" 500 84ms

NAME: EmailError
CODE: ESOCKET
MESSAGE: Error sending email: Failed to send email. Reason: 0058DD3E1B7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:355:
. Please check your email settings and resend the invitation.

level: normal

"Please see https://ghost.org/docs/config/#mail for instructions on configuring email."
Error: 0058DD3E1B7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:355:
.


[2025-02-15 14:39:36] INFO "GET /ghost/api/admin/roles/?limit=all&permissions=assign" 200 68ms
[2025-02-15 14:40:03] WARN Missing mail.from config, falling back to a generated email address. Please update your config file and set a valid from address
[2025-02-15 14:40:03] WARN Missing mail.from config, falling back to a generated email address. Please update your config file and set a valid from address
[2025-02-15 14:40:03] WARN Error sending email: Failed to send email. Reason: 0058DD3E1B7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:355:
. Please check your email settings and resend the invitation.
[2025-02-15 14:40:03] ERROR "POST /ghost/api/admin/invites/" 500 58ms

NAME: EmailError
CODE: ESOCKET
MESSAGE: Error sending email: Failed to send email. Reason: 0058DD3E1B7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:355:
. Please check your email settings and resend the invitation.

level: normal

"Please see https://ghost.org/docs/config/#mail for instructions on configuring email."
Error: 0058DD3E1B7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:355:
.


[2025-02-15 14:40:08] WARN Missing mail.from config, falling back to a generated email address. Please update your config file and set a valid from address
[2025-02-15 14:40:08] WARN Missing mail.from config, falling back to a generated email address. Please update your config file and set a valid from address
[2025-02-15 14:40:08] WARN Error sending email: Failed to send email. Reason: 0058DD3E1B7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:355:
. Please check your email settings and resend the invitation.
[2025-02-15 14:40:08] ERROR "POST /ghost/api/admin/invites/" 500 53ms

NAME: EmailError
CODE: ESOCKET
MESSAGE: Error sending email: Failed to send email. Reason: 0058DD3E1B7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:355:
. Please check your email settings and resend the invitation.

level: normal

"Please see https://ghost.org/docs/config/#mail for instructions on configuring email."
Error: 0058DD3E1B7F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:355:
.



Maybe someone know what i need to do i guess it has to do with ssl but this is above my level to try on my own without someone pointing out the direction :slight_smile: Because i dont want to ruin my installation again XD

Can you share your compose file, after removing secrets?

Is there a compose file in a regular installation on Ubuntu? I cant find that without Docker :confused: maybe i dont get it right

Sorry, I got your problem confused with someone else’s ! Post config,production.json, in that case!

1 Like
{
  "url": "https://notmydomain",
  "server": {
    "port": 2368,
    "host": "127.0.0.1"
  },
  "database": {
    "client": "mysql",
    "connection": {
      "host": "127.0.0.1",
      "user": "notmyuser",
      "password": "notmypasword",
      "database": "notmydatabase"
    }
  },
  "mail": {
    "transport": "SMTP",
    "options": {
      "service": "Mailgun",
      "host": "smtp.eu.mailgun.org",
      "port": 587,
      "secure": true,
      "auth": {
        "user": "postmaster@notmydomain",
        "pass": "932603b1notmypassword932603b1"
      }
    }
  },
  "logging": {
    "transports": [
      "file",
      "stdout"
    ]
  },
  "process": "systemd",
  "paths": {
    "contentPath": "/var/www/insights/content"
  }
}

Common issues: is your mailgun account set up for E.U.? (Remove from the mailgun domain if not.)

Try:

  "mail": {
    "from": "support@your.domain",
    "transport": "SMTP",
    "options": {
      "host": "smtp.eu.mailgun.org",
      "port": 587,
      "service": "Mailgun",
      "secure": false,
      "requireTLS": true,
      "auth": {
        "user": "postmaster@mg.your.domain",
        "pass": "xxxxxxxxxx"
      }
    }
  },

Or try swaks for debugging - see this page Sending Messages

Okay, after a lot of trail and error I found out:

this is the config that works for me:

  "mail": {
    "transport": "SMTP",
    "options": {
      "service": "Mailgun",
      "host": "smtp.eu.mailgun.org",
      "port": 465,
      "secure": true,
      "auth": {
        "user": "postmaster@my.domain",
        "pass": "******NEW-Mailgun SMTP PW******"
      }
    }
  },

I’m guessing that the Mailgun Server was not allowing the connection from a new server with the same config or something like that so i reset the Mailgun SMTP PW

Thanks for your help

This is super interesting. I thought I was the only one…

I had cases where the SMTP password was 100% correct and worked – then I deployed the same site on a different server (I am running a managed hosting service on a distributed Kubernetes infrastructure) and well…same password gets rejected by Mailgun :upside_down_face:

I had quite an extensive exchange with the Mailgun support, who did not see a problem on their end and was absolutely convinced that I typed the wrong password (and did not read the fact that the only difference was a redeployment).

Good to know that I am not the only one…I built a workaround that uses the Mailgun API to reset the password, but if you’re running into the same issue, I might open that ticket again :person_shrugging:

Thanks for sharing!

1 Like