Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker: Using COPY when the Dockerfile is located in a subdirectory

Tags:

I'm building an app using multiple dockerfiles (one for each service). My app's directory structure is as follows:

app
├── dockerfiles
│   ├── webserver
│   │   └── Dockerfile
│   └── database
│       └── Dockerfile
├── public
    └── <frontend>
├── db
    └── <data>
  [...]
├── LICENSE
├── README.md
└── docker-compose.yml

In my webserver's Dockerfile, I want to copy in my existing code using the COPY command:

# Dockerfile
COPY ./public /var/www/html

And I want to deploy the app using my docker-compose.yml file:

# docker-compose.yml
version: "3"
services:
   webserver:
      build: ./dockerfiles/webserver
      image: webserver:php-apache

However, when I run docker-compose from the working directory (app), I get the following error:

Building webserver
Step 1/2 : FROM php:7.1.11-apache-jessie
 ---> cb6a5015ad72
Step 2/2 : COPY ./public /var/www/html
Service 'webserver' failed to build: COPY failed: stat /var/lib/docker/tmp/docker-builder193736188/public: no such file or directory

This error disappears if I move my webserver's Dockerfile to the app's root, so I know that it's being caused by a paths or build context issue.

And knowing this, we can fix the problem one of two ways, by either:

(1) Using one Dockerfile for the entire app (in the app's root), or

app
└── Dockerfile

(2) Using multiple Dockerfiles for each service (in the app's root).

app
├── Dockerfile.webserver
└── Dockerfile.database

These solutions are bad because using one dockerfile/container for everything is not best practice (1), and having multiple dockerfiles organized in this way just looks messy (2).


So, My Question is:

How do we fix this problem without changing our original directory structure?

  • What changes need to be made to the dockerfiles, to docker-compose.yml, or to the basic runtime commands?
  • Is there a better way to organize everything?
  • What about the WORKDIR command?

Ideally, the best solution should work for both dev (local) and production (remote) environments, so let's avoid volumes for now...

like image 649
CodyAE Avatar asked Dec 13 '17 04:12

CodyAE


People also ask

Does Docker COPY COPY recursively?

The cp command behaves like the Unix cp -a command in that directories are copied recursively with permissions preserved if possible. Ownership is set to the user and primary group at the destination. For example, files copied to a container are created with UID:GID of the root user.

Does COPY in Dockerfile create directory?

Docker Dockerfiles COPY InstructionThe COPY instruction copies new files or directories from <src> and adds them to the filesystem of the container at the path <dest> . Multiple <src> resource may be specified but they must be relative to the source directory that is being built (the context of the build).

How does Copy command work in Dockerfile?

COPY and ADD are both Dockerfile instructions that serve a similar purpose. They let you copy files from a specific location into a Docker image. COPY takes in a source and destination. It only lets you copy in a local or directory from your host (the machine-building the Docker image) into the Docker image itself.

Can Dockerfile COPY from parent directory?

It turns out that you cannot include files outside Docker's build context. However, you can copy files from the Dockerfile's parent directory.

What is the difference between dockerfile copy and copy?

The Copy Command COPY is a Docker container destination that copies files from a local source location. A Dockerfile is a text file that contains instructions on how to set up a Docker container. In Dockerfile, what is the difference between ADD and COPY? COPY destroys a src file.

How to copy a directory in dockerfile without a star (*)?

If you want to copy a source directory entirely with the same directory structure, Then don't use a star (*). Write COPY command in Dockerfile as below. OP specifically asked about a directory within the current directory and not the contents of the current directory. COPY files/ /files/ without a wildcard is the answer.

Where is the dockerfile located?

By default, the Dockerfile is assumed to be located here, but you can specify a different location with the file flag (-f). Regardless of where the Dockerfile actually lives, all recursive contents of files and directories in the current directory are sent to the Docker daemon as the build context.

How to make a copy of a docker image?

Docker – COPY Instruction. 1 Step 1: Create a Directory to Copy. In this example, we will create a directory and a file which we will copy using the COPY command. Create a folder ... 2 Step 2: Edit the Dockerfile. 3 Step 3: Build the Docker Image. 4 Step 4: Verifying the Docker Image. 5 Step 5: Running the Docker Container. More items


1 Answers

All you need to do here is add context: . and dockerfile in your build section inside your docker-compose.yml file so that your service understands the complete directory structure.

# docker-compose.yml
version: "3"
services:
  webserver:
    build:
      context: .
      dockerfile: ./dockerfiles/webserver/Dockerfile
    image: webserver:php-apache
like image 77
vivekyad4v Avatar answered Oct 12 '22 18:10

vivekyad4v