I want to know why we have two different options to do the same thing, What are the differences between the two.
Bind mounts are like a superset of Volumes (named or unnamed). Bind mounts are created by binding an existing folder in the host system (host system is native linux machine or vm (in windows or mac)) to a path in the container.
Volume command results in a new folder, created in the host system under /var/lib/docker
Volumes are recommended because they are managed by docker engine (prune, rm, etc).
A good use case for bind mount is linking development folders to a path in the container. Any change in host folder will be reflected in the container. Another use case for bind mount is keeping the application log which is not crucial like a database.
Command syntax is almost the same for both cases:
bind mount: note that the host path should start with '/'. Use $(pwd) for convenience.
docker container run -v /host-path:/container-path image-name
unnamed volume: creates a folder in the host with an arbitrary name
docker container run -v /container-path image-name
named volume: should not start with '/' as this is reserved for bind mount. 'volume-name' is not a full path here. the command will cause a folder to be created with path "/var/lib/docker/volume-name" in the host.
docker container run -v volume-name/container-path image-name
A named volume can also be created beforehand a container is run (docker volume create). But this is almost never needed.