【问题标题】:How to run my react app in Docker container如何在 Docker 容器中运行我的反应应用程序
【发布时间】:2021-01-05 03:46:44
【问题描述】:

我有这个想要 dockerize 的 react 应用程序。但问题是,即使我尝试过,它也不起作用。 但它在本地运行得很好

这是当前目录的样子:

docker-compose.yaml
frontend_v2
   - node_modules
   - public
   - src
       - <react jsx files>
   - Dockerfile
   - package.json
   - package-lock.json

原来这就是上面Dockerfile的内容:

# Use an official node runtime as a parent image
FROM node:latest

WORKDIR /app

# Install dependencies
COPY package.json /app

RUN npm install

# Add rest of the client code
COPY . /app

EXPOSE 3000

CMD ["npm", "start"]

我正在使用docker-compose.yml 来启动容器,这就是它的样子: 这是在根目录中。

version: "3.2"

services:

  frontend:
    build: ./frontend_v2
    environment:
      CHOKIDAR_USEPOLLING: "true"
    volumes:
      # - /app/node_modules
      - ./frontend_v2/src:/app/src
    ports:
      - 80:3000

我面临的问题是,即使容器正在运行,我也会收到以下错误(我没有在本地运行)

当我尝试时

docker logs &lt;exited-container-id&gt;我在输出下面得到这个

> cyberhr-rv18.0.4@0.1.0 start /app
> react-scripts start


There might be a problem with the project dependency tree.
It is likely not a bug in Create React App, but something you need to fix locally.

The react-scripts package provided by Create React App requires a dependency:

  "webpack-dev-server": "3.11.0"

Don't try to install it manually: your package manager does it automatically.
However, a different version of webpack-dev-server was detected higher up in the tree:

  /app/node_modules/webpack-dev-server (version: 3.10.3) 

Manually installing incompatible versions is known to cause hard-to-debug issues.

If you would prefer to ignore this check, add SKIP_PREFLIGHT_CHECK=true to an .env file in your project.
That will permanently disable this message but you might encounter other issues.

To fix the dependency tree, try following the steps below in the exact order:

  1. Delete package-lock.json (not package.json!) and/or yarn.lock in your project folder.
  2. Delete node_modules in your project folder.
  3. Remove "webpack-dev-server" from dependencies and/or devDependencies in the package.json file in your project folder.
  4. Run npm install or yarn, depending on the package manager you use.

In most cases, this should be enough to fix the problem.
If this has not helped, there are a few other things you can try:

  5. If you used npm, install yarn (http://yarnpkg.com/) and repeat the above steps with it instead.
     This may help because npm has known issues with package hoisting which may get resolved in future versions.

  6. Check if /app/node_modules/webpack-dev-server is outside your project directory.
     For example, you might have accidentally installed something in your home folder.

  7. Try running npm ls webpack-dev-server in your project folder.
     This will tell you which other package (apart from the expected react-scripts) installed webpack-dev-server.

If nothing else helps, add SKIP_PREFLIGHT_CHECK=true to an .env file in your project.
That would permanently disable this preflight check in case you want to proceed anyway.

P.S. We know this message is long but please read the steps above :-) We hope you find them helpful!

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! cyberhr-rv18.0.4@0.1.0 start: `react-scripts start`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the cyberhr-rv18.0.4@0.1.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2020-09-18T08_32_25_268Z-debug.log

[更新]

这是我的package.json 文件:

{
  "name": "cyberhr-rv18.0.4",
  "version": "0.1.0",
  "private": true,
  "homepage": "",
  "dependencies": {
    "3d-force-graph": "^1.60.11",
    "@blueprintjs/core": "^3.26.1",
    "@coreui/coreui": "^2.1.12",
    "@coreui/coreui-plugin-chartjs-custom-tooltips": "^1.3.1",
    "@coreui/icons": "0.3.0",
    "@coreui/react": "^2.5.1",
    "@emotion/core": "^10.0.35",
    "@material-ui/core": "^4.11.0",
    "@tensorflow/tfjs": "^1.7.2",
    "@tensorflow/tfjs-tsne": "^0.2.0",
    "axios": "^0.19.2",
    "bootstrap": "^4.3.1",
    "chart.js": "^2.8.0",
    "classnames": "^2.2.6",
    "core-js": "^3.1.4",
    "d3-dsv": "^1.2.0",
    "enzyme": "^3.10.0",
    "enzyme-adapter-react-16": "^1.14.0",
    "evergreen-ui": "^4.27.4",
    "flag-icon-css": "^3.3.0",
    "font-awesome": "^4.7.0",
    "google-maps-react": "^2.0.2",
    "jquery": "^3.4.0",
    "material-dashboard-react": "^1.8.0",
    "mdbreact": "4.25.3",
    "node-sass": "^4.12.0",
    "prop-types": "^15.7.2",
    "react": "^16.8.4",
    "react-animations": "^1.0.0",
    "react-app-polyfill": "^1.0.1",
    "react-bootstrap": "^1.0.0-beta.5",
    "react-chartjs-2": "^2.7.6",
    "react-chat-popup": "^1.1.2",
    "react-dom": "^16.8.4",
    "react-dropzone": "^11.0.1",
    "react-force-graph": "^1.32.1",
    "react-full-screen": "^0.2.4",
    "react-loadable": "^5.5.0",
    "react-nvd3": "^0.5.7",
    "react-perfect-scrollbar": "^1.4.4",
    "react-pure-grid": "^2.1.1",
    "react-redux": "^6.0.1",
    "react-reveal": "^1.2.2",
    "react-router-config": "^5.0.1",
    "react-router-dom": "^4.3.1",
    "react-scripts": "^3.4.3",
    "react-spinners": "^0.9.0",
    "react-step-wizard": "^5.3.2",
    "react-table": "^7.2.1",
    "react-test-renderer": "^16.8.6",
    "react-toastify": "^6.0.8",
    "react-window-size": "^1.2.2",
    "reactstrap": "^8.0.0",
    "redux": "^4.0.1",
    "simple-line-icons": "^2.4.1",
    "tabler-react": "^2.0.0-alpha.1",
    "three": "latest",
    "tsne-js": "^1.0.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "devDependencies": {
    "react-to-print": "^2.1.1"
  }
}

