Migrate ghost images to cloudinary

frontend tips

It has taken me several days to figure it out. So I document the solution here for others to reference.

  1. Setup cloudinary storage adapter. Follow instructions at https://leecy.me/ghost-cloudinary/.

  2. Upload all images from disk to cloudinary. By default, images are stored locally, it’s necessary to upload them to cloudinary to ensure that old posts display correctly. Below is the bash script I used for uploading. Please execute it under $GHOST_INSTALL/content/images folder with command find -name "*.png" -not -path "*/size/*" -exec ~/upload.sh ".png" {} \; Do the same for other image types like jpg, jpeg. Remember to replace apiKey, apiSecret, cloudName with your cloudinary setting.

    #!/bin/bash
    
    fileName=$2
    suffix=$1
    timestamp=$(date +%s)
    apiSecret="your-secret"
    apiKey="your-key"
    cloudName="your-cloud"
    
    data="api_key=${apiKey}&file=${fileName}&timestamp=${timestamp}"
    
    echo $fileName
    public_id=$(echo $fileName | sed -E "s,\./([0-9]{4})/(\w{3}|[0-9]{2})/(.*)${suffix},\1\2\3,")
    echo $public_id
    
    datatobehashed="folder=blog-images&public_id=${public_id}&timestamp=${timestamp}$apiSecret"
    
    hash=$(echo -n ${datatobehashed} | sha1sum | awk '{print $1}')
    
    curl -X POST "https://api.cloudinary.com/v1_1/$cloudName/image/upload" -F "file=@${fileName}" -F "timestamp=${timestamp}" -F "api_key=$apiKey" -F "signature=$hash" -F "folder=blog-images" -F "public_id=$public_id"
    
    echo "upload file $fileName"
    
  3. Export your content from setting/lab and reimport. Open the json file with an editor like VSCode to do regex replace with pattern GHOST_URL/content/images/(\d{4})/(\w{3}|\d{2})/ to https://res.cloudinary.com/your-cloudname/image/upload/blog-images/$1$2. Then delete all content and import the new json file.