Delete a container and everything saved inside it vanishes with it. That is not a bug - it is the design. Volumes are how real data escapes that design: storage that lives outside the container, managed by Docker, and survives every rebuild.
Almost every beginner loses data to Docker exactly once, and it is always the same moment: they remove a container to 'start fresh' and discover the database went with it. This page exists so it never happens to you. The rule is simple: containers are cattle, volumes are the barn. Anything that must survive - database files, uploads, configuration - lives in a volume or a bind mount, never in the container's own layer.
A container writes into a thin writable layer stacked on its image. That layer exists only while the container exists. Remove the container and the layer is removed with it - completely, with no recycle bin.
This is deliberate. Containers are designed to be replaced: upgrade the image, delete the old container, start a new one. The design only hurts when data with a long life is stored in a place with a short one.
A volume is storage Docker manages for you, kept outside any single container.
docker volume create appdata makes one (starting a container with a new -v name creates it automatically too)-v appdata:/var/lib/mysql mounts it at the folder the application writes to - the path on the right must match where that app stores datadocker volume ls lists your volumes; docker volume inspect appdata shows the detailsdocker volume rm does - which is why that command deserves a pause before EnterA bind mount connects a real folder on your machine straight into the container. On the WSL 2 setup, folders inside the Linux filesystem work best:
-v /home/anshu/myapp:/app inside Ubuntu - fast, and you can edit the files with normal tools/mnt/c works, but file operations are noticeably slower, and Windows-style permissions can surprise Linux applicationsRule of thumb: volumes for application data, bind mounts for code you are actively editing.
A volume survives the container. It does not survive the machine dying, the disk failing, or you deleting the volume in a cleanup. A volume is availability, not a backup.
The simple backup pattern: stop the application container and archive the volume, for example with a throwaway container - docker run --rm -v appdata:/data -v /home/anshu/backups:/backup busybox tar czf /backup/appdata.tar.gz -C /data . - then copy that archive somewhere off the machine. If the data matters, test restoring it once; an untested backup is a hope, not a backup.
Watch the video for the install, then apply this page before your second container - data discipline is cheapest at the start.
▶️ Watch Full VideoIf the data was written inside the container's own layer and no volume was attached, honestly no - removing the container removed that layer permanently. This is the lesson volumes exist to prevent. If a volume was attached, your data is still there: start a new container with the same -v mount and the application will open it.
Start with named volumes for databases and application data - Docker manages them and they behave the same everywhere. Use bind mounts for project code you edit from Windows or Ubuntu directly. Many real setups use both at once, for different folders.
Compose declares volumes in the same file as the services, and Docker names them after the project. The rules do not change: data in a volume survives container removal and compose down, while docker compose down -v deliberately deletes the volumes too - read that flag before using it.