Compose: Suporte --user opção em "docker-compose up"

Criado em 9 jun. 2015  ·  53Comentários  ·  Fonte: docker/compose

Eu preciso passar a opção --user para executar contêineres orquestrados no meu próprio UID. Isso ocorre principalmente por causa dos volumes de host montados e gostaria que o aplicativo dockerizado gerasse arquivos de minha propriedade, não a raiz.

Com docker-compose up , isso não é possível, pelo menos não diretamente. Agora estou usando uma solução maluca:

NAME=`compose run -d --user="$UID" someservicename`
docker rename $NAME ${NAME/_run/}

o que é subótimo, para ser gentil.

areconfig

Comentários muito úteis

Quase um ano atrás, quando eu estava tentando resolver isso, encontrei este tópico. Como nenhuma solução foi fornecida naquele momento, criei vários scripts bash de encapsulamento para executar seu docker-compose.

Agora depois de um ano é tudo a mesma coisa. Eu me pergunto quanto tempo leva para resolver um problema tão simples para um software como o docker-compose, que nem é um provedor real, mas um wrapper.

$UID não é exportado no Linux por padrão, ok? Isso nos impede de criar um docker-compose universal - o que é uma coisa estranha por si só, pois esse software é considerado uma solução de front-end, certo?

Se vocês não gostam de perder tempo com ninharias - e eu entendo isso - então por que você não nos deixa executar um comando de host aleatório antes de executar um serviço, hein? Poderíamos simplesmente fazer algo assim:

services:
  web:
     ...
     host_command: export UID

Isso não é óbvio?

Todos 53 comentários

