如何配置我的 Docker React 容器仅在需要时安装模块?
How do I configure my Docker React container to only install modules when it needs them?
我正在尝试在我的 docker-compose.yml 文件中构建多个 Docker 服务,这些服务将启动我的 Django/MySql 后端以及我的 React 客户端应用程序。我的 docker-compose.yml 中有这个部分来处理 React 部分....
client:
build:
context: ./client
volumes:
- ./client:/app
ports:
- '3001:3000'
restart: always
container_name: web-app
environment:
- NODE_ENV=development
- REACT_APP_PROXY=http://localhost:9090
depends_on:
- web
然后我构建了以下 client/Dockerfile 来配置 React 容器 ...
FROM node:10-alpine AS alpine
# A directory within the virtualized Docker environment
# Becomes more relevant when using Docker Compose later
WORKDIR /app/
# Copies package.json and package-lock.json to Docker environment
COPY package*.json ./
# Installs all node packages
RUN npm install
# Finally runs the application
CMD [ "npm", "start" ]
但是当我的容器启动时,它死于以下错误...
web-app | Failed to compile.
web-app |
web-app | ./node_modules/react-tag-input/dist-modules/components/ReactTags.js
web-app | Module not found: Can't resolve 'react-dnd' in '/app/node_modules/react-tag-input/dist-modules/components'
我认为我上面的 "RUN npm install" 可以挽救这一天,但我想不会。有没有办法以某种方式检测未安装哪些模块并在我的容器启动时安装它们?
编辑: package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.4.0",
"@testing-library/user-event": "^7.2.1",
"bootstrap": "^4.4.1",
"jquery": "^1.9.1",
"react": "^16.12.0",
"react-bootstrap": "^1.0.0-beta.17",
"react-device-detect": "^1.12.1",
"react-dom": "^16.12.0",
"react-hamburger-menu": "^1.2.1",
"react-native-flash-message": "^0.1.15",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.1",
"react-tag-input": "^6.4.3",
"typescript": "^3.8.3"
},
"scripts": {
"start": "react-scripts start",
"build": "NODE_ENV=development react-scripts build",
"build:prod": "NODE_ENV=production react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"proxy": "http://localhost:8000",
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
这里发生了两件事:
- 您的
volumes:
指令覆盖 /app
树中的所有内容,包括 node_modules
.
- 您的 Docker 文件实际上并未
COPY
将应用程序代码放入图像中(因此您需要使用 volumes:
将其放在那里的解决方法)。
您可以通过更新 Docker 文件
来解决这个问题
FROM node:10-alpine
WORKDIR /app/
COPY package*.json ./
RUN npm install
# Actually copy the application code in
COPY . ./
CMD ["npm", "start"]
如果您还没有 .dockerignore
文件,请创建包含行 node_modules
的文件,以防止该主机目录被构建到映像中。
最后,从您的 docker-compose.yml
文件中删除 volumes:
。
如果您更改了前端代码,则需要docker-compose up --build
来重建图像。
如果你想要一个实时开发环境,你可以直接在主机上使用 Node,即使你的堆栈的大部分其余部分是 运行 in Docker。对于前端代码尤其如此:由于所提供的代码实际上在最终用户的浏览器中运行,它无法直接与 Docker 网络通信或以其他方式真正利用 Docker完全没有。
# Start everything besides the front-end
docker-compose up -d web
# Start a dev server in the usual way
export NODE_ENV=development
export REACT_APP_PROXY=http://localhost:9090
npm start
我正在尝试在我的 docker-compose.yml 文件中构建多个 Docker 服务,这些服务将启动我的 Django/MySql 后端以及我的 React 客户端应用程序。我的 docker-compose.yml 中有这个部分来处理 React 部分....
client:
build:
context: ./client
volumes:
- ./client:/app
ports:
- '3001:3000'
restart: always
container_name: web-app
environment:
- NODE_ENV=development
- REACT_APP_PROXY=http://localhost:9090
depends_on:
- web
然后我构建了以下 client/Dockerfile 来配置 React 容器 ...
FROM node:10-alpine AS alpine
# A directory within the virtualized Docker environment
# Becomes more relevant when using Docker Compose later
WORKDIR /app/
# Copies package.json and package-lock.json to Docker environment
COPY package*.json ./
# Installs all node packages
RUN npm install
# Finally runs the application
CMD [ "npm", "start" ]
但是当我的容器启动时,它死于以下错误...
web-app | Failed to compile.
web-app |
web-app | ./node_modules/react-tag-input/dist-modules/components/ReactTags.js
web-app | Module not found: Can't resolve 'react-dnd' in '/app/node_modules/react-tag-input/dist-modules/components'
我认为我上面的 "RUN npm install" 可以挽救这一天,但我想不会。有没有办法以某种方式检测未安装哪些模块并在我的容器启动时安装它们?
编辑: package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.4.0",
"@testing-library/user-event": "^7.2.1",
"bootstrap": "^4.4.1",
"jquery": "^1.9.1",
"react": "^16.12.0",
"react-bootstrap": "^1.0.0-beta.17",
"react-device-detect": "^1.12.1",
"react-dom": "^16.12.0",
"react-hamburger-menu": "^1.2.1",
"react-native-flash-message": "^0.1.15",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.1",
"react-tag-input": "^6.4.3",
"typescript": "^3.8.3"
},
"scripts": {
"start": "react-scripts start",
"build": "NODE_ENV=development react-scripts build",
"build:prod": "NODE_ENV=production react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"proxy": "http://localhost:8000",
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
这里发生了两件事:
- 您的
volumes:
指令覆盖/app
树中的所有内容,包括node_modules
. - 您的 Docker 文件实际上并未
COPY
将应用程序代码放入图像中(因此您需要使用volumes:
将其放在那里的解决方法)。
您可以通过更新 Docker 文件
来解决这个问题FROM node:10-alpine
WORKDIR /app/
COPY package*.json ./
RUN npm install
# Actually copy the application code in
COPY . ./
CMD ["npm", "start"]
如果您还没有 .dockerignore
文件,请创建包含行 node_modules
的文件,以防止该主机目录被构建到映像中。
最后,从您的 docker-compose.yml
文件中删除 volumes:
。
如果您更改了前端代码,则需要docker-compose up --build
来重建图像。
如果你想要一个实时开发环境,你可以直接在主机上使用 Node,即使你的堆栈的大部分其余部分是 运行 in Docker。对于前端代码尤其如此:由于所提供的代码实际上在最终用户的浏览器中运行,它无法直接与 Docker 网络通信或以其他方式真正利用 Docker完全没有。
# Start everything besides the front-end
docker-compose up -d web
# Start a dev server in the usual way
export NODE_ENV=development
export REACT_APP_PROXY=http://localhost:9090
npm start