Docker,docker撰写和在项目之间复制文件 docker-compose.yaml Dockerfile entrypoint.sh

如何解决Docker,docker撰写和在项目之间复制文件 docker-compose.yaml Dockerfile entrypoint.sh

我有以下设置。

文件夹结构

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/**
...

但是没有什么可以消除这种滞后。

我无法使其正常工作。 另外-我无法摆弄现有项目的内部结构。

这是怎么了?

解决方法

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


解决方案1 ​​

缺点

首先,我想指出这种解决方案的缺点。

  • 您需要清理卷。卷在首次创建时仅填充有容器的内容。有关说明,请参见here。 因此,如果项目目录中的某些文件已更改,docker-compose down -v 必须完成
  • 一种docker-compose down -v`` is to manually delete the named volumes using docker volume rm``的替代方法。
  • 如果您不希望这样做,则可以暂时将文件COPY /tmp到文件夹(不是已装载的卷)中。然后,您可以使用入口点脚本将文件复制到其预期位置(例如/home/developer/)。有关详情,请参见。

我的设置:文件夹结构

我的文件夹结构类似于您的文件夹结构:

├── 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

来源

docker-compose.yaml

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:

Dockerfile

它们几乎相同。 * 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" ]

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来更新内容,否则它仍将重用旧卷中的预填充内容


解决方案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

# Then do your stuff

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-