Não tenho certeza se entendi, docker-compose run --user é uma opção e o docker-compose.yml suporta a chave user (http://docs.docker.com/compose/yml/ #working95dir-entrypoint-user-hostname-domainname-mem95limit-privileged-restart-stdin95open-tty-cpu95shares).

Acho que precisaríamos dar suporte à resolução de variável de ambiente no campo user para que você possa configurá-lo para $UID , certo? #1377

Oi. Sim, a expansão $UID faria o truque neste caso. Ainda assim, a opção $# --user docker-compose up (não apenas para docker-compose run ) seria útil para iniciar todo o projeto como um usuário específico.

O objetivo é permitir a especificação do usuário sem tocar em yml.

iniciar todo o projeto como usuário específico

Nunca me ocorreu que as pessoas pudessem querer fazer isso. Você poderia detalhar o caso de uso?

Não importa, eu rolei para cima. Estou certo em pensar que você está no Linux? Ao usar o boot2docker, ele cria arquivos com permissões sensatas.

Gostaria de saber se há uma maneira de configurar o daemon do Docker para fazer isso para cada volume que ele monta.

Sim, no Linux.

Estou usando o compose para executar testes no CI montando o volume do host (sim, eu sei). Sem esta opção, alguns arquivos são criados com propriedade "errada", ou seja, root:root

Eu sei que poderia usar um contêiner somente de dados e inspecionar/copiar arquivos dele, mas um volume de host é muito mais conveniente e requer menos scripts.

up --user pode ser perigoso se alguns contêineres/serviços já especificarem um usuário.

@mrzechonek Não acho que modificar um contêiner por causa de seu ambiente seja uma boa prática.

@josephpage sim, pode ser. A expansão $UID faria o truque.

Praticamente a única coisa de que preciso são permissões adequadas em volumes de host. Não conheço nenhuma outra maneira de conseguir isso, além de executar o processo do contêiner como $UID ...

Na verdade, eu preferiria que esse recurso estivesse presente no próprio Damon, como @aanand disse. Ou talvez uma opção para montar um volume nesse modo (um driver de armazenamento talvez?).

@mrzechonek , você encontrou uma solução alternativa?

Não, realmente não. Agora estamos fazendo docker-compose run --user e então renomeamos/renomeiamos o container para fazer compose pensar que ele foi iniciado pelo comando up , de modo que stop e ps funcionaria.

1377 está no master e estará na versão 1.5.0, então você poderá fazer user: $UID em docker-compose.yml . Se você se sente confortável usando o master, pode experimentá-lo agora, caso contrário, uma versão RC deve chegar nas próximas semanas.

Vou encerrar este problema, pois o recurso em si é implementado como parte do #1377

e, em seguida, renomeie/renomeie o contêiner para fazer o compose pensar que foi iniciado pelo comando up

Na verdade, não é a primeira vez que ouço sobre a necessidade disso (embora neste caso eu ache que seja apenas temporário). Eu tenho uma correção proposta para isso em #2042

Obrigado, #1377 corrige isso muito bem.

@mrzechonek Você poderia esclarecer como isso resolveu seu problema? Eu tenho exatamente o mesmo caso de uso: "Gostaria que o aplicativo dockerizado gerasse arquivos de minha propriedade, não a raiz"

Eu tentei adicionar user: $UID ao contêiner web e quando uso docker-compose run web touch foo recebo o seguinte:

WARNING: The UID variable is not set. Defaulting to a blank string.

O arquivo foo é criado, mas ainda pertence a root .

Eu usei user: $USER , mas $UID também funciona. Não sei por que sua configuração reclama de variáveis ​​ausentes :(

Tendo exatamente o mesmo problema que @michaelmior.

Ao usar $USER, recebo System error: Unable to find user Max . O que faz sentido porque é um usuário host.

O que pode fazer com que o $UID não esteja disponível durante a execução do docker-compose?

Olá, mesmo problema aqui.
Estou no Fedora 23 e a variável UID não é propagada quando chamo o comando env no host.

Gambiarra:
faça um export UID no host primeiro, depois ligue para seu docker-compose

Seria bom se o docker-compose apenas disponibilizasse $UID sem ter que ser exportado. Acaba sendo clichê.

Se UID não for exportado, não há como compose obtê-lo, então acho que o que você está pedindo é impossível.

Então, compose simplesmente como um aplicativo em execução não tem como inferir o usuário como ele está sendo executado?

Claro, ele pode ler a variável de ambiente $USER , mas você também pode fazer isso a partir do arquivo Compose! Se a variável não for exportada, ela não estará disponível para processos filhos. A solução realmente fácil parece ser apenas exportá-lo.

Estou mais pensando que, se o UID não for declarado, o executável poderá examinar o uid de quem o executou e disponibilizá-lo como tal.

Novamente, pensando em clichê e etapas fáceis de ignorar. A maioria das pessoas quer uma configuração em que o único passo seja docker-compose up . Por que adicionar um pequeno requisito variável de que 99% das pessoas vão definir exatamente da mesma maneira.

Existe um bom recurso que explica quaisquer outras pegadinhas semelhantes entre hosts Mac e Linux?

Além disso, forçar o usuário não é realmente o que queremos no Linux, queremos o comportamento que o Mac tem, onde mesmo quando você executa como root no contêiner, novos arquivos em volumes de host têm permissões úteis :(

Na verdade, eu estava confuso sobre por que meu comportamento no Mac era melhor do que no meu comportamento no Linux, e não é estritamente nada a ver com esse problema. Comecei um problema no Dinghy para buscar soluções para uma boa experiência no Linux.

@mrzechonek você pode compartilhar como usa a diretiva user: para garantir que as permissões do arquivo estejam corretas no host e no contêiner?

Eu simplesmente adiciono user: $UID no arquivo .yml . Isso está no Linux, Gentoo e Ubuntu 12.04.

@mrzechonek obrigado. Seu contêiner faz alguma mágica em tempo de execução? Pelo que entendi, user: espelha a instrução Dockerfile. Mas isso significa simplesmente que os comandos dentro do contêiner são executados como user: $UID . Não consigo entender como isso ajuda nas permissões de volume =/.

@mrzechonek : Isso é diferente. Queremos um recurso para controlar o usuário com o qual o contêiner atua, fora do sistema host, independentemente de quem ele está configurado como dentro do próprio contêiner.

Pense: _" root no contêiner grava como myuser usuário no host"_.

Em nosso caso de uso, é praticamente sempre o mesmo usuário construindo o contêiner e executando-o, então não há problema.

Se, no entanto, você quiser mapear usuários de contêiner para hospedar usuários "dinamicamente", acho que a única maneira de fazer isso é oferecer suporte a namespaces de usuário LXC no próprio daemon do docker, recurso que não foi implementado (ainda? conhecer?).

Eu não acho que isso é algo que docker-compose poderia fazer.

Parece que perdi alguns lançamentos: https://integratedcode.us/2015/10/13/user-namespaces-have-arrived-in-docker/

Desculpe, não uso mais o Docker, pelo menos não ativamente no projeto atual.

Obrigado @mrzechonek. Por fim, estou tentando fazer o que o @gkop está tentando fazer - ter os arquivos gerados pelo contêiner nos volumes montados no host pertencentes ao iniciador do contêiner. É assim que funciona no OS X com o Docker 1.12 beta mais recente (como?) e é assim que eu gostaria de vê-lo no linux também.

@mrzechonek - Alguns aplicativos exigem que sejam executados como um usuário específico ou exigem que o usuário que está executando mapeie para um usuário real no sistema. Nesses casos, é mais fácil deixá-lo como root e fazer o mapeamento sobre a cabeça do contêiner.

(isso substitui muitos hacks feios para mapear o esquema de usuário do sistema em execução atual no contêiner apenas para alinhar tudo)

@dmitrym0 Acho que, no OSX, você executa boot2docker dentro de uma virtualização nativa do OSX (https://github.com/mist64/xhyve/) e, em seguida, os contêineres são criados dentro dessa VM. Isso significa que é realmente a VM fazendo todo o mapeamento do usuário, não o daemon do docker. O root do contêiner ainda é o root do host.

$UID não é definido por padrão nos hosts Ubuntu 16.04. Seria trivial para o docker-compose adquirir o ID do usuário executando-o e injetando-o mesmo assim. Muito menos código clichê e ambiente configurado para usuários de composição de desenvolvimento de aplicativos, o que faz sentido, já que a composição tem tudo a ver com UX do docker.

+1 para docker-compose up --user ou usuário em execução ....

Existe alguma solução ou notícia sobre este problema?

Não, e eu abri esse recurso no mecanismo do docker há algum tempo: https://github.com/docker/docker/issues/22415

Acho que esta é uma questão de impacto muito maior do que está sendo reconhecido atualmente. Ser capaz de alterar qual usuário o contêiner toca no sistema de arquivos, sem ter que fazer o próprio contêiner ciente dos sistemas de permissões, abriria algumas portas.

Se isso é algo em que você está interessado, sugiro compartilhar e votar no ticket que vinculei.

isso funciona para mim: user: "1000:1000"

@jovanialferez FYI se você codificar assim, terá problemas se outras pessoas estiverem envolvidas no projeto que não tenham seu UID e GID definido como 1000. Acho que o OSX começa a numerar usuários regulares em 500 e qualquer Linux instalar com vários usuários terminaria com um UID maior que 1000.

@jovanialferez que funcionará apenas no Linux.

observado. obrigado @nfm @luispabon

Recentemente, mudei do Mac para o Linux e acabei de ser atingido por isso, não entendo como isso ainda não foi resolvido

Mencionando este problema novamente para que os recém-chegados o vejam: https://github.com/moby/moby/issues/22415

Realmente precisamos da capacidade de mapear externamente os processos do docker para um usuário específico. Ênfase no exterior . Não escolha o UID/GID do processo no container. Mas mapeie o processo do contêiner para um UID/GID local de fora.

Sim, de fato. Atribuir o uid/gid do usuário atual ao contêiner funciona apenas no Linux. Parece um problema do docker embora.

Estamos enfrentando um problema um pouco mais esotérico no Windows. Usamos uma instância local do OrientDB, que grava os arquivos no sistema de arquivos do host, e no Windows parece não fazê-lo. Ah... pode ser porque o volume do host não é o volume do bloco?

Quase um ano atrás, quando eu estava tentando resolver isso, encontrei este tópico. Como nenhuma solução foi fornecida naquele momento, criei vários scripts bash de encapsulamento para executar seu docker-compose.

Agora depois de um ano é tudo a mesma coisa. Eu me pergunto quanto tempo leva para resolver um problema tão simples para um software como o docker-compose, que nem é um provedor real, mas um wrapper.

$UID não é exportado no Linux por padrão, ok? Isso nos impede de criar um docker-compose universal - o que é uma coisa estranha por si só, pois esse software é considerado uma solução de front-end, certo?

Se vocês não gostam de perder tempo com ninharias - e eu entendo isso - então por que você não nos deixa executar um comando de host aleatório antes de executar um serviço, hein? Poderíamos simplesmente fazer algo assim:

services:
  web:
     ...
     host_command: export UID

Isso não é óbvio?

+1

Este problema não tem curtidas e +1s suficientes e, para mim, é negligenciado, mas necessário e solicitado por muitos usuários, incluindo eu.

Estou aqui para dar o meu +1 também porque fui atingido por isso. Atualmente, não quero que meus contêineres sejam executados como root -ainda- quero que eles compartilhem um volume no host que seja gravável pelo meu usuário. Isso não pode ser feito se eu não definir o usuário e a expansão seria a maneira mais natural de fazer isso em vez de user: 1000:1000 porque, como dito anteriormente, causará conflitos com usuários de outro ambiente. $UID, mesmo que não seja exportado, prova ser uma solução melhor, pois é baseado em ambiente do que baseado em exposição do docker.

Apenas meus 2 centavos. Então, alguém encontrou uma maneira de fazer isso de qualquer maneira?

@darkguy2008 - Certifique-se de divulgar este: https://github.com/moby/moby/issues/22415

Suspeito que um recurso será necessário dentro do próprio docker antes que o compose possa ser construído em cima dele.

Não tenho certeza se entendi, docker-compose run --user é uma opção e o docker-compose.yml suporta a chave user (http://docs.docker.com/compose/yml/ #working95dir-entrypoint-user-hostname-domainname-mem95limit-privileged-restart-stdin95open-tty-cpu95shares).

Acho que precisaríamos dar suporte à resolução de variável de ambiente no campo user para que você possa configurá-lo para $UID , certo? #1377

O link está quebrado.

Descobriu que adicionar uma variável obrigatória ajudou como solução alternativa:

version: "3"
services:
  testapp:
    image: ubuntu:20.04
    entrypoint: /bin/bash -c "cd $PWD && touch tmp"
    user: ${CURRENT_UID:?"Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"}
    volumes:
      - $PWD:$PWD

Mostraria:

ERROR: Missing mandatory value for "user" option in service "testapp": "Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"

Especificando que o arquivo deve ser executado assim:

CURRENT_UID=$(id -u):$(id -g) docker-compose up

Descobriu que adicionar uma variável obrigatória ajudou como solução alternativa:

version: "3"
services:
  testapp:
    image: ubuntu:20.04
    entrypoint: /bin/bash -c "cd $PWD && touch tmp"
    user: ${CURRENT_UID:?"Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"}
    volumes:
      - $PWD:$PWD

Mostraria:

ERROR: Missing mandatory value for "user" option in service "testapp": "Please run as follows 'CURRENT_UID=$(id -u):$(id -g) docker-compose up'"

Especificando que o arquivo deve ser executado assim:

CURRENT_UID=$(id -u):$(id -g) docker-compose up

O problema é que meus serviços exigem acesso root para iniciar. Por exemplo:

app-php-fpm  | [14-Jun-2020 00:15:12] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
app-php-fpm  | [14-Jun-2020 00:15:12] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
app-redis    | 1:M 14 Jun 2020 00:15:12.710 * Ready to accept connections
app-php-fpm  | [14-Jun-2020 00:15:12] ERROR: Unable to create the PID file (/run/php-fpm.pid).: Permission denied (13)
app-php-fpm  | [14-Jun-2020 00:15:12] ERROR: FPM initialization failed
app-webserver exited with code 1
app-mysql exited with code 1
app-php-fpm exited with code 78
Esta página foi útil?
0 / 5 - 0 avaliações