15
FROM golang:1.8

ADD . /go/src/beginnerapp

RUN go get -u github.com/gorilla/mux

RUN go get github.com/mattn/go-sqlite3

RUN go install beginnerapp/

VOLUME /go/src/beginnerapp/local-db

WORKDIR /go/src/beginnerapp

ENTRYPOINT /go/bin/beginnerapp

EXPOSE 8080

The sqlite db file is in the local-db directory but I don't seem to be using the VOLUME command correctly. Any ideas how I can have db changes to the sqlite db file persisted?

I don't mind if the volume is mounted before or after the build.

I also tried running the following command

user@cardboardlaptop:~/go/src/beginnerapp$ docker run -p 8080:8080 -v ./local-db:/go/src/beginnerapp/local-db beginnerapp

docker: Error response from daemon: create ./local-db: "./local-db" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path.

EDIT: Works with using /absolutepath/local-db instead of relative path ./local-db

irregular
  • 1,437
  • 3
  • 20
  • 39
  • 2
    Possible duplicate of [How to mount host volumes into docker containers in Dockerfile during build](https://stackoverflow.com/questions/26050899/how-to-mount-host-volumes-into-docker-containers-in-dockerfile-during-build) – tima Sep 11 '17 at 03:42
  • It is not persisting after you run the container and make changes? That is because you didn't mount the volume – Tarun Lalwani Sep 11 '17 at 06:45
  • @tima I don't need it to mount during the build. Before or After is fine – irregular Sep 12 '17 at 01:10

2 Answers2

17

You are not mounting volumes in a Dockerfile. VOLUME tells docker that content on those directories can be mounted via docker run --volumes-from

You're right. Docker doesn't allow relative paths on volumes on command line.

Run your docker using absolute path:

docker run -v /host/db/local-db:/go/src/beginnerapp/local-db

Your db will be persisted in the host file /host/db/local-db

If you want to use relative paths, you can make it work with docker-compose with "volumes" tag:

volumes:
  - ./local-db:/go/src/beginnerapp/local-db

You can try this configuration:

  • Put the Dockerfile in a directory, (e.g. /opt/docker/myproject)
  • create a docker-compose.yml file in the same path like this:
version: "2.0"
services:
  myproject:
    build: .
    volumes:
      - "./local-db:/go/src/beginnerapp/local-db"
  • Execute docker-compose up -d myproject in the same path.

Your db should be stored in /opt/docker/myproject/local-db

Just a comment. The content of local-db (if any) will be replaced by the content of ./local-db path (empty). If the container have any information (initialized database) will be a good idea to copy it with docker cp or include any init logic on an entrypoint or command shell script.

Alfonso Tienda
  • 3,442
  • 1
  • 19
  • 34
  • 1
    Works with the absolute path, couldn't use `./local-db` though – irregular Sep 12 '17 at 03:00
  • With docker-compose ,the host path can be relative to docker-compose.yml file, and it is a good practice e.g volumes: - ./db/local-db:/go/src/beginnerapp/local-db – Alfonso Tienda Sep 13 '17 at 15:34
  • Should I use docker-compose even though I have only 1 container? – irregular Sep 13 '17 at 17:13
  • docker-compose is a good docker solution. You can use it even if you have a single docker container. I improve my response to try to help you – Alfonso Tienda Sep 14 '17 at 09:49
  • Could this be accomplished using bind mounts? I can't get the data to persist following the official bind mount tutorial https://docs.docker.com/get-started/06_bind_mounts/ – Alber8295 Jul 31 '21 at 17:31
0

In Docker windows, you can use relative path from project directory like this (where 'app' is a project directory and 'mnt' is a sub-directory holding some file/s to be mount/ed):

docker run -v %cd%\mnt:/app/mnt
diman82
  • 702
  • 8
  • 11