我正在学习将Docker与ROS结合使用,并且对此错误消息感到惊讶:
FROM ros:kinetic-robot-xenial
# create non-root user
ENV USERNAME ros
RUN adduser --ingroup sudo --disabled-password --gecos "" --shell /bin/bash --home /home/$USERNAME $USERNAME
RUN bash -c 'echo $USERNAME:ros | chpasswd'
ENV HOME /home/$USERNAME
USER $USERNAME
RUN apt-get update
给出此错误消息
Step 7/7 : RUN apt-get update
---> Running in 95c40d1faadc
Reading package lists...
E: List directory /var/lib/apt/lists/partial is missing. - Acquire (13: Permission denied)
The command '/bin/sh -c apt-get update' returned a non-zero code: 100
答案 0 :(得分:3)
apt-get
通常需要以root用户身份运行,但是一旦运行了USER
命令,命令就不再以root用户身份运行。
您将经常在Dockerfile的 start 上运行类似的命令:如果可能的话,您想利用Docker层缓存,并且通常会在其余部分安装依赖项。 Dockerfile的需求。同样出于层缓存的原因,一步一步运行apt-get update
和其他安装步骤也很重要。因此,您的Dockerfile通常看起来像
FROM ros:kinetic-robot-xenial
# Still root
RUN apt-get update \
&& apt-get install ...
# Copy in application (still as root, won't be writable by other users)
COPY ...
CMD ["..."]
# Now as the last step create a user and default to running as it
RUN adduser ros
USER ros
如果需要,您可以显式USER root
切换回root以使用后续命令,但通常更容易读取和维护Dockerfile,而用户切换较少。
还要注意,sudo
和用户密码在Docker中都没有真正的用处。通常,很难在脚本中运行sudo
,并且脚本中会发生很多Docker事情。容器几乎也永远不会运行可能会接受用户密码的诸如getty
或sshd
之类的东西,而且它们对于读取docker history
来说是微不足道的,因此设置一个毫无意义。相反,如果您可以在容器中放置壳,则始终可以将-u root
传递给docker run
或docker exec
命令以获取根壳。
答案 1 :(得分:1)
尝试将这一行放在dockerfile的末尾
USER $ USERNAME(一旦此行出现在dockerfile中...您将假设此用户具有权限...在这种情况下,无需安装任何内容) 默认情况下,您是root
答案 2 :(得分:0)
您将用户ros
添加到组sudo
,但是您尝试使用apt-get update
而不使用sudo。因此,您可以无特权地运行命令并获得permission denied
。
使用do运行命令(t):
FROM ros:kinetic-robot-xenial
RUN whoami
RUN apt-get update
# create non-root user
RUN apt-get install sudo
RUN echo "ros ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
ENV USERNAME ros
RUN adduser --ingroup sudo --disabled-password --gecos "" --shell /bin/bash --home /home/$USERNAME $USERNAME
RUN bash -c 'echo $USERNAME:ros | chpasswd'
ENV HOME /home/$USERNAME
USER $USERNAME
RUN whoami
RUN sudo apt-get update
所有这些都没有多大意义。可以用root用户准备docker镜像(例如,安装软件等)。如果您担心安全性(这是一件好事),请保留sudo的内容,并确保与无特权的用户一起执行映像(例如,创建容器)时运行的进程...
如果要将映像的准备工作与实际的可运行项目分开,还可以考虑多阶段构建:
https://docs.docker.com/develop/develop-images/multistage-build/
答案 3 :(得分:0)
通过以下方式切换到root用户:
version: "3.7"
services:
frontend:
build:
context: ./client
dockerfile: Dockerfile
image: client
ports:
- "3000:3000"
volumes:
- ./client:/usr/src/app
backend:
build:
context: ./server
dockerfile: Dockerfile
image: server
ports:
- "8000:8000"
volumes:
- ./server:/usr/src/app
db:
image: postgres
environment:
POSTGRES_DB: ckl
POSTGRES_USER: postgres
POSTGRES_PASSWORD: docker
ports:
- "5432:5432"
然后每个命令都应该起作用