Docker,Docker在项目之间编写和复制文件

Docker,Docker在项目之间编写和复制文件,docker,docker-compose,dockerfile,Docker,Docker Compose,Dockerfile,我有以下设置 文件夹结构 solution-root ├── docker-compose.yml ├── project1 │   ├── Dockerfile │   ├── sub1 │   │   ├── ...loads of stuff... │   ├── sub2 │   │   ├── ...more stuff... ├── project2 │   ├── Dockerfile │   ├──

我有以下设置

文件夹结构

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
FROM mysql:5.7

COPY ../project1/app/seeders /seeders/
COPY ../project2/app/seeders /seeders/
COPY project1/app/seeders /seeders/
COPY project2/app/seeders /seeders/
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:
    build:
      context: .
      dockerfile: ./project-db/Dockerfile
    ...
项目数据库/Dockerfile

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
FROM mysql:5.7

COPY ../project1/app/seeders /seeders/
COPY ../project2/app/seeders /seeders/
COPY project1/app/seeders /seeders/
COPY project2/app/seeders /seeders/
显然,我想从另一个同级文件夹复制文件,因为这
projectdb
需要它们

因此,当我运行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

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:
    build:
      context: .
      dockerfile: ./project-db/Dockerfile
    ...
现在我们可以复制我们需要的文件

项目数据库/Dockerfile

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
FROM mysql:5.7

COPY ../project1/app/seeders /seeders/
COPY ../project2/app/seeders /seeders/
COPY project1/app/seeders /seeders/
COPY project2/app/seeders /seeders/
现在,
docker compose build
一切正常(ish)。 但有一个问题,建设项目数据库持续相当长的一段时间。这意味着每次它运行时。我想这是因为现在
projectdb
的上下文是整个文件夹结构

因此,我尝试使用
.dockrignore
筛选出不需要的文件夹:

dockerignore先生

project3
project3/**
project4
project4/**
project5
project5/**
...
但没有什么能消除这种滞后

我不能让它正常工作。 此外,我不能摆弄现有项目的内部结构

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

这里出了什么问题?

正如作者正确指出的,卷用于持久化数据。这里我想展示两个解决方案,关于如何使用它们在容器之间共享数据此解决方案远非完美


解决方案1 缺点 首先,我想指出这个解决方案的缺点

  • 您需要清理卷。卷仅在第一次创建时使用容器的内容填充。请参阅以获取解释。 因此,如果项目目录中的某些文件已更改,则必须执行
    docker compose down-v
  • docker compose down-v``的另一种方法是使用
    docker volume rm``手动删除命名卷
  • 如果您不想这样做,您可以暂时
    将文件复制到一个文件夹中(该文件夹不是已装入的卷,例如
    /tmp
    )。使用入口点脚本,您可以将文件复制到其预期位置(例如
    /home/developer/
    )。请参见解决方案2
我的设置:文件夹结构 我的文件夹结构与您的类似:

├── docker-compose.yaml
├── 项目1
│   ├── Dockerfile
│   ├── entrypoint.sh
│   ├── sub1
│   │   ├── testfile_project_1_1.txt
│   │   └── testfile_project_1_2.txt
│   └── sub2
│       └── testfile_project_1_3.txt
├── 项目2
│   ├── 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
└── 项目数据库
├── Dockerfile
└── entrypoint.sh
来源 docker-compose.yaml
版本:“3.8”
服务:
第一次服务:
建造:
上下文:./project1
dockerfile:dockerfile
卷数:
-数据优先服务:/home/developer/
第二项服务:
建造:
上下文:./project2
dockerfile:dockerfile
卷数:
-数据第二服务:/home/developer/
数据库服务:
建造:
上下文:./projectdb
dockerfile:dockerfile
卷数:
-数据优先服务:/home/developer/project1/
-数据第二服务:/home/developer/project2/
取决于:
-第一次服务
-二次服务
卷数:
数据优先服务:
数据第二服务:
Dockerfile(s) 他们几乎一样。*db服务*的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" ]
entrypoint.sh 这两个项目的入口点并不特殊,它们只包含一个简单的
ls-l
/home/developer
。 *db服务*的入口点只显示一个
输出(参见结果):

#/bin/bash
光盘~
echo“数据库服务-您在这里:${PWD}”
树--du-shaC | grep-Ev'(*[^]*){5}\['
结果 如您所见,
projectdb
容器现在包含来自其他两个项目的文件

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进行分类。 因此,工作流程与此类似:
docker compose build和&docker compose up
。 如果更改某个项目目录中的文件或要更新内容,ud必须调用
docker compose down-v
,否则它仍将重用旧卷中预先填充的内容


解决方案2 基本上,它与解决方案1相同。区别在于,“项目容器”首先将源复制到一个临时位置,然后在容器启动(并装入卷)后复制到装入卷的路径

Dockerfile 只是对这个解决方案做了一些小改动

[...]
# 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
#那就做你的事

哪个步骤需要很长时间:“发送上下文”步骤,或者你的Dockerfile中的某些内容?你不使用卷来共享有什么特别的原因吗?@DavidMaze:我认为自己是Docker初学者,所以我不能100%回答这个问题;从我所读到的内容来看,这种延迟通常是由发送上下文引起的,但我怎么知道呢?@agentsm