How To Migrate Your Ghost Blog To Zeit's Now

I recently moved my site from Digital Ocean to Now and wanted to share some of the steps I took. The process isn’t overly complicated but I ended up making a few mistakes that made the process a bit harder than I thought it would be.

This assumes the following:

  1. Export your content using either the Ghost Admin Dashboard or the Ghost-CLI. I used the dashboard because it was pretty straightforward, go to Labs > Export your content. This will output a JSON file with your settings, users, pages, tags and post data and meta data (published dates, etc.). Do keep in mind that it does not include any images you may have uploaded directly. If that’s the case you’ll also want to download your images folder located in the content folder (and any other folder that might contain information you want to keep e.g., logs, themes, etc.).

  2. On your local machine, do the following:

  1. After you did the above, you want to create two configuration files. I called mine config.development.json and config.production.json. Here is what I put in each (be sure to change the url in the production config to your own):

In config.development.json

In config.production.json

Note: What tripped me up was the contentPath. You need to make sure it does NOT include the trailing slash. Again, it should look like this:

  "paths": {
    "contentPath": "content"

I didn’t remove it the first time around and Ghost ended up saving everything in its installation location (in the node_modules/ghost/content location). And since every time you make a change to your site you have to re-deploy the whole thing, every change I would make would get deleted.

  1. Create the file server.js. Mine looks like this since I’m not doing anything custom
const ghost = require('ghost');

ghost().then((ghostServer) => ghostServer.start());
  1. Create the following folder structure
├── content
│   ├── data
│   ├── images
│   ├── logs
│   └── themes

So right now your main folder should look something like this:

├── config.development.json
├── config.production.json
├── content
│   ├── data
│   ├── images
│   ├── logs
│   └── themes
├── package-lock.json
├── package.json
└── server.js

If you had logs/images or other folders exported, you’d place them there.

  1. Now you want to create a new database. To do so, type in the following command in your terminal:
  1. This next step is optional but it helps me keep my commands organized. We’re going to add some npm scripts to our package.json file. Here’s what mine looks like:
"scripts": {
    "server": "node server.js",
    "start": "NODE_ENV=production npm run server",
    "dev": "NODE_ENV=development npm run server",
    "deploy": "now && now alias && now rm my-app --safe --yes"

Note: Be sure to change my-app to whatever name you used when you ran npm init. If you don’t remember, look at your package.json file. The now rm my-app –safe –yes will delete old deployments under the my-app name that are no longer aliased. You can see all your deployments using now ls

  1. For now alias to work we need to tell now which url we want to use. You can set this up in package.json file but I prefer doing it its own file called now.json. Mine looks like this:
  "alias": ""
  1. To start your ghost site locally run npm run dev. Since you don’t have a theme yet, you’ll most likely see a notification in your terminal but you can ignore it. We’ll take care of that next. Once the server is running, go to http://localhost:1234/ghost and create your credentials.

  2. Once you’re logged in, go to Design and upload your theme if you have one or download the zip for Casper and upload it.

  3. Next we’ll import the json file you exported at the beginning. To do that, go to Labs and click on Import content. I did receive a few warnings of duplicate data that was not imported but you can ignore those.

  4. After all that, if you go to http://localhost:1234 you should see all your posts and content there.

  5. And finally comes the time to deploy to now. To do so, simply run npm run deploy or now && now alias. It might take a minute or so depending on how much you’re deploying. Once that’s done, go to your url and you should see everything there.