Docker turn anonymous volume into named volume

Solution 1:

You cannot currently rename existing volumes. (This is true whether they were previously named or were unnamed and had their names auto-generated.)

You can see this issue for more information on implementation of this feature, as well as add your "+1"/"Thumbs up" to let the developers know that you want it.

Without that, as far as I know, the only good way to do it is to create the new named volume and copy the data.

Solution 2:

To summarize the workaround:

docker volume create --name <new_volume>
docker run --rm -it -v <old_volume>:/from:ro -v <new_volume>:/to alpine \
    ash -c "cd /from ; cp -av . /to"
docker volume rm <old_volume>

This method has the benefit of using the docker API. It uses a lightweight Linux image called alpine and its default shell, ash to run a file copy, cp -av from the old volume to the newly named volume.

Solution 3:

At the time of this writing the only option is to copy the data. The details may vary depending on your particular setup. The general list of steps to be performed is as follows:

  1. Stop and remove the source container to let the new volume be created at step 3.

    docker stop NAME
    docker rm NAME
    # or
    docker-compose stop SERVICE
    docker-compose rm SERVICE
    

    In some cases you might be able to postpone removing the source container, e.g. when switching from docker-compose anonymous volume to docker-compose named volume. In this case up would create the new volume. And you can proceed with copying the data. But even in this case stopping the container is advised to avoid data being changed as you copy them. And you've got to remove the source container for docker-compose to switch to the new volume (pay attention to the warnings).

    In some cases it's not really needed, e.g. when switching from standalone containers to docker-compose.

  2. Change docker-compose.yml if applicable.

  3. Start the new container for the new volume to be created.

    Standalone containers:

    docker run ...
    # or
    docker-compose up -d
    
  4. Stop the new container to avoid data being changed.

    docker stop ...
    # or
    docker-compose stop
    

    In case of migrating to e.g. a standalone container with a named volume you can just create the volume in place of starting/stopping the container.

  5. Copy the data.

    docker run --rm -v "SRC_VOLUME:/from" -v "DST_VOLUME:/to" \
        bash -c '
            shopt -s dotglob
            # rm -r /to/*  # e.g. pg might have populated the new volume
            cp -r /from/* /to
        '
    

    Where SRC_VOLUME, DST_VOLUME - volume name, id, or absolute path to a directory on the host.

    To list volumes attached to a container use:

    docker inspect CONTAINER --format '{{json .Mounts}}' | jq
    

    Where CONTAINER - container name or id.

  6. Start the new container.

    docker run ...
    # or
    docker-compose up -d
    
  7. Rejoice :)

In case you want to experiment with different setups, check out the following gist.