Dave
Dave

Reputation: 19290

In Docker, how do I copy files from a local directory so that I can then copy those files into my Docker container?

I'm using Docker

Docker version 19.03.8, build afacb8b

I have the following docker-compose.yml file ...

version: "3.2"
services:

  sql-server-db:
    build: ./
    container_name: sql-server-db
    image: microsoft/mssql-server-linux:2017-latest
    ports:
      - "1433:1433"
    environment:
      SA_PASSWORD: "Password1!"
      ACCEPT_EULA: "Y"

and here is the Docker file it uses to build ...

FROM microsoft/mssql-server-linux:latest
  
# Create work directory
RUN mkdir -p /usr/work

WORKDIR /usr/work

# Copy all scripts into working directory
COPY . /usr/work/

# Grant permissions for the import-data script to be executable
RUN chmod +x /usr/work/import-data.sh

EXPOSE 1433

CMD /bin/bash ./entrypoint.sh

On my local machine, I have some files in a "../../scripts/myproject/*.sql" directory (the ".." are relative to the directory where my docker-compose.yml file is stored). Is there a way I can run "docker-compose up" and have those files copied into a directory from which I can then copy them into the container's "/usr/work" directory?

Upvotes: 0

Views: 1712

Answers (1)

tenstan
tenstan

Reputation: 1319

There are 2 ways to solve this, with one being easier than the other, but both have use cases.

The easy way

You could mount the directory directly to the container through the docker-compose like this:

version: "3.2"
services:

  sql-server-db:
    build: ./
    container_name: sql-server-db
    image: microsoft/mssql-server-linux:2017-latest
    ports:
      - "1433:1433"
    environment:
      SA_PASSWORD: "Password1!"
      ACCEPT_EULA: "Y"
    volumes:
      - ../../scripts/myproject:/path/to/dir

Note the added volumes compared to the yaml in your question. This will mount the myproject directory to /path/to/dir within the container. What this will also mean is that if the sql-server-db container writes to any of the files in /path/to/dir, then the file in myproject on the host machine will also change, since the files are mounted.

The less easy way

You could copy the files directly during the build of the image. This is a little bit harder, since the build stage of docker doesn't allow the copying of parent directories unless you add some extra arguments. What needs to happen is that you set the context of the build stage to a different directory than the current directory. The context determines which files are sent to the build stage. This is the same directory as the directory the Dockerfile resides in by default.

To take this approach, you need the following in your docker-compose.yml:

version: "3.2"
services:

  sql-server-db:
    build:
      context: ../..
      dockerfile: path/to/Dockerfile # Here you should specify the path to your Dockerfile, this is a relative path from your context
    container_name: sql-server-db
    image: microsoft/mssql-server-linux:2017-latest
    ports:
      - "1433:1433"
    environment:
      SA_PASSWORD: "Password1!"
      ACCEPT_EULA: "Y"

So above the context is now ../.. so that you are able to copy files two directories above. You can then copy the myproject directory in your Dockerfile like this:

FROM microsoft/mssql-server-linux:latest

COPY ./scripts/myproject /myfiles

The advantage of this approach is that the files are copied instead of being mounted, so the docker container can write whatever it wants to these files, without affecting the host machine.

Upvotes: 1

Related Questions