在我的团队中,我们使用 Docker 容器在本地运行我们的网站应用程序,同时对它们进行开发。
假设我正在开发一个 Flask 应用程序,app.py
并且依赖项在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
。除非应用程序将文件写回到工作目录中,否则这不是问题。如果是这样,那么我们最终可能会在工作目录中拥有文件(例如cache.sqlite
或) 。这给我们团队中的用户带来了许多问题。debug.log
root
对于我们的其他应用程序,我们通过运行应用程序来解决这个问题主机用户的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
在这种情况下,应用程序将作为不存在的1000
容器内具有 ID 的用户,但写入主机目录的任何文件最终都正确归robin
用户所有。这在 Django 中运行良好。
但是,Flask 拒绝以不存在的用户身份运行(在调试模式下):
$ 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应用程序以主机用户身份在主机上创建文件?
我现在能想到的唯一解决方案(超级黑客)是将/etc/passwd
docker 镜像中的权限更改为全局可写,然后在运行时向该文件添加新行以将新的 UID/GID 对分配给用户名。
答案1
这个答案是发布在 StackOverflow 上经过罗伯特:
您可以共享主机的密码文件:
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
在 docker 接收命令之前,和 $USER 都在主机 shell 中解析)