这是一个讨论得很好的话题,但我从未找到解决方案。
您可能知道,当我的容器中有一个卷并且我在Dockerfile中使用yarn install
安装依赖项时,yarn将在{{1 }}访问。
这种方法(在开发环境中)存在两个问题:
node_modules
文件夹仅在我的容器中,但是主机的代码编辑器(我的是VSC)可能需要此文件夹才能正常工作。例如,如果您没有此文件,VSC会错误告知您他找不到您的进口商品...
如果主机要使用root: root
安装软件包,则他将不得不重新启动以重建要安装的软件包的容器。
所以我想到了另一个想法,如果我将依赖项与Dockerfile的node_modules
(或yarn add ...
文件中的CMD
服务属性)一起安装。因此,Docker将与主机共享command
文件夹,因为他将在构建后创建它。但这是主要问题,docker-compose
具有node_modules
权限访问权限,因此,如果您主机的用户名为node_modules
,并且没有相同的root:root
和{{1 }},您将需要使用某种mint
来安装/删除依赖项。
这是我当前的配置:
uid
:
gid
sudo
:
docker-compose.yml
version: '3.7'
services:
app:
container_name: 'app_DEV'
build: .
command: sh -c "yarn install && node ./server.js"
volumes:
- ./:/usr/src/app
ports:
- 3000:3000
tty: true
:
Dockerfile
FROM node:12.8.1-alpine
WORKDIR /usr/src/app
COPY . .
:
package.json
然后您可以尝试{
"dependencies": {
"express": "^4.17.1"
}
}
然后做server.js
,您应该会看到类似的内容:
const app = require('express')();
app.get('/', (req, res) => {
res.send('Hello');
});
app.listen(3000, () => console.log('App is listening on port 3000'));
您可以看到,除docker-compose up
以外的每个文件/文件夹都具有ls -la
访问权限(-rw-r--r-- 1 mint mint 215 août 23 16:39 docker-compose.yml
-rw-r--r-- 1 mint mint 56 août 23 16:29 Dockerfile
drwxr-xr-x 52 root root 4096 août 23 16:31 node_modules
-rw-r--r-- 1 mint mint 53 août 23 16:31 package.json
-rw-r--r-- 1 mint mint 160 août 23 16:29 server.js
是我的主机用户)。这就是第二种解决方案的问题。
最后,我的问题是:有没有更好的方法来完成这件事?
答案 0 :(得分:2)
在您的情况下,为了使其按您希望的方式工作,应在docker文件中添加USER
,并在docker-compose.yml中添加user:
。例如
Dockerfile:
FROM node:12.8.1-alpine
WORKDIR /usr/src/app
USER node
COPY . .
docker-compose.yml:
version: '3.7'
services:
app:
container_name: 'app_DEV'
build: .
command: sh -c "yarn install && node ./server.js"
user: "1000:1000"
volumes:
- ./:/usr/src/app
ports:
- 3000:3000
tty: true
无论如何,我们面临着类似的情况,因此我们选择了不同的方法。我们决定避免在主机和容器之间共享node_modules文件夹(如果与使用不同操作系统的同事共享行为很讨厌),而是决定避免将node_modules文件夹安装在docker-compose.yml中。
在我们的例子中,Dockerfile如下所示:
FROM node:8.12.0-stretch
RUN mkdir /api
WORKDIR /api
COPY ./package.json ./package-lock.json ./
RUN npm ci --prod
COPY . .
CMD [ "nodemon", "server.js" ]
docker-compose.yml看起来像这样:
version: '3.7'
services:
app:
build: .
volumes:
- "./:/api"
- "/api/node_modules/"
这样,我们能够在主机中创建node_modules(可用于测试,开发等),并安全地保留docker容器的内容。这种方法的缺点是我们的开发人员必须在主机上也运行npm ci
,并且每次更改package.json时,他们都需要重新创建映像。
答案 1 :(得分:2)
通常来说,我不推荐这种方法,因为您的主机和容器可能无法共享相同的模块。例如,如果您团队中的其他人使用Windows,并且您拥有一些已编译的模块(例如,node-sass或bcrypt),则共享这些模块会使容器或主机无法使用它们。
另一个经常出现的解决方案是在Dockerfile中分离node_modules安装步骤,并为此覆盖卷安装。每次您要添加软件包时,仍将需要重建Docker映像,但这(可能)不应该经常发生。
这是Dockerfile的相关部分:
FROM node:12.8.1-alpine WORKDIR /usr/src/app COPY ./package*.json . COPY ./yarn.lock . RUN yarn COPY . . CMD [ "yarn", "start" ]
然后,在您的docker-compose文件中:
version: '3.7' services: app: container_name: 'app_DEV' build: . command: sh -c "yarn install && node ./server.js" volumes: - ./:/usr/src/app - /usr/src/app/node_modules/ ports: - 3000:3000 tty: true
确保包含/usr/src/app/node_modules/
卷{strong>之后的根挂载,因为它将在容器中覆盖它。另外,尾部的斜线很重要。