Docker: 以非root用户身份执行命令

6

之前我是用以下命令运行:

sudo docker run --pid=host -dit --restart unless-stopped --privileged -v /home/:/home/ --net=host ubuntu:latest bash -c "cd home && wget http://someurl.com/a.js -O /home/a.js && node a.js && tail -F anything"

这个命令默认启动一个root用户的容器。所以wget http://someurl.com/a.js -O /home/a.js 命令可以正常工作。

现在我想从容器中获取声音。为了确保容器和主机同时播放音频,我使用了pulseaudio socket,否则会出现设备繁忙错误,因为alsa占用了声卡。

这是我用来满足我的需求的新命令:

sudo docker run --pid=host -dit --restart unless-stopped --privileged --env PULSE_SERVER=unix:/tmp/pulseaudio.socket --env PULSE_COOKIE=/home/$USER/pulseaudio.cookie --volume /tmp/pulseaudio.socket:/tmp/pulseaudio.socket --volume /home/$USER/pulseaudio.client.conf:/etc/pulse/client.conf --user $(id -u):$(id -g) -v /home/:/home/ --net=host ubuntu:latest bash -c "cd home && wget http://someurl.com/a.js -O /home/a.js && node a.js && tail -F anything"

问题在于当Docker内的用户为root用户时,pulseaudio无法正常工作,因此我必须在运行命令中使用--user $(id -u):$(id -g)。现在由于用户不是root用户,wget http://someurl.com/a.js -O /home/a.js 命令会出现权限被拒绝的错误。

我希望每次启动容器时都能执行此wget命令。我想以非root用户身份运行容器,并能够执行wget命令。

是否有任何解决方法?


使用sudo运行该命令? - Mike Doe
当用户是 root 时,无需使用 sudo。如果用户不是 root,则在这种情况下 sudo 不起作用。 - node_man
我当然是在谈论非根命令。你是什么意思,它不起作用?在Dockerfile中安装和配置它。 - Mike Doe
当我以非root用户身份运行时,我会收到“bash:sudo:command not found”错误。顺便说一下,我没有dockerfile。我直接使用问题中提到的命令。 - node_man
你能告诉我如何为我的特定场景创建Dockerfile吗?我觉得很困惑。 - node_man
显示剩余2条评论
4个回答

11

1- 使用非root用户执行docker命令

如果您不想使用root用户运行docker命令,请按照此链接的说明进行操作。 创建一个docker组并将当前用户添加到其中。

$ sudo groupadd docker
$ sudo usermod -aG docker $USER

2- 在docker中执行命令!使用非root用户

如果我没记错,您想在docker中使用非root用户而不是root用户!

分配给您在docker中的用户的uid与您正在使用的根docker镜像有关,例如alphineubuntu:xenial如本文所述(链接)

但是您可以通过在Dockerfile中进行以下小改动来更改docker中的用户并使用它。像这样添加一个新用户并使用它:

 RUN adduser -D myuser
 USER myuser
 ENTRYPOINT [“sleep”]
 CMD [“1000”]

然后在 Docker 文件中,如果你获取了 /bin/bash 并在其中执行 id 命令,你会发现 Docker 内部用户的 ID 已经改变。

更新:

如果你有一个可用的 Dockerfile,那么创建一个新的 Dockerfile,例如名为 myDocker,并将下面的代码放入其中:

 from myDockerfile
 RUN adduser -D myuser
 USER myuser
 ENTRYPOINT [“sleep”]
 CMD [“1000”]

然后保存该文件,并构建它:
$ docker build -t myNewDocker .
$ docker run myNewDocker <with your options>

你说得对。但我没有Dockerfile,而且我从来没有使用过它。你能告诉我怎么为我的情境编写Dockerfile吗?我想先以root用户身份运行并执行wget命令,然后作为非root用户运行容器。 - node_man
嘿,我找到了一个非常简单的解决方案。我很快就会发布它。 - node_man
对我来说,adduser -D 显示 Option d is ambiguous (debug, disabled-login, disabled-password)。我按照这个问答中的建议以非交互方式运行 adduser:https://askubuntu.com/q/94060/14987。 - Sadeq Dousti

2

我使用了一个简单的chmod 777命令来解决这个问题。

首先,我执行了docker run命令,没有-c标志或wget命令等

sudo docker run --pid=host -dit --restart unless-stopped --privileged -v /home/:/home/ --net=host ubuntu:latest bash

一旦容器运行起来,我使用以下命令以root用户身份进入此容器:

sudo docker exec -it --user="root" bash

现在,一旦进入容器,我执行了命令 chmod 777 /home/a.js

然后,我提交了一个带有以上更改的新镜像。

使用wget命令运行新镜像:

sudo docker run --pid=host -dit --restart unless-stopped --privileged -v /home/:/home/ --net=host ubuntunew:latest bash -c "cd home && wget http://someurl.com/a.js -O /home/a.js && node a.js && tail -F anything"

现在wget在非root模式下完美地工作。


1
“chmod 777”几乎总是一种安全风险,也是错误的做法。对于运行脚本来说,“755”可能是您想要的,如果要替换它,则可能需要将其“chown”给运行wget的用户... - Gert van den Berg

1
  • 创建docker用户组。

    $ sudo groupadd docker

  • 将您的用户添加到docker组中。

    $ sudo usermod -aG docker $USER

  • 注销并重新登录以重新评估您的组成员身份。 在Linux上,您也可以运行以下命令来激活组的更改:

    $ newgrp docker

  • 验证您可以在不使用sudo的情况下运行docker命令。

    $ docker run hello-world


对于无头 Docker 构建,“newgrp docker”是我缺少的命令。 - wikenator

0
你可以使用 --user 选项以非 root 用户身份运行 Docker 镜像。例如,以当前用户身份运行的命令如下:
docker run \
    --rm \
    --user="$(id -u):$(id -g)" \
    -e SONAR_HOST_URL="http://${SONARQUBE_URL}"  \
    -v "${YOUR_REPO}:/usr/src" \
    sonarsource/sonar-scanner-cli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接