在Docker容器中以主机用户身份运行 [英] Running as a host user within a Docker container
问题描述
在我们的团队中,我们使用Docker容器在开发网站应用程序的同时在本地运行我们的网站应用程序.
In my team we use Docker containers to locally run our website applications while we do development on them.
假设我正在使用 requirements.txt
中的依赖项在 app.py
上开发Flask应用程序,则工作流程大致如下:
Assuming I'm working on a Flask app at app.py
with dependencies in requirements.txt
, a working flow would look roughly like this:
# 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
现在我们有一个运行应用程序的本地服务器,我们可以更改本地文件,服务器将根据需要刷新.
Now we have a local server running our application, and we can make changes to the local files and the server will refresh as needed.
在上面的示例中,该应用程序最终以 root
用户身份运行.除非应用程序将文件写回到工作目录中,否则这不是问题.如果这样做的话,我们可以在 root
拥有的工作目录中保存文件(例如 cache.sqlite
或 debug.log
之类的文件).这给我们团队中的用户带来了许多问题.
In the above example, the application end up running as the root
user. This isn't a problem unless the application writes files back into the working directory. If it does then we could end up with files (e.g. something like cache.sqlite
or debug.log
) in our working directory owned by root
. This has caused a number of problems for users in our team.
对于其他应用程序,我们通过使用主机用户的 UID和GID运行该应用程序来解决此问题-例如对于Django应用:
For our other applications we've solved this by running the application with the host user's UID and GID - e.g. for a Django app:
$ 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中可以正常工作.
In this case, the application will be running as a non-existent user with ID 1000
inside the container, but any files written to the host directory end up correctly owned by the robin
user. This works fine in Django.
但是,Flask拒绝以不存在的用户身份运行(在调试模式下):
However, Flask refuses to run as a non-existent user (in debug mode):
$ 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'
有人知道我是否有办法:
Does anyone know if there's any way that I could either:
- 让Flask不必担心未分配的用户ID,或者
- 在运行时以某种方式将用户ID动态分配给用户名,或
- 是否允许docker应用程序以主机用户身份在主机上创建文件?
我现在唯一想到的解决方案(超级hacky)是将docker映像中的/etc/passwd
权限更改为可全局写入,然后在该行上添加新行文件在运行时将新的UID/GID对分配给用户名.
The only solution I can think of right now (super hacky) is to change the permissions of /etc/passwd
in the docker image to be globally writeable, and then add a new line to that file at runtime to assign the new UID/GID pair to a username.
推荐答案
您可以共享主机的passwd文件:
You can share the host's passwd file:
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
或者,使用/etc
作为卷,使用 useradd
将用户添加到映像中,就像使用/usr/local
:
Or, add the user to the image with useradd
, using /etc
as volume, in the same way you use /usr/local
:
docker run -v etcvol:/etc python..... useradd -u `id -u` $USER
( id -u
和$ USER都在主机外壳中解析,在docker接收命令之前)
(Both id -u
and $USER are resolved in the host shell, before docker receive the command)
这篇关于在Docker容器中以主机用户身份运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!