【问题标题】:Dockerize nestjs microservices applicationDockerize nestjs 微服务应用程序
【发布时间】:2021-12-05 00:23:36
【问题描述】:

我正在尝试对基于微服务的应用程序进行 dockerize。 api 是用 nestjs 和 MySQL 构建的。以下是目录结构

.
├── docker-compose.yml
├── api
│   ├── src
│   ├── Dockerfile
│   ├── package.json
│   ├── package-lock.json
│   ├── ormconfig.js
│   └── .env
├── payment
│   ├── src
│   ├── Dockerfile
│   ├── package.json
│   └── package-lock.json
├── notifications
│   ├── src
│   ├── Dockerfile
│   ├── package.json
│   └── package-lock.json
└

以下是api目录下的Dockerfile

FROM node:12.22.3

WORKDIR /usr/src/app

COPY package*.json .

RUN npm install
    
CMD ["npm", "run", "start:dev"]

以下是docker-compose.yml 文件。请注意,付款和通知的详细信息尚未添加到 docker-compose 文件中。

version: '3.7'

networks:
  server-network:
    driver: bridge

services:
  api:
    image: api
    build: 
      context: .
      dockerfile: api/Dockerfile
    command: npm run start:dev
    volumes:
      - ".:/usr/src/app"
      - "/usr/src/app/node_modules"
    networks:
      - server-network
    ports:
      - '4000:4000'
    depends_on:
      - mysql
  mysql:
    image: mysql:5.7
    container_name: api_db
    restart: always
    environment:
      MYSQL_DATABASE: api
      MYSQL_ROOT_USER: root
      MYSQL_PASSWORD: 12345
      MYSQL_ROOT_PASSWORD: root
    ports:
      - "3307:3306"
    volumes:
      - api_db_db:/var/lib/mysql
    networks:
      - server-network
volumes:
  api_db:

现在,当我尝试使用 docker-compose up 启动应用程序时,出现以下错误。

没有这样的文件或目录,打开'/usr/src/app/package.json'

更新 尝试删除卷,它也没有帮助。另外,尝试通过运行列出目录的内容来查看api 中的内容

docker-compose run api ls /usr/src/app

它在文件夹中显示以下内容

node_modules  package-lock.json

非常感谢任何帮助。

【问题讨论】:

  • volumes: 块将映像中的源代码替换为与您的主机系统不同的内容(您可以通过docker-compose run api ls /usr/src/app 查看实际存在的内容;因为您正在绑定安装.目录我猜它是包含docker-compose.yml 文件的根目录,而不是任何特定的应用程序)。删除整个 volumes: 块有帮助吗?
  • @DavidMaze 删除卷没有帮助。尝试列出目录docker-compose run api ls /usr/src/app 的内容,它显示文件夹中的node_modules package-lock.json 文件。

标签: docker docker-compose dockerfile nestjs


【解决方案1】:

您的build: { context: } 目录设置错误。

镜像构建机制使用 构建上下文 将文件发送到 Docker 守护进程。 dockerfile: 位置是相对于这个目录的;在 Dockerfile 中,任何COPY(或ADD)指令的左侧总是被解释为相对于这个目录(即使它看起来像一个绝对路径;你不能用..)。

对于您展示的设置,您有多个独立的应用程序,最简单的方法是将context: 设置为包含应用程序的目录。

build:
  context: api
  dockerfile: Dockerfile  # the default value

或者,如果您使用dockerfile 的默认值,则为等效的简写形式

build: api

如果您需要在镜像之间共享文件,则需要将构建上下文设置为父目录(请参阅How to include files outside of Docker's build context?)。在这种情况下,所有COPY 指令都需要使用组合源树中的子目录进行限定。

# Dockerfile, when context: .
COPY api/package*.json ./
RUN npm ci
COPY api/ ./

您通常不需要您显示的volumes:。这些具有以下核心效果:(1)用本地系统上的任何东西替换映像中的应用程序,这可能完全不同,然后(2)用 Docker 匿名替换 its node_modules 目录卷,永远不会更新以反映package.json 文件中的更改。在此特定设置中,您还需要非常小心卷映射与文件系统布局相匹配。我建议在这里删除 volumes: 块;使用本地节点进行日常开发,也许将其配置为指向 Docker 托管的数据库。

如果您还删除了 Dockerfile (command:) 中设置的内容,并且 Compose 可以为 (image:container_name:networks:) 提供合理的默认值,您可以将 docker-compose.yml 文件减少为:

version: '3.8'
services:
  api:          # without volumes:, networks:, image:, command:
    build: api  # shorthand corrected directory-only form
    ports:
      - '4000:4000'
    depends_on:
      - mysql
  mysql:        # without container_name:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: api
      MYSQL_ROOT_USER: root
      MYSQL_PASSWORD: 12345
      MYSQL_ROOT_PASSWORD: root
    ports:
      - "3307:3306"
    volumes:
      - api_db:/var/lib/mysql
volumes:
  api_db:

【讨论】:

    猜你喜欢
    • 2020-11-29
    • 2020-11-16
    • 2019-09-20
    • 2022-12-17
    • 2021-02-24
    • 2021-01-12
    • 1970-01-01
    • 2020-02-04
    • 2019-06-14
    相关资源
    最近更新 更多