代码之家  ›  专栏  ›  技术社区  ›  Michał Czapliński

在停靠节点中重新加载代码。带docker compose的js应用程序

  •  17
  • Michał Czapliński  · 技术社区  · 9 年前

    我有一个小节点。js docker应用程序。

    我能够成功地运行它,但是,尽管按照 docker-compose docs

    目录布局:

    my-test-app
    | docker-compose.yml
    | Dockerfile
    | index.js
    | package.json
    

    Dockerfile文件:

    FROM mhart/alpine-node:8
    WORKDIR /app
    COPY . .
    EXPOSE 5000
    CMD ["node", "index.js"]
    

    docker撰写。yml:

    version: '3'
    services:
      node-app:
        build: .
        ports:
          - "5000:5000"
        volumes:
          - .:/app
      redis:
        image: "redis:alpine"
    

    const http = require('http');
    const server = http.createServer((req, res) => {
      res.end("hello world");
    });
    server.listen(5000);
    

    包裹json:

    {
      "name": "my-test-app",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
      },
      "author": "",
      "license": "MIT"
    }
    

    • 使用正式节点图像,而不是 alpine-node
    • 将应用程序代码置于 ./app 文件夹内 my-test-app 以及更新 COPY 在…内 Dockerfile 和 volumes docker-compose.yml 照着
    3 回复  |  直到 9 年前
        1
  •  12
  •   Kryten    9 年前

    我看到短语“实时重新加载”用于两种不同类型的重新加载:

    1. 自动重新加载HTML&代码更改时客户端浏览器上的资源。

    认为 你指的是第一种类型,所以下面的答案解决了这个问题。


    这里的问题是 .

    请记住,docker容器与主机是隔离的,具体来说,容器中运行的进程不同于主机上运行的进程(通常不能与之交互)。在您的例子中,您选择在容器中装载一个主机目录,但这只是文件系统,而不是进程。

    node index.js 在 WORKDIR . 当代码更改时,停止它并重新启动它的代码在哪里?大概它是在 主办 . 这意味着它无法接触在中运行的节点进程 (因为它是孤立的)。

    现在,您还没有提到您正在使用什么方法来处理实时重新加载,但这不会有太大的区别。它们基本上都以相同的方式工作:在更改应用程序代码时,杀死现有进程并启动一个新进程。

    要解决这个问题,您有两个选择:

    1. 在容器内运行“实时重新加载”代码,或
    2. 在容器外运行开发代码

    首先,你可以遵循@MarkS的建议并使用 nodemon

    CMD ["node", "index.js"]
    

    在Dockerfile中

    CMD ["nodemon", "index.js"]
    

    诺德蒙

    另一种方法是在开发期间在Docker环境之外的主机上运行代码,然后在部署时将其打包到映像中,这就是我要做的。这解决了两个问题:

    1. 您在孤立节点进程中遇到的问题,以及
    2. 权限问题。

    root . 这意味着,如果你的应用程序创建文件,它们将归 . 我尝试在Docker环境中开发,但遇到了一些问题,例如,我想删除应用程序创建的一个文件,不得不删除 sudo (以身份登录 )只是为了清理东西。

        2
  •  3
  •   Mark S.    9 年前

    我拥有的和您拥有的唯一区别是,我的Dockerfile中没有COPY指令。试着移除它,看看它是否有效。

    我还使用nodemon在代码更改时自动重新启动节点服务器:

        3
  •  0
  •   Eristikos    5 年前

    即使我在使用nodemon,我也遇到了类似的问题。对我来说,有效的解决方案是将docker compose文件中的node应用程序的体积更改为从中读取 /src