有人可以帮帮我吗?

【问题讨论】:

  • 请同时发布您的 package.json。此外,在进行安装之前,您还应该将 package-lock.json 复制到容器中,以具有与本地安装相同的先决条件。
  • 嗨,我添加了package.json
  • webpack-dev-server 未在此处列出,因此除非它是某个其他包的子依赖项,否则不会安装它。在您的 package-lock.json 中搜索 webpack-dev-server 并查看它是否显示(以及它与哪个软件包一起安装),否则您可能在某个时候手动或全局安装了它(npm install -g)。
  • 你试过日志输出中的过程1.2.3.4吗?你可能想要记录下来。我注意到你在 #3 上没问题,开发网络服务器没有出现在你发布的 package.json 中。
  • 如果你使用npm list -g --depth=0,你会得到你已经安装的所有全局 npm 包的树形结构,也许 webpack-dev-server 就在里面。

标签: node.js reactjs docker webpack


【解决方案1】:

首先,确保复制用于在本地安装 deps 的相同 package-lock.json 文件,以确保容器中的依赖关系树与本地相同。

COPY package.json package-lock.json /app/

然后,确保您匹配与本地运行相同的节点/npm 版本(将 12 替换为您正在运行的主要版本,无论是 10、12、14 还是其他):

FROM node:12

每个节点版本都捆绑了特定的 npm 版本(最新的 12 版本附带 npm 6.14.6),您可以在更改日志中找到捆绑的 NPM 版本,https://github.com/nodejs/node/tree/master/doc/changelogs

此外,您可能想在容器中运行npm ci,而不是运行npm install。后者跳过对锁定文件和你的 package.json 文件之间差异的任何检查,只安装锁定的依赖树,这不仅更快,而且还能完全匹配你的本地 dep 树。

编辑:

另外,这一行:

COPY . /app

除非您通过 .dockerignore 或类似的方式忽略它,否则也会覆盖 node_modules。

最简单的方法可能是将.dockerignore 文件添加到与 Dockerfile 相同的文件夹中,并添加以下行:

.git
node_modules

完整的 Dockerfile 如下所示:

# Use whatever version you are running locally (see node -v)
FROM node:12

WORKDIR /app

# Install dependencies (you are already in /app)
COPY package.json package-lock.json ./
RUN npm ci

# Add rest of the client code
# .dockerignore needs to skip node_modules
COPY . /app

EXPOSE 3000

CMD ["npm", "start"]

【讨论】:

  • 哦,是的。他在容器中来自npm installpackage-lock 稍后会被Dockerfile 中的完整应用副本覆盖。
  • 这并不重要,重要的是调用 npm install 时包文件中的内容。
  • @jishi 能否提供Dockerfile 的结构?
  • @ToRrent 添加了一个示例 Dockerfile,但记得创建一个 .dockerignore 文件。
  • 你发现我的docker-compose.yml有什么问题吗?
【解决方案2】:

所以这里

# Install dependencies
COPY package.json /app

RUN npm install

在这些步骤结束时,您将在容器构建环境中拥有一个新的 package-lock.json 文件和 node_modules 文件夹。

但是随后发布的Dockerfile 有:

# Add rest of the client code
COPY . /app

很可能——WHAMMO! ——他们走了。无论 OLD package-lock.json 文件或 node_modules 目录在 .构建机器上的文件夹将覆盖容器中的 ./app 文件夹——包括刚刚在容器中创建的那些新文件。或者也许最终会在 node_modules 目录中混合使用两者。

我采取了不同的方法。我让一切按我的意愿工作,并使用位于源代码目录中的Dockerfile

FROM node:alpine  # as of 2020-09 this runs node 14; also uses sh not bash
COPY . /app
WORKDIR /app
USER node
EXPOSE 8888   # change this to the port(s) where your app listens
CMD [ "node", "./index.js" ]

这是从依赖 Google Cloud Build 构建容器以在 GCP 上启动的生产系统复制的。因此,执行系统上的环境将是 Linux,与我的开发人员系统上的环境相同。 如果您要进行跨平台开发,这显然有时行不通。

【讨论】:

  • 我如何确保node_modules 也能复制?也不应该有任何 .gitingore 或 .dockerginore 文件,对吧?还是?
  • .gitignore 没有问题,但.dockerignore 应该仔细检查。
  • 是的,我认为您对 node_modules 的覆盖是正确的,我认为它会合并文件夹。
  • 不应该把WORKDIR放在COPY之前吗?
  • 在这种情况下,我不确定这是否重要。这个脚本是从我已知的工作系统复制而来的。
猜你喜欢
  • 1970-01-01
  • 2020-07-17
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-11
  • 1970-01-01
相关资源
最近更新 更多