Skip to content
docker 1 min read

Docker volume migration

Docker volume migration
Photo by Bernd 📷 Dittrich / Unsplash

I recently encountered the scenario of moving this ghost instance (my blog) from a host to another, for whatever reason. For the context, I ran this instance using a docker-compose.yaml on a machine as:

services:
  ghost:
    image: ghost:5-alpine
    restart: always
    ports:
      - 3006:2368
    environment:
      # see https://ghost.org/docs/config/#configuration-options
      database__client: mysql
      database__connection__host: db
      database__connection__user: root
      database__connection__password: JustAFantasticPassword
      database__connection__database: ghost
      # this url value is just an example, and is likely wrong for your environment!
      url: https://blog.duydao.org
      # contrary to the default mentioned in the linked documentation, this image defaults to NODE_ENV=production (so development mode needs to be explicitly specified if desired)
      #NODE_ENV: development
    volumes:
      - ghost:/var/lib/ghost/content

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: JustAFantasticPassword
    volumes:
      - db:/var/lib/mysql

volumes:
  ghost:
  db:

And the need was to migrate this whole stack from that machine, to another one, given that a docker-compose.yaml file with that exact content had already been waiting on the new server. So, what was left? As you can see, those 2 docker volumes ghost_ghost and ghost_db!

For the migration, I luckily found this tool that saved my ass for this task: the docker-volume-snapshot.

The installation was straight-forward, I just needed to run these 2 commands on both source and destination servers:

sudo curl -SL https://raw.githubusercontent.com/junedkhatri31/docker-volume-snapshot/main/docker-volume-snapshot -o /usr/local/bin/docker-volume-snapshot
# Set the permission to run
sudo chmod o+x,g+x /usr/local/bin/docker-volume-snapshot

Then, on the source server:

docker-volume-snapshot create ghost_ghost ghost_ghost.tar.gz
docker-volume-snapshot create ghost_db ghost_db.tar.gz
scp ghost_* $USER_NAME@$DEST_SERVER_IP:/some/path/on/dest/server/

And the last step would only restore the 2 volumes on the destination server with:

cd /some/path/on/dest/server/
docker-volume-snapshot restore ghost_ghost.tar.gz ghost_ghost
docker-volume-snapshot restore ghost_db.tar.gz ghost_db

Job done!

Kudos to @junedkhatri31 for the tool.