[英]Docker: Using COPY when the Dockerfile is located in a subdirectory
我正在使用多個 dockerfile (每個服務一個)構建一個應用程序。 我的應用程序的目錄結構如下:
app
├── dockerfiles
│ ├── webserver
│ │ └── Dockerfile
│ └── database
│ └── Dockerfile
├── public
└── <frontend>
├── db
└── <data>
[...]
├── LICENSE
├── README.md
└── docker-compose.yml
在我的網絡服務器的Dockerfile
中,我想使用COPY
命令復制現有代碼:
# Dockerfile
COPY ./public /var/www/html
我想使用我docker-compose.yml
文件部署應用程序:
# docker-compose.yml
version: "3"
services:
webserver:
build: ./dockerfiles/webserver
image: webserver:php-apache
但是,當我從工作目錄 ( app
) 運行docker-compose
時,我收到以下錯誤:
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
如果我將網絡服務器的Dockerfile
移動到應用程序的根目錄,此錯誤就會消失,因此我知道它是由路徑或構建上下文問題引起的。
知道了這一點,我們可以通過以下兩種方式之一解決問題:
(1) 為整個應用程序(在應用程序的根目錄中)使用一個Dockerfile
,或者
app
└── Dockerfile
(2) 為每個服務(在應用程序的根目錄中)使用多個Dockerfiles
。
app
├── Dockerfile.webserver
└── Dockerfile.database
這些解決方案很糟糕,因為對所有內容都使用一個 dockerfile/container 並不是最佳實踐(1),並且以這種方式組織多個 dockerfile 看起來很混亂 (2)。
所以,我的問題是:
我們如何在不改變我們原來的目錄結構的情況下解決這個問題?
docker-compose.yml
或基本運行時命令進行哪些更改?WORKDIR
命令呢?理想情況下,最好的解決方案應該適用於開發(本地)和生產(遠程)環境,所以現在讓我們避免卷......
您需要在這里做的就是添加context: .
和dockerfile
在您的 docker-compose.yml 文件中的構建部分,以便您的服務了解完整的目錄結構。
# docker-compose.yml
version: "3"
services:
webserver:
build:
context: .
dockerfile: ./dockerfiles/webserver/Dockerfile
image: webserver:php-apache
正如在其他地方已經闡明的那樣, context
和dockerfile
的組合可以解決問題。 我只想補充一點,您甚至不需要在應用程序的根目錄中找到docker-compose.yml
文件本身即可工作。
例如,在我的一個項目中,我有多個 compose 配置來支持多個環境( development 、 staging 、 production等),我決定將所有內容放在它們自己的子目錄中,以保持整潔。 我的目錄樹如下:
.
+-- README.md
+-- scripts
| +-- docker
| +-- compose.yml
| +-- compose-stage.yml
| +-- compose-prod.yml
| +-- dockerfile
| +-- ...
| +-- ...
其中compose.yml
如下所示:
# compose.yml
version: "3.9"
services:
web:
build:
context: ../../
dockerfile: ./scripts/docker/dockerfile
....
請注意context
,它指向應用程序的根目錄 - 從compose.yml
文件所在的目錄向上兩層 - 以及dockerfile
,它與context
。
有了上面的目錄樹和compose.yml
文件,我們要做的就是從應用程序的根目錄(即README.md
所在的目錄)運行以下命令:
> docker compose -f scripts/docker/compose.yml up
一切都像魅力一樣!
我知道這聽起來有點令人費解,而且可能確實如此,但是當涉及將應用程序部署到三個(或更多!)不同的環境時,所花費的時間將得到回報。
COPY
指令的作用域是 Dockerfile 所在的文件夾。 我的建議是將您的 Dockerfile 更改為 public 文件夾並將指令更改為COPY . /var/www/html
COPY . /var/www/html
。
不完全是 OP 的場景,但如果您不使用docker-compose
,您還可以分別指定 context 和 Dockerfile :
docker build . -f app/dockerfiles/webserver/Dockerfile
這與當前目錄一起構建.
作為上下文,但使用子目錄中的Dockerfile
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.