如何在 Docker 容器内观察 NestJs 应用程序中开发的文件更改

Posted

技术标签:

【中文标题】如何在 Docker 容器内观察 NestJs 应用程序中开发的文件更改【英文标题】:How to watch file changes developing in NestJs app inside Docker container 【发布时间】:2019-12-09 09:11:33 【问题描述】:

我在使用 NestJSDocker 时遇到问题。我想通过 npm start: dev 运行开发脚本,但问题是应用程序运行正常,但它没有检测到源文件中的任何更改,所以我不能用它来开发我的应用程序。

这是我的 docker-compose.yml 的一部分:

messages:
   image: c2c/messages:v1
   command: npm run start:dev
   build:
     context: ./services/c2c-server-messages
     dockerfile: Dockerfile
   container_name: c2c_server_messages
   depends_on:
     - postgres
     - nginx
   networks:
     c2c_net:
       ipv4_address: 172.28.1.5

还有我的 Nest 应用的 Dockerfile

FROM node:10-alpine
WORKDIR /api/messages
ADD . .
RUN npm install
EXPOSE 3000
CMD ["npm", "run", "start"]

我在 package.json 中的 npm start:dev 脚本:

"start:dev": "tsc-watch -p tsconfig.build.json --onSuccess \"node dist/main.js\"",

控制台输出向我显示了这一点,但应用没有检测到文件更改:

c2c_server_messages | 7:26:29 PM - Found 0 errors. Watching for file changes.
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [NestFactory] Starting Nest application...
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [InstanceLoader] TypeOrmModule dependencies initialized +63ms
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [InstanceLoader] AppModule dependencies initialized +2ms
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [InstanceLoader] TypeOrmCoreModule dependencies initialized +151ms
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [InstanceLoader] TypeOrmModule dependencies initialized +1ms
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [InstanceLoader] MessageModule dependencies initialized +2ms
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [RoutesResolver] AppController /: +8ms
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [RouterExplorer] Mapped /, GET route +6ms
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [RoutesResolver] MessageController /messages: +1ms
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [RouterExplorer] Mapped /, POST route +2ms
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [RouterExplorer] Mapped /all, GET route +2ms
c2c_server_messages | [Nest] 36   - 07/31/2019, 7:26 PM   [NestApplication] Nest application successfully started +5ms

【问题讨论】:

与本地节点安装相比,您希望在这里使用 Docker 获得什么好处? 你好@DavidMaze 好处是可以利用 docker-compose 发起的其他服务。 【参考方案1】:

我现在可以工作了:)

关键是在 docker-compose 中用你的微服务文件夹的本地机器根文件夹创建一个 volume,在本例中是 ./services/c2c-server-messages 作为容器中应用的根 :/api/messages

这样,您使用的是本地文件来运行应用程序,而不是复制到容器中的文件,因此您可以在保存文件时观察更改。

例子:

  messages:
   image: c2c/messages:v1
   volumes:
    - ./services/c2c-server-messages:/api/messages
   command: npm run start:dev
   build:
     context: ./services/c2c-server-messages
     dockerfile: Dockerfile
   container_name: c2c_server_messages
   depends_on:
     - postgres
     - nginx
   networks:
     c2c_net:
       ipv4_address: 172.28.1.5

【讨论】:

【参考方案2】:

当您运行 docker-compose ... 时,它会寻找匹配的图像 (c2c/messages:v1),如果它...

在本地找到图像,然后运行它 没找到,你的docker-compose.yaml会导致docker-compose构建镜像。

一旦运行,更改运行进程的一种方法是更改​​容器映像的文件,然后触发进程重新加载它们。但是,拥有“不可变”(不要更改)容器被认为是一种很好的做法。

您可以解决此问题的一种方法是:

将您的源代码添加到源代码管理中 使用源的一些唯一标识符来检测更改。

(通常是您的来源的哈希,例如使用 git git --rev-parse HEAD

如果您的来源发生变化,哈希值也会发生变化,您可以使用它来触发映像的重建 docker-compose 下次启动。一个简单的方法是:

TAG=$(git rev-parse HEAD) 然后使用哈希作为图像的标签(而不是v1),例如c2c/messages:$TAG

您的工作流程将变为:

更改您的来源 计算哈希 docker-compose up... 引用带有哈希标记的图像以强制重建

使用源代码管理可为您提供源代码历史记录。

使用源哈希的图像标签允许您将图像与提交匹配

【讨论】:

我想在开发中每次修改源代码时都重建镜像,不能每次都commit。这可能吗? 您可能应该编写流程脚本...docker-compose down,重建您的图像并适当地标记它,编辑您的 docker-compose.yaml,docker-compose up。也可以将源卷安装到映像中,然后您只需要重新启动容器|进程即可检测到它们,但是使用 docker 的优点不太清楚。

以上是关于如何在 Docker 容器内观察 NestJs 应用程序中开发的文件更改的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 docker 容器中的时区?

NestJs / Mongoose 在 Docker 撰写时无法建立 MongoDB 数据库连接

如何检查一个进程是不是在 docker 容器内运行?

如何将一个python应用以docker镜像的方式来运行?

Docker Compose 无法连接到数据库

使用 Docker 部署 Node 应用