Home > Mobile >  docker-compose : how to create a volume to save only one file?
docker-compose : how to create a volume to save only one file?

Time:05-29

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).

  • Related