Im adapting a docker-compose.yml file to my usecase. The database im using is only a sqlite file and i would like to save that file to a volume...can i point a volume to a file and not a folder like this ?
version: '3.7'
services:
nginx:
build:
context: .
dockerfile: ./compose/production/nginx/Dockerfile
restart: always
volumes:
- staticfiles:/app/static
- mediafiles:/app/media
ports:
- 80:80
depends_on:
- web
networks:
spa_network:
web:
build:
context: .
dockerfile: ./compose/production/django/Dockerfile
restart: always
command: /start
volumes:
- staticfiles:/app/static
- mediafiles:/app/media
- sqlite_volume:/app/db.sqlite3
env_file:
- ./.env/.prod-sample
networks:
spa_network:
volumes:
sqlite_volume:
staticfiles:
mediafiles:
CodePudding user response:
A named volume is always a directory in docker. The way to mount individual files into a container involves using a host/bind mount. You'll want to mount an entire directory. If your app requires the DB to be in the same folder with other files you don't want to change, a workaround is to use a different directory and a symlink:
RUN mkdir -p /app/db \
&& touch /app/db/db.sqlite3 \
&& ln -s /app/db/db.sqlite3 /app/db.sqlite3
VOLUME /app/db
volumes:
- staticfiles:/app/static
- mediafiles:/app/media
- sqlite_volume:/app/db/
Note that writing to a single file bind mount can have unexpected consequences since many tools that modify files do so by creating a new file and then replacing the existing file. This avoids the risk of a partial change that would happen if the write stopped part way through. However, bind mounts are based on the file inode, and a new file will have a new inode, so you will encounter errors trying to replace a bind mounted file. Either the replace will fail, or in some scenarios, you'll see the new contents in the container but not on the host and those changes will be lost when the container is replaced.
CodePudding user response:
Yes, from memory (!), that should work.
docker-compose
will create any volumes that don't exist.
Existing volumes will be reused (on subsequent) docker-compose
runs.
Docker encourages the use of volumes (as your propose) over bind mounts (as was) though I tend (lazy?) to use bind mounts almost exclusively in my development (non-production) uses of Docker (Compose). One consideration is that, in your example, a bind mount would result in a single file shared between the host and the container|service whereas using a volume results in a file system containing the single file that needs to be managed through Docker's tooling (or similar).