Reputation: 129
I have a compose file:
version: "3"
services:
db:
image: postgres:12.5
ports:
- "15432:5432"
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test
volumes:
- ./postgres-data:/var/lib/postgresql/data
backend:
image: backend
depends_on:
- db
restart: always
ports:
- "6969:8000"
volumes:
- ./app:/app
When I run docker-compose up to start the 2 containers, I notice that:
Both service uses bind mount, and as I understand: bind mount always transfer the content from the host directory to the container. But this does not happen in the case of the db service
So where did I understand wrong here ?
Thanks in advance
Upvotes: 1
Views: 803
Reputation: 158647
Nothing ever gets "transferred". The contents of the host directory always hide what was in the underlying image, and once the container has started, the host and container directories are "the same"; writes in one side should be visible in the other.
The Docker Hub database images in particular know to look at their data directories at startup time. The sequence is roughly like this:
$PWD/postgres-data
directory replacing /var/lib/postgresql/data
in the container.postgres
image's entrypoint script looks at the data directory and sees it is totally empty. It then creates a new database and runs any first-time-initialization scripts. Since that directory is a bind-mounted host directory, this content is also visible on the host.This work is done on the mounted directory at container startup time, so it happens to be visible on the host as well. (If you docker run --rm -it --entrypoint /bin/sh postgres
and look around, bypassing its entrypoint script, you'll probably find the /var/lib/postgresql/data
directory is totally empty; there is nothing there to be "transferred to the host".)
This also means that your bind mount over the application container's /app
directory hides whatever the Dockerfile does; if you run a build sequence it will get lost, and if the directory layouts in the host and container aren't identical, you will have non-reproducible problems. This further means you can't directly use volumes to copy file out of an image; you have to run a container that runs a cp
command.
Upvotes: 5
Reputation: 36016
I must admit that I thought this behaviour only worked with volume mounts and not bind mounts. The documentation for the volume long syntax indicates the copy mode is only available to volume mounts.
Upvotes: 1