我可以使用Docker容器来存储静态文件,以便其他Docker容器可以访问吗? 可以。

3
我正在构建两个微服务并对它们进行docker化。我有一个包含脚本(PackageA)的文件夹,我需要在两个服务(ServiceA & B)中使用该脚本。我的文件夹结构如下:
Root
|
|--Docker
   |--ProjectA
      |-docker-compose.yml (builds ServiceA & ServiceB)
|--Services
   |--PackageA
      |-src
      |-index.js
      |-package.json

   |--ServiceA
      |-src
      |-index.js
      |-Dockerfile
      |-package.json

   |--ServiceB
      |-src
      |-index.js
      |-Dockerfile
      |-package.json

我的docker-compose.yml文件:

version: '3'

networks:
  mynetwork:

services:
  servicea:
    build: ./../../Services/ServiceA
    container_name: servicea
    ports:
      - ...
    networks:
      - mynetwork
  serviceb:
    build: ./../../Services/ServiceB
    ports: serviceb
      - ...
    networks:
      - mynetwork

在这两个服务中,Dockerfile 的格式如下:

FROM node:16
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm ci --only=production
COPY . ./
EXPOSE ...
CMD [ "node", "index.js" ]

所以我的问题是:我可否将 PackageA Docker化并创建一个包含其内容的volume,然后在ServiceA & B中使用该volume?如何在容器之间共享volumes?
1个回答

4

我认为采用这种架构风格并不是一件好事情。如果以这种方式耦合,它们就不是微服务了。您最好发布共享库,甚至可以复制和粘贴一些代码来复制。

然而,从技术上讲,这是可能的。您可以按照以下方式操作:

对于共享服务,Dockerfile 在目录 /shared 中创建一些虚拟内容。

FROM busybox

WORKDIR /shared
RUN echo "shared content" > /shared/data.txt

然后启动2个服务。两个服务都会挂载同一个共享卷。由于app-a有depends_oncondition,所以共享服务会先挂载该卷。

name: example

services:
  shared:
    build: ./
    volumes: [ shared:/shared ]
  app-a:
    image: busybox
    command: cat /shared/data.txt
    volumes: [ shared:/shared ]
    depends_on:
      shared:
        condition: service_completed_successfully

volumes:
  shared:

$ docker compose up
[+] Running 4/4
 ⠿ Network example_default     Created                                                                                                                                                                     0.6s
 ⠿ Volume "example_shared"     Created                                                                                                                                                                     0.0s
 ⠿ Container example-shared-1  Created                                                                                                                                                                     0.1s
 ⠿ Container example-app-a-1   Created                                                                                                                                                                     0.1s
Attaching to example-app-a-1, example-shared-1
example-shared-1 exited with code 0
example-app-a-1   | shared content
example-app-a-1 exited with code 0

当挂载一个空命名的卷时,容器文件系统的内容首先被复制到该卷中,然后再挂载。

这样一来,app-a就可以“看到”共享的内容了。

有时候您可能也希望让共享服务在启动时手动填充卷。因为我在这里所做的非常特定于Docker。例如,在Kubernetes中不会起作用。在那里,您必须在共享服务启动时将共享内容复制到卷中。

shared:
  image: busybox
  command: sh -c 'echo "shared content" > /shared/data.txt'
  volumes: [ shared:/shared ]

谢谢你详细的回答。它帮助我更好地理解了Docker和Docker Compose。将软件包发布听起来是个好主意。如果我通过npm发布它,那么以后我可以像普通的npm软件包一样使用它,通过npm i PackageA进行安装,对吗? - ask4you
@ask4you,是的,你可以将它发布到像NPM这样的包存储库中。可能是私有的,只有你可以使用它。然而,有些人不建议在创建微服务时选择这种方式,因为这也会产生耦合。因此,你甚至可以复制代码。例如,请参见https://phauer.com/2016/dont-share-libraries-among-microservices/。你可以在网上找到更多相关资料。 - The Fool
是的,最后的结果是相同的。但我不想让它们在两个服务中重复出现。谢谢你的回答。 - ask4you
@ask4you,如果它们共享这样的业务逻辑,那么它们可能不是独立的服务。 - The Fool
我的意思是,这个包只是我用来管理Apache Kafka与nodejs连接的实现。这就是为什么我需要将它用作共享库,以便它们可以相互通信。 - ask4you
1
@ask4you,所以它更像是一个通用库。在这种情况下,将其发布到某个工件库可能是有意义的。就像 SQL 客户端或类似的软件包一样。 - The Fool

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接