instruction: Create a comprehensive Dockerfile for storage applications with best practices
output: ```dockerfile
  from copying a container's pre-existing files into an empty
  volume, use the volume-nocopy option, see Options for --mount.Named and anonymous volumesA volume may be named or anonymous. Anonymous volumes are given a random name
  that's guaranteed to be unique within a given Docker host. Just like named
  volumes, anonymous volumes persist even if you remove the container that uses
  them, except if you use the --rm flag when creating the container, in which
  case the anonymous volume associated with the container is destroyed. See
  Remove anonymous volumes.If you create multiple containers consecutively that each use anonymous
  volumes, each container creates its own volume. Anonymous volumes aren't reused
  or shared between containers automatically. To share an anonymous volume
  between two or more containers, you must mount the anonymous volume using the
  random volume ID.SyntaxTo mount a volume with the docker run command, you can use either the
  --mount or --volume flag.
  
  $ docker run --mount type=volume,src=<volume-name>,dst=<mount-path>
  $ docker run --volume <volume-name>:<mount-path>
  In general, --mount is preferred. The main difference is that the --mount
  flag is more explicit and supports all the available options.You must use --mount if you want to:Specify volume driver optionsMount a volume subdirectoryMount a volume into a Swarm serviceOptions for --mountThe --mount flag consists of multiple key-value pairs, separated by commas
  and each consisting of a <key>=<value> tuple. The order of the keys isn't
  significant.
  
  $ docker run --mount type=volume[,src=<volume-name>],dst=<mount-path>[,<key>=<value>...]
  Valid options for --mount type=volume include:OptionDescriptionsource, srcThe source of the mount. For named volumes, this is the name of the volume. For anonymous volumes, this field is omitted.destination, dst, targetThe path where the file or directory is mounted in the container.volume-subpathA path to a subdirectory within the volume to mount into the container. The subdirectory must exist in the volume before the volume is mounted to a container. See Mount a volume subdirectory.readonly, roIf present, causes the volume to be mounted into the container as read-only.volume-nocopyIf present, data at the destination isn't copied into the volume if the volume is empty. By default, content at the target destination gets copied into a mounted volume if empty.volume-optCan be specified more than once, takes a key-value pair consisting of the option name and its value.Example
  
  $ docker run --mount type=volume,src=myvolume,dst=/data,ro,volume-subpath=/foo
  Options for --volumeThe --volume or -v flag consists of three fields, separated by colon
  characters (:). The fields must be in the correct order.
  
  $ docker run -v [<volume-name>:]<mount-path>[:opts]
  In the case of named volumes, the first field is the name of the volume, and is
  unique on a given host machine. For anonymous volumes, the first field is
  omitted. The second field is the path where the file or directory is mounted in
  the container.The third field is optional, and is a comma-separated list of options. Valid
  options for --volume with a data volume include:OptionDescriptionreadonly, roIf present, causes the volume to be mounted into the container as read-only.volume-nocopyIf present, data at the destination isn't copied into the volume if the volume is empty. By default, content at the target destination gets copied into a mounted volume if empty.Example
  
  $ docker run -v myvolume:/data:ro
  Create and manage volumesUnlike a bind mount, you can create and manage volumes outside the scope of any
  container.Create a volume:
  
  $ docker volume create my-vol
  List volumes:
  
  $ docker volume ls
  
  local my-vol
  Inspect a volume:
  
  $ docker volume inspect my-vol
  [
   {
   "Driver": "local",
   "Labels": {},
   "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
   "Name": "my-vol",
   "Options": {},
   "Scope": "local"
   }
  ]
  Remove a volume:
  
  $ docker volume rm my-vol
  Start a container with a volumeIf you start a container with a volume that doesn't yet exist, Docker creates
  the volume for you. The following example mounts the volume myvol2 into
  /app/ in the container.The following -v and --mount examples produce the same result. You can't
  run them both unless you remove the devtest container and the myvol2 volume
  after running the first one.
  --mount
  
  -v
  
  $ docker run -d \
   --name devtest \
   --mount source=myvol2,target=/app \
   nginx:latest
  
  $ docker run -d \
   --name devtest \
   -v myvol2:/app \
   nginx:latest
  Use docker inspect devtest to verify that Docker created the volume and it mounted
  correctly. Look for the Mounts section:
  
  "Mounts": [
   {
   "Type": "volume",
   "Name": "myvol2",
   "Source": "/var/lib/docker/volumes/myvol2/_data",
   "Destination": "/app",
   "Driver": "local",
   "Mode": "",
   "RW": true,
   "Propagation": ""
   }
  ],This shows that the mount is a volume, it shows the correct source and
  destination, and that the mount is read-write.Stop the container and remove the volume. Note volume removal is a separate
  step.
  
  $ docker container stop devtest
  
  $ docker container rm devtest
  
  $ docker volume rm myvol2
  Use a volume with Docker ComposeThe following example shows a single Docker Compose service with a volume:
  
  services:
   frontend:
   image: node:lts
   volumes:
   - myapp:/home/node/app
  volumes:
   myapp:Running docker compose up for the first time creates a volume. Docker reuses the same volume when you run the command subsequently.You can create a volume directly outside of Compose using docker volume create and
  then reference it inside compose.yaml as follows:
  
  services:
   frontend:
   image: node:lts
   volumes:
   - myapp:/home/node/app
  volumes:
   myapp:
   external: trueFor more information about using volumes with Compose, refer to the
  Volumes
  section in the Compose specification.Start a service with volumesWhen you start a service and define a volume, each service container uses its own
  local volume. None of the containers can volume driver. However, some volume drivers do support shared storage.The following example starts an nginx service with four replicas, each of which
  uses a local volume called myvol2.
  
  $ docker service create -d \
   --replicas=4 \
   --name devtest-service \
   --mount source=myvol2,target=/app \
   nginx:latest
  Use docker service ps devtest-service to verify that the service is running:
  
  $ docker service ps devtest-service
  
  ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
  4d7oz1j85wwn devtest-service.1 nginx:latest moby Running Running 14 seconds ago
  You can remove the service to stop the running tasks:
  
  $ docker service rm devtest-service
  Removing the service doesn't remove any volumes created by the service.
  Volume removal is a separate step.Populate a volume using a containerIf you start a container which creates a new volume, and the container
  has files or directories in the directory to be mounted such as /app/,
  Docker copies the directory's contents into the volume. The container then
  mounts and uses the volume, and other containers which use the volume also
  have access to the pre-populated content.To show this, the following example starts an nginx container and
  populates the new volume nginx-vol with the contents of the container's
  /usr/share/nginx/html directory. This is where Nginx stores its default HTML
  content.The --mount and -v examples have the same end result.
  --mount
  
  -v
  
  $ docker run -d \
   --name=nginxtest \
   --mount source=nginx-vol,destination=/usr/share/nginx/html \
   nginx:latest
  
  $ docker run -d \
   --name=nginxtest \
   -v nginx-vol:/usr/share/nginx/html \
   nginx:latest
  After running either of these examples, run the following commands to clean up
  the containers and volumes. Note volume removal is a separate step.
  
  $ docker container stop nginxtest
  
  $ docker container rm nginxtest
  
  $ docker volume rm nginx-vol
  Use a read-only volumeFor some development applications, the container needs to write into the bind
  mount so that changes are propagated back to the Docker host. At other times,
  the container only needs read access to the data. Multiple
  containers can mount the same volume. You can simultaneously mount a
  single volume as read-write for some containers and as read-only for others.The following example changes the previous one. It mounts the directory as a read-only
  volume, by adding ro to the (empty by default) list of options, after the
  mount point within the container. Where multiple options are present, you can separate
  them using commas.The --mount and -v examples have the same result.
  --mount
  
  -v
  
  $ docker run -d \
   --name=nginxtest \
   --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly \
   nginx:latest
  
  $ docker run -d \
   --name=nginxtest \
   -v nginx-vol:/usr/share/nginx/html:ro \
   nginx:latest
  Use docker inspect nginxtest to verify that Docker created the read-only mount
  correctly. Look for the Mounts section:
  
  "Mounts": [
   {
   "Type": "volume",
   "Name": "nginx-vol",
   "Source": "/var/lib/docker/volumes/nginx-vol/_data",
   "Destination": "/usr/share/nginx/html",
   "Driver": "local",
   "Mode": "",
   "RW": false,
   "Propagation": ""
   }
  ],Stop and remove the container, and remove the volume. Volume removal is a
  separate step.
  
  $ docker container stop nginxtest
  
  $ docker container rm nginxtest
  
  $ docker volume rm nginx-vol
  Mount a volume subdirectoryWhen you mount a volume to a container, you can specify a subdirectory of the
  volume to use, with the volume-subpath parameter for the --mount flag. The
  subdirectory that you specify must exist in the volume before you attempt to
  mount it into a container; if it doesn't exist, the mount fails.Specifying volume-subpath is useful if you only want to share a specific
  portion of a volume with a container. Say for example that you have multiple
  containers running and you want to store logs
  ```