Search code examples
dockerdocker-composedocker-named-volume

How to map a specific file within a named binding?


I'm trying to setup an evcc's docker compose setup.

They do recommend the following configuration:

services:
  evcc:
    command:
      - evcc
    container_name: evcc
    image: evcc/evcc:latest
    ports:
      - 7070:7070/tcp
      - 8887:8887/tcp
      - 7090:7090/udp
      - 9522:9522/udp
    volumes:
      - /etc/evcc.yaml:/etc/evcc.yaml
      - /home/[user]/.evcc:/root/.evcc
    restart: unless-stopped

In my case, I want to bind all the volumes of my docker instances to my NAS(like this if it fails, my data & configuration are safe) through NFS(and also configure it for traefik):

version: "3.9"
services:
  evcc:
    command:
      - evcc
    image: evcc/evcc:latest
    ports:
      - 7070:7070/tcp
      - 8887:8887/tcp
      - 7090:7090/udp
      - 9522:9522/udp
    volumes:
      - evcc-config/evcc.yaml:/etc/evcc.yaml
      - evcc-config/.evcc:/root/.evcc
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.evcc.rule=Host(`evcc.mydomain.com`)"
      - "traefik.http.routers.evcc.entrypoints=websecure"
      - "traefik.http.routers.evcc.tls.certresolver=myresolver"
      - "traefik.http.services.evcc.loadbalancer.server.port=7070" 

volumes:
  evcc-config:
    driver_opts:
      type: "nfs"
      o: "addr=192.168.0.60,nolock,rw,soft"
      device: ":/volume2/apps/config/evcc"

But it doesn't seems to like the volume with a file, I get the following error:

service evcc: undefined volume "evcc-config/evcc.yaml"

My guess is that I cannot bind a path with a named binding? But then, how to do similar with it?

I cannot bind the whole ETC to my NAS, same for the whole root?


Solution

  • The short syntax for specifying a volume mount is either:

    - <volume_name>:<mountpoint>
    

    Or:

    - <source path>:<mountpoint>
    

    The only way Docker can differentiate between a volume name and a path is whether or not the string includes a directory separator (/). Since you're trying to do this:

    evcc-config/evcc.yaml:/etc/evcc.yaml
    

    Docker assumes you're referring to a local filesystem path.

    You're looking for a subpath mount, which is supported in recent versions of Docker and Docker Compose. You need to use the long format for volume mounts, which permits you to set a subpath option.

    The syntax would look like this:

    services:
      evcc:
        command:
          - evcc
        image: evcc/evcc:latest
        volumes:
        - type: volume
          source: evcc-config
          target: /etc/evcc.yaml
          volume:
            nocopy: true
            subpath: evcc.yaml