Executando como um usuário do host em um contêiner do Docker

3

Na minha equipe, usamos contêineres do Docker para executar localmente os aplicativos do nosso site enquanto desenvolvemos neles.

Supondo que estou trabalhando em um aplicativo do Flask em app.py com dependências em requirements.txt , um fluxo de trabalho seria mais ou menos assim:

# 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

Agora, temos um servidor local executando nosso aplicativo, e podemos fazer alterações nos arquivos locais e o servidor será atualizado conforme necessário.

No exemplo acima, o aplicativo acaba sendo executado como o usuário root . Isso não é um problema, a menos que o aplicativo grave os arquivos de volta no diretório de trabalho. Se isso acontecer, poderemos acabar com arquivos (por exemplo, algo como cache.sqlite ou debug.log ) em nosso diretório de trabalho de propriedade de root . Isso causou vários problemas para os usuários de nossa equipe.

Para nossos outros aplicativos, resolvemos isso executando o aplicativo com o UID e o GID do usuário do host - por exemplo, para um aplicativo do 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

Nesse caso, o aplicativo será executado como um usuário inexistente com ID 1000 dentro do contêiner, mas todos os arquivos gravados no diretório do host acabam corretamente pertencidos pelo robin do utilizador. Isso funciona bem no Django.

No entanto, o Flask se recusa a executar como um usuário inexistente (no modo de depuração):

$ 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'

Alguém sabe se existe alguma maneira que eu possa:

  • Make Flask não se preocupa com o ID de usuário não atribuído ou
  • De alguma forma, atribua dinamicamente o ID do usuário a um nome de usuário em tempo de execução ou
  • Caso contrário, permite que o aplicativo docker crie arquivos no host como o usuário do host?

A única solução em que posso pensar agora (super hacky) é alterar as permissões de /etc/passwd na imagem do docker para serem globalmente graváveis e, em seguida, adicionar uma nova linha ao arquivo em tempo de execução para atribuir o novo UID / GID par para um nome de usuário.

    
por Robin Winslow 23.08.2017 / 00:11

1 resposta

0

Esta resposta foi publicada no StackOverflow por Robert :

Você pode compartilhar o arquivo passwd do host:

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

Ou adicione o usuário à imagem com useradd , usando /etc como volume, da mesma maneira que você usa /usr/local :

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

(Ambos id -u e $ USER são resolvidos no shell do host, antes que o docker receba o comando)

    
por Robin Winslow 03.05.2018 / 11:47