我有以下设置。
文件夹结构
solution-root
├── docker-compose.yml
├── project1
│ ├── Dockerfile
│ ├── sub1
│ │ ├── ...loads of stuff...
│ ├── sub2
│ │ ├── ...more stuff...
├── project2
│ ├── Dockerfile
│ ├── sub1
│ │ ├── ...more stuff...
│ ├── sub2
│ │ ├── ...even more stuff...
├── project-db
│ ├── Dockerfile
docker-compose.yml
version: '3'
services:
project1:
build:
context: ./project1
dockerfile: Dockerfile
...
project2:
build:
context: ./project2
dockerfile: Dockerfile
...
project-db:
build:
context: ./project-db
dockerfile: Dockerfile
...
...
project-db / Dockerfile
FROM mysql:5.7
COPY ../project1/app/seeders /seeders/
COPY ../project2/app/seeders /seeders/
很显然,我想从另一个同级文件夹中复制文件,因为此project-db
需要它们。
因此,当我运行docker-compose build时,出现此错误:
Service 'project-db' failed to build: COPY failed: Forbidden path outside the build context: ../project1/app/seeders
好的,我明白了,上下文不允许我升级。 然后将上下文移至根,然后从那里运行project / Dockerfile。
docker-compose.yml
project-db:
build:
context: .
dockerfile: ./project-db/Dockerfile
...
现在我们可以复制所需的文件。
project-db / Dockerfile
COPY project1/app/seeders /seeders/
COPY project2/app/seeders /seeders/
现在docker-compose build
一切都很好。
但是存在一个问题-构建project-db会持续相当长的时间。这意味着每次运行时。我猜这是由于现在project-db
的上下文是整个文件夹结构。
因此,我尝试使用.dockerignore
过滤掉不需要的文件夹:
.dockerignore
project3
project3/**
project4
project4/**
project5
project5/**
...
但是没有什么可以消除这种滞后。
我无法使其正常工作。 另外-我无法摆弄现有项目的内部结构。
这是怎么了?
答案 0 :(得分:1)
正如作者正确指出的那样,卷用于持久化数据。在这里,我想展示两个解决方案,关于如何使用它们在容器之间共享数据。 该解决方案远非完美!
首先,我想指出这种解决方案的缺点。
docker-compose down -v
必须完成。docker-compose down -v`` is to manually delete the named volumes using
docker volume rm``的替代方法。COPY
/tmp
到文件夹(不是已装载的卷)中。然后,您可以使用入口点脚本将文件复制到其预期位置(例如/home/developer/
)。有关详情,请参见<解决方案2 。我的文件夹结构类似于您的文件夹结构:
├── docker-compose.yaml
├── project1
│ ├── Dockerfile
│ ├── entrypoint.sh
│ ├── sub1
│ │ ├── testfile_project_1_1.txt
│ │ └── testfile_project_1_2.txt
│ └── sub2
│ └── testfile_project_1_3.txt
├── project2
│ ├── Dockerfile
│ ├── entrypoint.sh
│ ├── sub1
│ │ └── testfile_project_2_1.txt
│ └── sub2
│ ├── testfile_project_2_2.txt
│ ├── testfile_project_2_3.txt
│ ├── testfile_project_2_4.txt
│ └── testfile_project_2_5.txt
└── project-db
├── Dockerfile
└── entrypoint.sh
version: "3.8"
services:
first-service:
build:
context: ./project1
dockerfile: Dockerfile
volumes:
- data-first-service:/home/developer/
second-service:
build:
context: ./project2
dockerfile: Dockerfile
volumes:
- data-second-service:/home/developer/
databse-service:
build:
context: ./project-db
dockerfile: Dockerfile
volumes:
- data-first-service:/home/developer/project1/
- data-second-service:/home/developer/project2/
depends_on:
- first-service
- second-service
volumes:
data-first-service:
data-second-service:
它们几乎相同。 * db-service *的 dockerfile 仅复制其入口点脚本。 sudoers
的部分在这里,因为这是我的默认测试图像。我只是包含了它,以明确用户拥有哪些权限,并使普通用户可以使用无密码sudo
。这不是强制性的。
FROM ubuntu:latest
# We need some tools
RUN apt-get update && apt-get install -y sudo
# We want to have another user than `root`
## USER SETUP
RUN adduser developer
# We want to have passwordless sudo access
RUN \
sed -i /etc/sudoers -re 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
sed -i /etc/sudoers -re 's/^root.*/root ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
sed -i /etc/sudoers -re 's/^#includedir.*/## **Removed the include directive** ##"/g' && \
echo "developer ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers; su - developer -c id
# Run now with user developer
USER developer
COPY sub1 /home/developer/sub1
COPY sub2 /home/developer/sub2
RUN ls -l
ADD ./entrypoint.sh /entrypoint.sh
RUN sudo chmod +x /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]
这两个项目的入口点并不特殊,它们仅包含一个简单的ls -l
至/home/developer
。
* db-service *的入口点仅显示tree
输出(请参见结果):
#!/bin/bash
cd ~
echo "db service - You are here: ${PWD} "
tree --du -shaC | grep -Ev '( *[^ ]* ){5}\['
如您所见,project-db
容器现在包含来自其他两个项目的文件。
databse-service_1 | .
databse-service_1 | |-- [ 220] .bash_logout
databse-service_1 | |-- [3.7K] .bashrc
databse-service_1 | |-- [ 807] .profile
databse-service_1 | |-- [ 17K] project1
databse-service_1 | | |-- [ 220] .bash_logout
databse-service_1 | | |-- [3.7K] .bashrc
databse-service_1 | | |-- [ 807] .profile
databse-service_1 | | |-- [4.0K] sub1
databse-service_1 | | | |-- [ 0] testfile_project_1_1.txt
databse-service_1 | | | `-- [ 0] testfile_project_1_2.txt
databse-service_1 | | `-- [4.0K] sub2
databse-service_1 | | `-- [ 0] testfile_project_1_3.txt
databse-service_1 | `-- [ 17K] project2
databse-service_1 | |-- [ 220] .bash_logout
databse-service_1 | |-- [3.7K] .bashrc
databse-service_1 | |-- [ 807] .profile
databse-service_1 | |-- [4.0K] sub1
databse-service_1 | | `-- [ 0] testfile_project_2_1.txt
databse-service_1 | `-- [4.0K] sub2
databse-service_1 | |-- [ 0] testfile_project_2_2.txt
databse-service_1 | |-- [ 0] testfile_project_2_3.txt
databse-service_1 | |-- [ 0] testfile_project_2_4.txt
databse-service_1 | `-- [ 0] testfile_project_2_5.txt
databse-service_1 |
databse-service_1 | 42K used in 6 directories, 17 files
如前所述,这种方法有一些缺点。您需要对docker-compose down
进行分类,以使该解决方案起作用。
因此,工作流程类似于以下内容:
docker-compose build && docker-compose up
。
如果您在项目目录之一中更改文件,或者要通过必须调用docker-compose down -v
来更新内容,否则它仍将重用旧卷中的预填充内容
基本上,它与解决方案1 相同。区别在于,“项目容器”首先将源复制到临时位置,然后将容器启动(并安装了卷)后,将源复制到安装卷的路径。
仅对此解决方案进行了次要更改
[...]
# Run now with user developer
USER developer
COPY sub1 /tmp/sub1
COPY sub2 /tmp/sub2
RUN ls -l
ADD ./entrypoint.sh /entrypoint.sh
RUN sudo chmod +x /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]
入口点看起来很有趣
#!/bin/bash
mv /tmp/sub1 /home/developer/sub1
mv /tmp/sub2 /home/developer/sub1
# Then do your stuff