我正在学习 Docker 课程,并有一个简单的 Docker 脚本来设置图像:
FROM node:14.16.0-alpine3.13
RUN addgroup app && adduser -S -G app app
USER app
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package*.json ./
RUN npm install
COPY . .
ENV APP_URL=http://api.myapp.com
EXPOSE 3000
CMD ["npm", "start"]
Run Code Online (Sandbox Code Playgroud)
现在,在脚本中它切换到,USER app但是当我使用 Docker exec 登录时,docker exec -it 187 sh我可以询问它whoami并获得响应:app这是正确的。当我尝试使用 echo 命令写入文件时出现问题:
echo data > data.txt
Run Code Online (Sandbox Code Playgroud)
sh:无法创建 data.txt:权限被拒绝
然后我运行ls -la查看文件和权限:
/app $ ls -la
total 1456
drwxr-xr-x 1 root root 4096 Oct 20 16:38 .
drwxr-xr-x 1 root root 4096 Oct 20 19:54 ..
-rw-rw-r-- 1 root root 13 Oct 20 13:46 .dockerignore
drwxr-xr-x 7 root root 4096 Mar 9 2021 .git
-rw-r--r-- 1 root root 310 Mar 5 2021 .gitignore
-rw-rw-r-- 1 root root 311 Oct 20 16:38 Dockerfile
-rw-r--r-- 1 root root 3362 Mar 5 2021 README.md
drwxr-xr-x 1 root root 4096 Oct 20 16:38 node_modules
-rw-rw-r-- 1 root root 1434378 Oct 20 16:10 package-lock.json
-rw-r--r-- 1 root root 814 Oct 20 16:10 package.json
drwxr-xr-x 2 root root 4096 Mar 9 2021 public
drwxr-xr-x 2 root root 4096 Oct 20 13:22 src
Run Code Online (Sandbox Code Playgroud)
这表明 root 是为这些文件/目录设置的用户和组。这显然是有意为之,因为我们不想以 root 身份登录。那么我应该怎么做才能将这个文件添加到容器中呢?这里的最佳实践是什么?也许我在某个地方错过了一步?
编辑: 应该/app由 拥有吗USER app?如果是这样,添加新用户有什么意义?我应该将其添加到 docker 脚本中:
RUN chown app /app
Run Code Online (Sandbox Code Playgroud)
谢谢!
应该
/app由 拥有吗USER app?
当然不。您希望防止应用程序有意或无意地覆盖其自己的代码和静态资产。
那么我应该怎么做才能将这个文件添加到容器中呢?
创建一个专用目录来保存应用程序的数据。这应该与源代码目录不同;普通应用程序目录的子目录就可以了。在 Dockerfile 中,使该目录(仅)由非 root 用户拥有。
FROM node:14.16.0-alpine3.13
RUN addgroup app && adduser -S -G app app
# don't switch to this user quite yet
WORKDIR /app
# usual setup and build stuff
COPY package*.json ./
RUN npm ci
COPY . ./
RUN npm build
# create the data directory and set its owner
RUN mkdir data && chown app data
# _now_ switch to the non-root user when running the container
EXPOSE 3000
USER app
CMD ["npm", "start"]
Run Code Online (Sandbox Code Playgroud)
在实践中,您可能希望在单个容器的生命周期之外保留应用程序的数据。一种方法是使用名为volume的Docker 。如果执行此操作,卷将从映像初始化,包括其所有权,因此您不需要在此处进行任何特殊设置。
docker volume create app-data
docker run -v app-data:/app/data ...
Run Code Online (Sandbox Code Playgroud)
由于多种原因,您可能更喜欢使用绑定挂载(如果您需要从 Docker 外部直接访问文件;备份和恢复文件可能更容易;...)。您还可以使用该docker run -v选项将主机目录绑定挂载到容器中,但它会带来其主机系统数字 uid 所有者。但是,请注意,映像中唯一拥有所有者的app是data目录,并且代码是世界可读的,因此如果我们将容器设置为使用与主机用户相同的 uid 运行,这仍然有效。
docker run -v "$PWD/data:/app/data" -u $(id -u) ...
Run Code Online (Sandbox Code Playgroud)
您的应用程序代码通常不需要 Docker 卷(它包含在映像中),也不需要在映像中构建特定的主机 uid。
| 归档时间: |
|
| 查看次数: |
2367 次 |
| 最近记录: |