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?
docker-compose.yml
, or to the basic runtime commands?WORKDIR
command?Ideally, the best solution should work for both dev (local) and production (remote) environments, so let's avoid volumes for now...
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.
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).
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.
It turns out that you cannot include files outside Docker's build context. However, you can copy files from the Dockerfile's parent directory.
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.
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.
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With