linux - 在 Docker 容器中以主机用户身份运行

标签 linux docker flask development-environment sudo

在我的团队中,我们使用 Docker 容器在本地运行我们的网站应用程序,同时对它们进行开发。

假设我在 app.py 上开发一个 Flask 应用程序,并在 requirements.txt 中有依赖项,工作流程大致如下所示:

# I am "robin" and I am in the docker group
$ whoami
robin
$ groups
robin docker

# Install dependencies into a docker volume
$ docker run -ti -v `pwd`:`pwd` -w `pwd` -v pydeps:/usr/local python:3-slim pip install -r requirements.txt
Collecting Flask==0.12.2 (from -r requirements.txt (line 1))
# ... etc.

# Run the app using the same docker volume
$ docker run -ti -v `pwd`:`pwd` -w `pwd` -v pydeps:/usr/local -e FLASK_APP=app.py -e FLASK_DEBUG=true -p 5000:5000 python:3-slim flask run -h 0.0.0.0
 * Serving Flask app "app"
 * Forcing debug mode on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 251-131-649

现在我们有一个本地服务器运行我们的应用程序,我们可以对本地文件进行更改,服务器将根据需要刷新。

在上面的示例中,应用程序最终以 root 用户身份运行。除非应用程序将文件写回工作目录,否则这不是问题。如果是这样,那么我们可能会在 root 拥有的工作目录中得到文件(例如,cache.sqlitedebug.log 之类的文件) .这给我们团队的用户带来了许多问题。

对于我们的其他应用程序,我们通过使用 主机用户的 UID 和 GID 运行应用程序解决了这个问题 - 例如对于 Django 应用程序:

$ docker run -ti -u `id -u`:`id -g` -v `pwd`:`pwd` -w `pwd` -v pydeps:/usr/local -p 8000:8000 python:3-slim ./manage.py runserver

在这种情况下,应用程序将在容器内以 ID 1000不存在用户身份运行,但写入主机目录的任何文件最终都会正确robin 用户拥有。这在 Django 中运行良好。

但是,Flask 拒绝以不存在的用户身份运行(在 Debug模式下):

$ docker run -ti -u `id -u`:`id -g` -v `pwd`:`pwd` -w `pwd` -v pydeps:/usr/local -e FLASK_APP=app.py -e FLASK_DEBUG=true -p 5000:5000 python:3-slim flask run -h 0.0.0.0
 * Serving Flask app "app"
 * Forcing debug mode on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
Traceback (most recent call last):
...
  File "/usr/local/lib/python3.6/getpass.py", line 169, in getuser
    return pwd.getpwuid(os.getuid())[0]
KeyError: 'getpwuid(): uid not found: 1000'

有没有人知道我有什么办法:

  • 让 Flask 不用担心未分配的用户 ID,或者
  • 以某种方式在运行时将用户 ID 动态分配给用户名,或者
  • 否则是否允许 docker 应用以主机用户身份在主机上创建文件?

我现在唯一能想到的解决方案( super hacky)是将docker镜像中 /etc/passwd 的权限更改为全局可写,然后添加一个新行文件在运行时将新的 UID/GID 对分配给用户名。

最佳答案

您可以共享主机的密码文件:

docker run -ti -v /etc/passwd:/etc/passwd -u `id -u`:`id -g` -v `pwd`:`pwd` -w `pwd` -v pydeps:/usr/local -p 8000:8000 python:3-slim ./manage.py runserver

或者,使用 useradd 将用户添加到图像中,使用 /etc 作为音量,与使用 /usr/local 的方式相同>:

docker run -v etcvol:/etc python..... useradd -u `id -u` $USER

(id -u 和 $USER 在 docker 接收命令之前在主机 shell 中解析)

关于linux - 在 Docker 容器中以主机用户身份运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45836272/

相关文章:

docker - Kubernetes部署失败的jenkins部署 “failed to create containerd task”

python - 为什么我的 Flask 应用返回空白页面

linux - Dummynet 与流不匹配

linux - 如何使用 sshpass 在两台远程计算机之间复制数据?

image - 如何在 Docker 的 ubuntu 中安装 JLink?

docker - Docker uWSGI-NGINX:uWSGI可以,但是NGINX是502

Python Flask 应用程序无法解析 XML 请求数据

google-app-engine - 使用 Google Cloud Platform 运行 Websockets

linux - 如何从 .cer 文件获取 CA 根证书和中间证书

linux - 内核-网络, "private"结构的作用