Compose: docker-compose copia o arquivo ou diretório para o contêiner

Criado em 1 jan. 2018  ·  141Comentários  ·  Fonte: docker/compose

perdemos a possibilidade de copiar um arquivo ou diretório usando docker-compose. Eu acho isso muito útil.
Verifique muitos +1 em https://github.com/docker/compose/issues/2105

kinfeature statu0-triage

Comentários muito úteis

Qual é a utilidade de insistir dogmaticamente que é antipadrão, só porque em _alguns_ casos pode _eventualmente_ causar problemas? Isso definitivamente tem uma boa utilidade, pois você pode adicionar uma linha a um arquivo existente, em vez de ter que criar uma pasta e um arquivo extras e, em seguida, mover o arquivo a ser adicionado lá. Essa criação burocrática e sem sentido de arquivos minúsculos é o verdadeiro antipadrão, impedindo os usuários de criar arquivos docker-compose simples e fáceis de manter.

Se os usuários desejam fazer coisas prejudiciais com o Docker, eles encontrarão uma maneira, não importa o que você faça. Recusar-se a adicionar recursos legítimos apenas porque alguém pode usá-los indevidamente um dia é tolice.

Todos 141 comentários

Qual é o caso de uso? A maioria dos usos sugeridos que vi eram antipadrões.

Você pode ver alguns dos muitos casos de uso clicando no link fornecido. Como você pode ver, muitos assinantes o consideram um recurso realmente útil em vez de um "antipadrão"

opa, agora vejo que "algo" aconteceu com o problema # 2105 porque não há mais comentários ...
Talvez eu tenha fornecido o link errado ...

então, acho muito útil copiar alguns arquivos de configuração / inicialização para o container. Como exemplo, algumas coisas * .sql para contêineres db, algum conteúdo html / js / css para contêineres apache / nginx ou mesmo arquivo jar para contêineres java. Isso o tornará disponível / executável "globalmente" não apenas na máquina onde foi composto, como no caso de volume (s) de montagem. Principalmente, esta será uma combinação de arquivos locais de host e contidos em contêiner. Na verdade, qualquer contêiner pode ser considerado inútil sem qualquer configuração ou inicialização

este é o link correto: https://github.com/docker/compose/issues/1664

+1

Isso o tornará disponível / executável "globalmente", não apenas na máquina onde foi composto como no caso de volume (s) de montagem

O problema com isso é que ele é incrivelmente míope (daí o termo "antipadrão"), pois vai forçar você a repetir a operação toda vez que os contêineres forem recriados. Sem mencionar o fato de que ele escala muito mal (e se você tiver 10 contêineres? 20? 100?)

A solução real para o seu problema é incluir os arquivos necessários em sua construção (Dockerfile) e reconstruir quando uma atualização for necessária.

claro, se for composto incluindo todo o conteúdo "compartilhado" em um contêiner, escalar 10-20-100- contêineres seria muito mais fácil. Tudo que você precisa é extraí-lo do repositório e montar (sim, neste caso, montar) apenas a configuração específica do nó. E ainda mais, você não precisa executar docker-compose em cada nó.
Claro que podemos usar docker-compose em combinação com build: & Dockerfile, no entanto, as coisas se tornam um pouco mais complexas e a configuração do yaml em docker-compose é muito mais "elegante": o)

Estou tendo um problema em que a cópia seria útil (pelo menos como uma substituição). Eu desenvolvo principalmente no mac, então quase nunca vejo um problema com comandos executados como root no contêiner e exportando para um volume montado. No entanto, recentemente usar o mesmo fluxo de trabalho em um CentOs causou alguns problemas, porque os arquivos pertencentes ao usuário root estão sendo adicionados ao host por meio do volume montado. Eu gostaria, nesses casos, de poder apenas copiar os arquivos do host para o contêiner em vez de montá-los.

O problema relacionado: # 1532

atualizar

Acho que no meu caso posso me safar usando COPY no Dockerfile e ter vários arquivos docker-compose, um dos quais usa uma montagem de volume.

Caso de uso:
Quero usar o diretório do sistema de arquivos somente leitura dentro do contêiner. O aplicativo cria novos arquivos nesse diretório, mas, como o sistema de arquivos é lido, isso causa erros.

Não consigo usar o volume rw, porque o sistema de arquivos é somente leitura.
Não posso usar o volume ro, porque o efeito será o mesmo.

Seria incrível fazer gravações que persistem apenas quando o contêiner é executado. Posso fazer wrapper (https://stackoverflow.com/questions/36362233/can-a-dockerfile-extend-another-one) para apenas COPY arquivos, mas fazendo isso na composição, semelhante a volume , seria melhor

Caso de uso: iniciar vários contêineres docker simultaneamente a partir de .gitlab-ci.yml que precisam ser gravados no diretório do repositório git.

Se o processo dentro de um contêiner falhar ou se o trabalho ci for cancelado antes que o contêiner seja limpo depois de si mesmo, os arquivos restantes não podem ser excluídos pelo gitlab-runner devido à falta de permissões. Agora eu poderia copiar os arquivos dentro do contêiner do volume para outro diretório, mas isso seria um antipadrão, não seria?

Isso é diferente de volumes: - ./folder_on_host/ :/folder_in_container/ ?
Posso copiar arquivos do host para o contêiner (equivalente a COPY) dessa forma no meu arquivo de composição

@harpratap você está certo, mas a desvantagem é que / folder_in_container não deve existir ou deve estar vazio ou então será sobrescrito. Se você tiver um script bash como seu ponto de entrada, você pode contornar isso vinculando simbolicamente seus arquivos ao diretório originalmente pretendido depois de criar um volume em / some_empty_location

1 por ter uma funcionalidade de CÓPIA. Nosso caso de uso é para criar ambientes de desenvolvimento local rapidamente e copiar em configurações para as configurações de desenvolvimento.

+1 para COPY. Esse seria um recurso realmente útil.

Caso de uso: no modo swarm, tenho um serviço usando a imagem mysql. Preciso copiar meu script de inicialização em /docker-entrypoint-initdb.d/ para que o MySQL possa executá-los.

Embora seja possível criar uma imagem no topo do mysql, copie os arquivos e use-o ou conecte-se ao mysql
tarefa no swarm e, em seguida, executar manualmente os scripts, é meio desnecessário na minha opinião.

+1 para COPY / ADD,

Caso de uso:
O Fluentd requer que os arquivos de configuração sejam movidos para o contêiner durante o tempo de execução. Esses arquivos de configuração são criados em tempo de execução por nosso mecanismo Jenkins e sem um COPY / ADD no docker compose ele simplesmente falha.

+1 para COPY

Suponha que se tenha um arquivo de configuração compartilhado em várias máquinas docker, com seus Dockerfiles nos respectivos subdiretórios do diretório docker-compose. Como você copia essa configuração compartilhada em cada imagem? Não consigo vincular simbolicamente a ../ partir do contexto do Dockerfile sem obter COPY failed: Forbidden path outside the build context

Neste caso, ao executar a compilação docker-compose, gostaria de copiar os arquivos de configuração do contexto docker-compose antes de executar as etapas de compilação docker.

Ficarei feliz se alguém puder sugerir uma solução alternativa, é claro.

Seria bom ter um recurso !!

Por favor, não comente apenas com +1 - é uma perda de tempo de todos. Se você tiver informações adicionais a fornecer, faça-o; caso contrário, basta adicionar um polegar para cima para o problema original.

Qual é a utilidade de insistir dogmaticamente que é antipadrão, só porque em _alguns_ casos pode _eventualmente_ causar problemas? Isso definitivamente tem uma boa utilidade, pois você pode adicionar uma linha a um arquivo existente, em vez de ter que criar uma pasta e um arquivo extras e, em seguida, mover o arquivo a ser adicionado lá. Essa criação burocrática e sem sentido de arquivos minúsculos é o verdadeiro antipadrão, impedindo os usuários de criar arquivos docker-compose simples e fáceis de manter.

Se os usuários desejam fazer coisas prejudiciais com o Docker, eles encontrarão uma maneira, não importa o que você faça. Recusar-se a adicionar recursos legítimos apenas porque alguém pode usá-los indevidamente um dia é tolice.

Acho que o que você está fazendo é na verdade a maneira certa de fazer isso, neste caso.

A questão aqui levantada era mais como, suponha que o arquivo mongo.conf foi compartilhado entre três imagens docker que são orquestradas por um arquivo docker-compose. Como você garante que ele seja o mesmo em cada subdiretório de compilação do docker?

Se você usar links simbólicos, por exemplo, o docker reclama que o arquivo é externo ao ambiente de construção, por exemplo, a construção do docker carece de reprodutibilidade, pois modificações fora desse diretório podem alterar a construção.

Portanto, a única maneira de orquestrar isso é com uma cópia de arquivo, que atualmente precisa ser feita com um Makefile ou script de shell antes de executar docker-compose, então parecia uma ideia discutir se esse era um recurso que docker-compose poderia fazer, como certamente é um caso de uso comum.

O problema que você está levantando parece ser mais sobre a injeção de tempo de execução (tempo de inicialização) de uma modificação de arquivo local.

Eu acho que você está realmente bem no que está fazendo, o que você disse acima é apenas como é feito. Uma imagem docker sempre pode ser construída para aceitar variáveis ​​de ambiente para responder a perguntas como onde está o diretório de configuração, e esse diretório de configuração pode ser "injetado" usando um volume em tempo de execução - mas isso depende do design da imagem docker, aproveitando variáveis ​​de ambiente e mapeamentos de volume (que são recursos que o docker suporta como modificação de configuração do tempo de execução).

Espero não ter interpretado mal seu comentário e que minha resposta seja útil.

@jpz - De alguma forma, apaguei meu comentário original - caramba - desculpe! Obrigado - sim, isso é útil.

Meu comentário original foi mais ou menos:

Meu caso de uso é que eu quero declarar um serviço usando mongo sem ter que criar minha própria imagem personalizada apenas para copiar um arquivo de configuração como /etc/mongod.conf .

ATUALIZAÇÃO: usei volumes . Um ou dois anos atrás - pensei ter tentado fazer isso com uma experiência ruim ... mas parece bom.

+1 para COPY

Eu criei uma ideia rápida para isso. Ele assume que o serviço de composição do docker é denominado phpfpm , mas você pode alterá-lo como desejar. sinta-se à vontade para modificar.
https://gist.github.com/markoshust/15efb29aa5eebf8adae402af18b2e674

Olá, gostaria de saber como está o andamento desse assunto. Agora, estou usando o windows 10 home com docker-toolbox. Parece principalmente um erro quando tento encontrar o arquivo de montagem como um volume no contêiner. Seria bom ter recursos de COPY no docker-compose

COPY / ADD seria definitivamente um recurso bem-vindo.

Um caso de uso: executar uma instância Graylog no Docker para fins de desenvolvimento. Para iniciar uma entrada automaticamente, uma especificação JSON deve ser colocada em / usr / share / graylog / data / contentpacks
Com o recurso COPY / ADD, será tão fácil quanto uma única linha em YML.

Para fazê-lo funcionar agora (em 16 de outubro de 2018), é necessário montar um volume até esse ponto E copiar o conteúdo original dessa pasta para o volume persistente. O que é silencioso e inconveniente.

Eu me beneficiaria com isso, tenho um conjunto de ferramentas que importam uma semente de banco de dados para um contêiner e, em seguida, executo o importador de banco de dados devtools com base nesse arquivo. Eu não quero ter que fazer:

docker cp "${seed_file}" $(docker-compose ps -q devtools):/tmp/seed_file

para poder importar minha semente. E não, eu não vou compilar minhas imagens dev com um esquema fixo, isso vai contra o padrão de desenvolvimento da web, no mínimo. Os contêineres devem ser para portabilidade do aplicativo, não dados.

Faria mais sentido fazer:

docker-compose cp "${seed_file}" devtools:/tmp/seed_file

Resumindo, é apenas um short-hand que basicamente faz a mesma coisa, mas parece melhor alavancar docker-compose qualquer lugar do que misturar coisas ...

1) esta parece ser uma duplicata de # 3593
2) Eu concordo com @ shin- que os casos de uso elaborados estão seguindo um anti-padrão
3) mas encerrar o comando cp do Docker faz sentido, imo

@funkyfuture Se você acha que esses casos de uso seguem um antipadrão, sugira uma solução que não siga.

E a "seção de dados" semelhante ao k8s ?
Por exemplo:

services:
  service1:
    image: image.name
    data:
      filename1.ini: |
        [foo]
        var1=val1
        [bar]
        var2=val2
      filename2.yml: |
        foo:
          bar: val1

ou talvez o mesmo, mas para a seção volumes:

volumes:
  service_config:
    data:
      filename1.ini: |
        [foo]
        var1=val1
        [bar]
        var2=val2

services:
  service1:
    image: image.name
    volumes:
      - service_config:/service/config

@canela-

O problema com isso é que ele é incrivelmente míope (daí o termo "antipadrão"), pois vai forçar você a repetir a operação toda vez que os contêineres forem recriados. Sem mencionar o fato de que ele escala muito mal (e se você tiver 10 contêineres? 20? 100?)

O problema real aqui é que algumas pessoas são muito rápidas em rejeitar os recursos solicitados porque isso entra em conflito com sua visão limitada dos cenários reais de caso de uso.

Aqui estou procurando uma maneira de copiar meu arquivo de configuração em um contêiner que acabei de obter no dockerhub. Não tenho acesso ao Dockerfile original e seria uma grande conveniência ter esse recurso (em vez de tentar construir outra camada por cima, o que funcionaria, mas é inconveniente, não quero reconstruir quando mudar algo).

Caso de uso:

Eu executo um banco de dados em um ambiente de teste de integração e quero que os dados sejam redefinidos a cada iteração, quando os contêineres são iniciados. Incorporar os dados em uma imagem personalizada funcionaria, mas montar um volume é complicado - porque os dados no host devem ser redefinidos.

Nós mantemos os dados independentemente e seria mais conveniente usar apenas a imagem padrão do banco de dados - copiando os dados para ela antes de começar a funcionar. Atualmente, isso não parece ser possível com docker-compose.

Tenho um caso de uso em mente. Quero basear minha imagem em uma imagem padrão, como um servidor Apache genérico. Eu quero copiar meu html durante a criação da imagem. Assim, posso atualizar minha imagem de base sempre que quiser e a diretiva de cópia garantirá que meu conteúdo seja incluído na nova imagem.

BTW, eu atualmente uso dockerfiles e uma diretiva de compilação em meu docker-compose.yaml para fazer isso. Seria bom se eu não precisasse dos arquivos do docker.

@tvedtorama -

Caso de uso:

Eu executo um banco de dados em um ambiente de teste de integração e quero que os dados sejam redefinidos a cada iteração, quando os contêineres são iniciados. Incorporar os dados em uma imagem personalizada funcionaria, mas montar um volume é complicado - porque os dados no host devem ser redefinidos.

Nós mantemos os dados independentemente e seria mais conveniente usar apenas a imagem padrão do banco de dados - copiando os dados para ela antes de começar a funcionar. Atualmente, isso não parece ser possível com docker-compose.

Este problema discute o desejo de copiar arquivos no tempo de construção da imagem, não no tempo de execução. Eu sugeriria criar um tíquete separado para discutir os méritos disso. Pode confundir esta discussão divagar em discutir injeção de arquivo em tempo de execução (que eu interpreto sobre o que você está falando).

@ c0ze -

E a "seção de dados" semelhante ao k8s ?
Por exemplo:

...

Não estou totalmente atualizado com o que essa configuração faz, mas sim, parece que seria uma solução. Fundamentalmente, quando você tem segredos (por exemplo, qual é o nome de usuário / pwd / porta de login do banco de dados), como faço para injetar isso nas imagens do docker - clientes e servidores - sem escrever um monte de código?

Algo como a seção de dados do kubernetes poderia funcionar - já que seria uma fonte única de verdade. Caso contrário, pode-se descobrir que eles têm os mesmos segredos mantidos várias vezes em várias imagens docker.

Também existe a técnica anterior, o que ajuda a conduzir a conversa para saber se essa é realmente uma boa ideia que vale a pena adotar ou não.

Para mim, tudo isso começou com o desejo de compartilhar um arquivo de configuração invariável entre contêineres, e perceber que não havia maneira de fazer isso sem scripts externos para docker-compose e escrever a configuração de uma única fonte de verdade em cada um as pastas Docker abaixo da pasta docker-compose. É claro que entendi o argumento de imutabilidade para o Docker (por exemplo, o diretório Dockerfile descreve completa e completamente como construir a imagem), portanto, pedir a automação para copiar as coisas para esse diretório parece que vai contra esses princípios.

Eu acho que a discussão é o quão intrusivo o docker-compose pode ser? Este é um caso de uso comum o suficiente para justificar tal automação? Se não for, então parecemos sobrecarregar os mecanismos de passagem de variáveis ​​de ambiente com as responsabilidades de injetar segredos de fora para dentro de uma única fonte de verdade, tarde (por exemplo, em tempo de execução). Espero que meus pontos sejam coerentes o suficiente aqui.

Isso não é muito importante para mim, mas acho que vale a pena discutir o caso de uso.

Seria extremamente útil para mim. No trabalho, o software antivírus bloqueia a capacidade do Windows 10 de compartilhar volumes com contêineres. É uma organização enorme e não é possível fazer com que mudem devido a uma política definida em outro continente.

Olá, meu caso de uso: estou usando a configuração docker-compose do Prometheus de código aberto (o repo é mantido por outras pessoas). Possui configurações que são montadas em contêineres. PROBLEMA: Não consigo fazer docker-compose em uma máquina remota (como aws docker-machine ou dentro do executor CI / CD) porque não consigo montar configs corretamente. Neste caso, gostaria de copiá-los / incorporá-los. Para dados RW, existem volumes, para RO -?

Ter volumes de RO com possibilidade de definir dados iniciais é a outra opção.

Solução atual: conecte-se ao host docker via ssh, clone / atualize repo e execute docker-compose up. Isso funciona para o caso manual, mas é doloroso para a automação :(

+1

Caso de uso: eu tenho uma máquina docker de desenvolvimento que executa um banco de dados e sempre que configuro, preciso de um despejo recente do banco de dados a ser instalado. Efetivamente, isso significa:

  1. Extraia a imagem do docker do banco de dados de extern
  2. Copie e extraia o ZIP para a imagem em execução.
  3. Execute db-restore dentro do volume.
  4. Exclua o db dump.

Agora, o grande problema é que a etapa 2 sempre será diferente para cada desenvolvedor, porque há muitas versões de despejo desse banco de dados, então o mais fácil seria se cada desenvolvedor tivesse seu próprio arquivo de composição com seu local / versão de despejo específico, e então faça com que o docker monte a imagem com esse local de arquivo específico durante a composição, que também pode ser alterado rapidamente quando uma versão diferente for necessária.

Meu caso de uso é simples. Não quero volumes nem quero rolar minha própria imagem. Só quero colocar uma cópia defensiva simples de um arquivo de configuração em um contêiner depois de criado e antes de ser iniciado.

isso ainda é um problema?
Eu tenho um aplicativo django com um arquivo de configurações muito longo. Para mim, seria muito mais fácil criar uma imagem docker e copiar um único arquivo de configuração para cada contêiner.
Passar todas as configurações como ENV é para mim o antipadrão. Requer muito código, é difícil de manter e pode ser resolvido com um único comando de cópia.

Abri o # 6643 e adoraria receber um feedback sobre como ele seria considerado um antipadrão. Especialmente, em um ambiente onde vários arquivos de configuração podem precisar ser adicionados / modificados em tempo real.

@canela-

O problema com isso é que ele é incrivelmente míope (daí o termo "antipadrão"), pois vai forçar você a repetir a operação toda vez que os contêineres forem recriados. Sem mencionar o fato de que ele escala muito mal (e se você tiver 10 contêineres? 20? 100?)

Como funciona docker-compose exec com vários contêineres?

    --index=index     index of the container if there are multiple
                      instances of a service [default: 1]

Não deveríamos tentar obter o mesmo comportamento com cp ?

IMHO exec é tão efêmero quanto cp seria. Mas eu sempre considero isso comandos de "desenvolvimento" de qualquer maneira, ambientes de desenvolvimento devem ser efêmeros, não devem?

Eu não tinha visto o comentário sobre muitos desenvolvedores aqui dizendo que eles são míopes por tentar corrigir isso rapidamente solicitando esse recurso. Eu acho que isso é um pouco duro e condescendente. Se há algo que aprendi em meus anos de desenvolvimento é o seguinte:

Não é o que seu software faz, é o que o usuário faz com ele que conta

Obviamente, eu entendo que você tem o papel de evitar que as coisas enlouqueçam, mas não é porque alguém usa uma ferramenta incorretamente com base na sua visão que todo mundo vai começar a fazer isso e o inferno vai explodir.

Todos os casos especiais que vi aqui são muito apropriados na maioria das vezes. E, a maioria desses casos especiais não deveriam e não aconteceriam no sistema de produção, eles são, por exemplo, como o meu caso que expliquei há pouco, personalizar um ambiente de desenvolvimento e executar arquivos especiais em um contêiner que não pode usar um mapeamento de volume. A maioria dos exemplos diz claramente que eles não querem usar esquemas, dados ou arquivos de configuração e não podem usar mapeamento de volume, então não vejo por que isso é tão inconveniente quanto usar o termo "visão curta".

Acho que você deve pesar cuidadosamente suas palavras ao dizer coisas assim ...

  1. Eu realmente não preciso de uma palestra sobre o que posso dizer ou escrever. Lamento que "míope" o ofenda. Ainda é correto dizer que essas coisas pertencem ao Dockerfile por design.
  2. Não sou mais um mantenedor. Por favor, pare de me fazer @ -ing sobre coisas sobre as quais não tenho mais controle.
  1. Tenho que dizer que estou do lado do crazycodr aqui ... Descartar casos de uso perfeitamente válidos do mundo real como "anti-padrão", sem dar alternativas práticas e realistas úteis, é uma abordagem hostil ao desenvolvedor e, honestamente, até um pouco rude.
  2. Mantenedor ou não, se você participou da parte de discussão do github você basicamente tem que conviver com pessoas comentando seus comentários. É assim que funciona. Lide com isso...

Vamos trazer de volta. Pergunta técnica honesta aqui. Com docker stack, temos uma opção de "configurações". Esse é um recurso nativo do docker, mas é para serviços, não contêineres. Qual é a viabilidade de fazer algo assim funcionar no nível do contêiner em vez do nível de serviço? Como o docker stack implementa o provisionamento de configuração? Essa implementação pode ser replicada para docker-compose especificamente?

Pelo menos metade dos casos de uso mencionados aqui são sobre configurações, portanto, muitas pessoas ficariam satisfeitas se apenas essa coceira fosse arranhada.

Outro caso de uso simples são coisas como validação de domínio do Google. Se você usar a imagem wordpress, não será possível adicionar um arquivo que o Google irá verificar. Você precisa fazer uma imagem totalmente nova para fazer isso.

Além disso, esses comentários dizendo que as coisas são "antipadrão" mal fazem sentido, cheiram a elitismo.

EDIT: caramba, leia mais, graças a Deus ele não é mais o mantenedor

Então você está me dizendo que se eu quiser copiar um pequeno arquivo de configuração em uma imagem pré-construída (digamos, nginx ou mariadb ), agora preciso gerenciar minha própria configuração de compilação de imagem e duplicar o espaço em disco usado (imagem original e imagem configurada)?

Isso deveria ser um recurso.

duplicar o espaço em disco usado

você não está quando está usando o Docker.

Eu gosto de como você critica uma coisa do que ele disse, que é a coisa mais secundária de tudo isso. Este deve ser um recurso. Este problema vai crescer cada vez mais por causa das pessoas chegando aqui conforme o docker cresce, já que é um caso de uso comum e as pessoas vão esperar que exista por causa do bom senso, algo que os mantenedores ex e atuais aqui parecem não ter.

Eu gosto de como você critica uma coisa do que ele disse, que é a coisa mais secundária de tudo isso.

um argumento inválido deve ser anotado como tal.

Acho que a questão aqui é que o argumento "anti-pattern" pode ser válido dada uma determinada estratégia de negócios (veja o ponto @washtubs ). podemos não concordar com essa estratégia, mas isso não justifica ataques pessoais. no final, são os esforços anteriores de @ shin-com docker-py que permitiriam a você implementar uma alternativa para docker-compose .

Que argumento "anti-padrão"? Não há nenhum argumento apresentado. É apenas um "não, porque anti-padrão" sem nenhuma lógica por trás disso, apenas dizendo sem nada que o apoie. É como se as pessoas dizendo isso pensassem no pior cenário de caso em suas cabeças, decidissem que esse cenário era um antipadrão e então descartassem tudo como tal, sem nem mesmo escrever sobre o chamado cenário antipadrão.

É apenas elitismo. Muitos comentários aqui foram sobre o quão ridículo é o raciocínio para não adicionar isso e todos eles foram ignorados.

O bom senso e a lógica não se importam com seus sentimentos ou elitismo. Ou seus antipadrões inventados.

Sim, @robclancy , por favor, mantenha-o civilizado FFS. Eu quero esse recurso, mas se tudo que você vai fazer é falar merda para os mantenedores, vá para o reddit, por favor. A correção anterior de @funkyfuture é totalmente garantida.

no final, são os esforços anteriores de @shin-com docker-py que permitiriam a você implementar uma alternativa para docker-compose.

Obviamente não quero um forker docker compose, se é isso que você está sugerindo, especialmente para um aprimoramento tão minucioso. Essa é a única outra maneira de isso acontecer, e isso seria ruim para a comunidade.

Se alguém enviar um PR, ele seria realmente considerado? Ou isso é algo que a equipe docker-compose decidiu firmemente que não vai aceitar? Você consideraria algo próximo a adicionar uma seção de configuração compatível com as configurações de pilha do docker ?

Isso saiu dos trilhos ... 'anti-padrão' sem explicação transforma 'anti-padrão' em uma definição muito ampla que é impossível argumentar contra. Também não há uma direção clara de que lado o 'antipadrão' fica; docker ou docker-compose.

Uma definição clara das respostas anti-padrão seria fantástica e muito apreciada.

A comunidade vai continuar a crescer, então um conjunto estabelecido de definições precisa existir.

Quero usá-lo para copiar artefatos gerados por um pipeline jenkins em execução em uma pilha de composição do docker. E então, o nome do contêiner pode ser aleatório, então não posso usar docker cp .

Hoje devo usar

docker cp $(docker-compose -f docker-compose.development.ci.yml ps -q test):/app/tests_output ./tests_output

Isso é diferente de volumes: - ./folder_on_host/ :/folder_in_container/ ?
Posso copiar arquivos do host para o contêiner (equivalente a COPY) dessa forma no meu arquivo de composição

Estou tentando fazer o mesmo. Tenho uma pasta com um arquivo csv e gostaria de fornecê-lo ao logstash.
Como eu posso fazer isso. ou qual pasta no container?
no momento eu tenho algo assim:
./path/to/storage:/usr/share/logstash/ data: ro

Quaisquer sugestões seriam úteis

@ shin- Este bilhete agora tem 1,5 anos. Quando 160 pessoas dizem que você está errado - provavelmente está.

O que mais você precisa para se convencer de que isso deve ser implementado?

@isapir , as empresas que não ouvem seus clientes, tendem a sair do mercado em breve. Portanto, acho que devemos ver algumas alternativas de docker prontas para produção em um futuro próximo.

@ shin- Este bilhete agora tem 1,5 anos. Quando 160 pessoas dizem que você está errado - provavelmente está.

😆 🤣 💯 🥇 😲 😮

Além disso,

Não sou mais um mantenedor. Por favor, pare de me fazer @ -ing sobre coisas sobre as quais não tenho mais controle.

@sfuerte Existe um pequeno projeto chamado Kubernetes que já substituiu o Docker-Compose. Eu me pergunto se isso teria acontecido se a atitude em relação ao feedback do usuário fosse mais positiva.

Precisamos de uma palavra da moda para combater suas palavras da moda. É tudo com que eles podem lidar.

Este recurso seria totalmente pro-pattern . Isso deve resolver. A diferença é que, embora eu tenha feito essa coisa estúpida, há muitos comentários nesta edição mostrando as vantagens disso de maneiras que são claramente casos de uso comuns. E não há uma única instância de anti-pattern .

@ shin- você foi marcado nisso porque começou essa porcaria antipadrão sem base na realidade. Portanto, pare de chorar por algo que você causou.

k divirta-se

Meu caso é:

  • Durante o "dev", quero que meu código-fonte seja construído como "volume" para que ele seja atualizado automaticamente durante o desenvolvimento
  • Quando o aplicativo estiver pronto para lançamento e eu precisar "implantar", quero copiar os arquivos copiados em vez de serem volumes.

Acho que a maneira mais fácil de resolver isso é ter 1 arquivo de composição para dev e 1 arquivo de composição para produção.

O problema aqui é que posso especificar "volumes" no arquivo docker, mas não consigo especificar "copiar" no arquivo docker.

Alguém está no mesmo caso que eu? Estou esquecendo de algo?

@ shin- isso é um anti-padrão? como você resolveria esse problema?

@hems , em um mundo perfeito, você deseja que seu aplicativo seja implantado como uma imagem docker independente. Portanto, se você estiver escrevendo um aplicativo, o código-fonte que pretende implantar provavelmente deve fazer parte do Dockerfile , de modo que a imagem contenha todo o seu aplicativo. Então, em Dockerfile , se você quisesse sua fonte em / var / www, você colocaria

COPY my-app-src /var/www

Sua fonte não é específica do ambiente, então ela pertence apenas à imagem do docker. Fácil.

A maioria de nós deseja incluir um arquivo de configuração específico do ambiente nos contêineres que fazem uma imagem existente funcionar bem com uma configuração docker-compose específica. E queremos ser capazes de fazer isso sem aumentar o volume de um arquivo pequeno ou rolar uma nova imagem.

Alguém da equipe docker-compose pode dar uma olhada séria e imparcial nisso e tirar um veredicto final (esperançosamente um que ignore todas as pessoas imaturas)? Este problema está aberto desde sempre. O resultado é importante, mas pessoalmente estou cansado de receber notificações.

COPY my-app-src /var/www

é isso que estou dizendo, no desenvolvimento eu quero usar meu arquivo docker-compose para montar VOLUMES nas imagens e durante a compilação de produção eu quero COPIAR arquivos nas imagens, por isso acho que deveríamos ser capazes de COPIAR e montar VOLUMES usando o arquivo docker-compose, então posso ter 1 arquivo de composição para dev e 1 para construção de produção

Eu trabalho na equipe que mantém o Compose e estou feliz em entrar nesta discussão. Para começar, vou descrever como vemos as responsabilidades dos arquivos Dockerfiles e Compose.

Dockerfiles são a receita para a construção de imagens e devem adicionar todos os binários / outros arquivos de que você precisa para fazer seu serviço funcionar. Existem algumas exceções: segredos (por exemplo: credenciais), configurações (por exemplo: arquivos de configuração) e dados de estado do aplicativo (por exemplo: seus dados de banco de dados). Observe que segredos e configurações são somente leitura.

Os arquivos de composição são usados ​​para descrever como um conjunto de serviços são implantados e interagem. O formato Compose é usado não apenas para um único mecanismo (ou seja: docker-compose ), mas também para ambientes orquestrados como Swarm e Kubernetes. O objetivo do formato Compose é tornar mais fácil escrever um aplicativo e testá-lo localmente e, em seguida, implantá-lo em um ambiente orquestrado com poucas ou nenhuma alteração. Esse objetivo limita o que podemos alterar no formato devido a diferenças fundamentais, como a forma como cada ambiente lida com volumes e armazenamento de dados.

Cortar as responsabilidades do Dockerfile e do arquivo Compose dessa forma nos dá uma boa separação de preocupações: O que há em cada imagem de contêiner (Dockerfile), como os serviços são implantados e interagem (arquivo Compose).

Agora, examinarei cada uma das exceções ao que você armazena em uma imagem. Para segredos, você não os quer embutidos em imagens, pois podem ser roubados e porque podem mudar com o tempo. Os segredos do Docker são usados ​​para resolver isso. Eles funcionam de maneira um pouco diferente dependendo de qual ambiente você implanta, mas essencialmente a ideia é que você pode armazenar credenciais em um arquivo que será montado somente para leitura em um diretório tmpfs no contêiner em tempo de execução. Observe que este diretório sempre será /run/secrets/ e o arquivo terá o nome do segredo. Os segredos são compatíveis com Swarm, apenas mecanismo ( docker-compose ) e Kubernetes.

Para arquivos de configuração ou dados de bootstrap, há Docker Configs . Eles funcionam de forma semelhante aos segredos, mas podem ser montados em qualquer lugar. Eles são compatíveis com Swarm e Kubernetes, mas não com docker-compose . Acredito que devemos adicionar suporte para eles e isso ajudaria com alguns dos casos de uso listados nesta edição.

Finalmente, há dados de estado do aplicativo que precisam ser armazenados externamente. Não vou me aprofundar nisso, pois não está relacionado a esse problema.

Com esse enquadramento, posso responder a algumas perguntas:

  • Vamos adicionar um campo copy ao formato Compose? Não, acho que não, pois não faz sentido em ambientes orquestrados.
  • Vamos adicionar suporte de configs a docker-compose ? Sim, acho que devemos.
  • Vamos adicionar um docker-compose cp ? Talvez eu não tenha certeza sobre isso ainda. Seria essencialmente um apelido para docker container cp .

Dado isso, existem algumas ferramentas que podem ser usadas aqui:

  • Compilações de vários estágios que permitem adicionar arquivos condicionalmente a uma imagem usando destinos.
  • Segredos que permitem que você passe credenciais para um serviço em tempo de execução.
  • Configs que permitem que você passe informações de configuração para um serviço em tempo de execução.

_Acho_ que essas ferramentas resolvem todos os problemas levantados neste tópico.

Este segmento está bastante aquecido. Lembre-se de que há uma pessoa real por trás de cada identificador do GitHub e que provavelmente ela está tentando fazer o melhor (mesmo que esteja mostrando sua frustração). Todos nós somos apaixonados pelo Compose e queremos que o projeto continue prosperando.

Vamos adicionar um docker-compose cp ? Talvez eu não tenha certeza sobre isso ainda.

eu consideraria uma conveniência útil como docker-compose exec .

@ chris-crone Resposta incrível, obrigado!

Sei que não falo por todos , mas tenho a impressão de que o suporte de configs satisfaz a grande maioria dos interesses aqui. Deve ser aberto um problema para isso?

E obrigado por oferecer algumas abordagens alternativas. Eu não sabia sobre construções de vários estágios até agora.

Tenho a impressão de que o suporte de configs satisfaz a grande maioria dos interesses aqui.

Eu duvido disso, pois suspeito que a maioria aqui não está usando Swarm e afaik a funcionalidade config requer isso.

Sim, atualmente o Swarm é necessário, mas a partir do comentário de @chris-crone ...

Eles são compatíveis com Swarm e Kubernetes, mas não com docker-compose. Acredito que devemos adicionar suporte para eles e isso ajudaria com alguns dos casos de uso listados nesta edição.

... Estou lendo que isso pode ser implementado em docker-compose (sans Swarm)

O objetivo do formato Compose é tornar mais fácil escrever um aplicativo e testá-lo localmente e, em seguida, implantá-lo em um ambiente orquestrado com poucas ou nenhuma alteração.

Em aplicativos complexos, podemos ter alguns arquivos de configuração que precisam de ajustes dinâmicos. No momento, a maneira mais eficiente (em termos de tempo e custo) de fazer isso é preencher a chave dos volumes (porque nenhuma pessoa sã vai criar uma imagem diferente enquanto testa várias configurações ... a menos que tenham um chefe que adore gastar dinheiro em horas de desenvolvimento).

Swarm e config não vão realmente responder a vários dos casos de uso listados. "Separação de interesses" também não é aplicável, pois o compor já faz o que você pode fazer no docker, mas o simplifica. Um invólucro não é separação ... estamos apenas pedindo que você o estenda um pouco mais ...

https://github.com/docker/compose/issues/6643

Seja hacky com isso .. estenda a funcionalidade de volume onde cada arquivo sob a nova chave é dinamicamente vinculado a um único volume e mapeado para seus respectivos caminhos internos ...

Acho que há dois cenários aqui que são perfeitamente válidos, um é sobre
ambientes de desenvolvimento. As pessoas criam ambientes flexíveis com fonte
código montado em suas imagens. O código-fonte evolui conforme o desenvolvimento
ocorre e você não pode reconstruir a imagem constantemente ou você apenas desperdiça
enormes quantidades de tempo. Esse é exatamente o meu cenário e posso ver que este
cenário se aplica a muitas outras pessoas.

O segundo é sobre imagens de produção onde você prepara seu código-fonte
(caso você esteja trabalhando com scripts não compilados) em sua imagem (e
então, de novo, eu não estava, eu ainda estava montando do meu lado) ou você apenas
compile seu aplicativo e copie-o na imagem final. Nesse ponto,
o aplicativo se torna extremamente portátil.

Acho que todo mundo entende isso! A questão é, faça o docker-compose
dev teve tempo para ler os casos e entender as necessidades? tem
nenhum antipadrão aqui em teoria, apenas desenvolvedores que precisam e gostariam
para ser respeitado.

Amamos docker, docker-compose e todo o ecossistema, usamos porque
adoro e porque nós o usamos, vocês têm empregos (pelo menos alguns de vocês são pagos
por isso, espero).

Algo que aprendi nos últimos anos e que gosto de trazer aqui e
existe o seguinte e se aplica muito bem a este cenário:

Não é o que seu software faz que importa, é o que seus usuários fazem
com isso que importa

Saudações e feliz continuidade!

Na quinta-feira, 6 de junho de 2019 às 10:55, jadon1979 [email protected] escreveu:

O objetivo do formato Compose é facilitar a escrita de um aplicativo
e testá-lo localmente e, em seguida, implantá-lo em um ambiente orquestrado com
pouca ou nenhuma mudança.

Em aplicativos complexos, podemos ter alguns arquivos de configuração que precisam
ajustes on-the-fly. No momento, a maneira mais eficiente (tempo e custo) de
fazer isso é preencher a chave de volumes (porque nenhuma pessoa sã vai
para criar uma imagem diferente ao testar várias configurações .. a menos
eles têm um chefe que adora gastar dinheiro em horas de desenvolvimento).

Swarm e config não vão realmente responder a vários dos casos de uso
listados. "Separação de interesse" também não é aplicável como já compor
faz o que você pode fazer no docker, mas o simplifica. Um invólucro não é
separação ... estamos apenas pedindo que você estenda um pouco mais ...

6643 https://github.com/docker/compose/issues/6643

Seja hacky com isso .. estenda a funcionalidade de volume onde cada arquivo sob o
nova chave é dinamicamente ligada a um volume singular e mapeada para seus
respectivos caminhos internos ...

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=ABBR3OMQH62242SM4QN5Y7TPZEQP7A5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXDDP4Q#issuecomment-499529714 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ABBR3OMOZFZ47L6ITHPF2TDPZEQP7ANCNFSM4EKAVONA
.

Quero ativar um ambiente do docker Tomcat para executar meu aplicativo a partir de um .war que não é denominado ROOT.war . Para fazer isso, tenho que copiá-lo para o dir do Tomcat webapps e renomeá-lo para ROOT para que ele seja executado nas portas 8005/9 atualmente vinculadas. Qualquer outra coisa falha devido a problemas de religação nas portas com erros sobre 'acesso ilegal'. Essas são compilações de teste efêmeras, portanto, não podem ir para o Dockerfile. É por isso que o quero em docker-compose

@washtubs

Eu sei que não falo por todos, mas tenho a impressão de que o suporte a configs satisfaz a grande maioria dos interesses aqui. Deve ser aberto um problema para isso?

Se ainda não houver um problema para isso, crie um e vincule-o aqui. Eu adicionei algo em nosso rastreador de equipe particular.

@washtubs @funkyfuture

... Estou lendo que isso pode ser implementado em docker-compose (sans Swarm)

Já temos suporte secreto rudimentar e as configurações podem ser implementadas de maneira semelhante.

Definitivamente, um recurso ausente. O único "antipadrão" é quando você tem que contornar o fato de que isso é difícil de fazer por outros meios, como, por exemplo, alterar o script de ponto de entrada do dockerfile ou vincular arquivos de montagem ao contêiner.

O que você quer é um contêiner que seja construído uma vez, de preferência oficialmente) e configurável para o caso de uso, no ponto de uso, ou seja, docker-compose.

Pelo que eu posso ver, o que o pessoal do docker não consegue perceber é que o "Dockerfile" é o maior antipadrão em todo o conceito do docker, especialmente porque a coisa toda é totalmente ilegível e insustentável. Realmente me faz rir quando alguém conectado com docker joga fora a palavra "antipadrão" como eles deveriam saber!

O Dockerfile na verdade evita a depuração normal e limpeza que estaria disponível se você usasse um script de construção ou algo realmente projetado para construir coisas, como ... um gerenciador de pacotes ou make.

Para mim, eu uso o mesmo DockerFile para todos os casos de uso (tornando-o um padrão!), Sugerindo que eu vá e mude meu DockerFile para cada uso diferente, realmente é um antipadrão.

E nenhum "suporte a configurações" não o corta de forma alguma, impondo uma estrutura onde simplesmente não é necessário.

O problema fundamental é que se você vincular o mount a dizer / etc / nginx, ele precisa ser rw para permitir a execução de scripts que ajustam as configurações (também conhecido como envsubst). E isso então muda a configuração de entrada (que precisa permanecer imutável) ... Você não obtém muito mais antipadrão do que um contêiner escrevendo em toda a sua configuração, então uma opção para copiar arquivos para o contêiner no momento da recriação é o necessário solução.

Em outras palavras, é um diretório de montagem de ligação rw no contêiner, mas ro no host. Sério, te mataria permitir isso?

Definitivamente, um recurso ausente. O único "antipadrão" é quando você tem que contornar o fato de que isso é difícil de fazer por outros meios, como, por exemplo, alterar o script de ponto de entrada do dockerfile ou vincular arquivos de montagem ao contêiner.

O que você quer é um contêiner que seja construído uma vez, de preferência oficialmente) e configurável para o caso de uso, no ponto de uso, ou seja, docker-compose.

Pelo que eu posso ver, o que o pessoal do docker não consegue perceber é que o "Dockerfile" é o maior antipadrão em todo o conceito do docker, especialmente porque a coisa toda é totalmente ilegível e insustentável. Realmente me faz rir quando alguém conectado com docker joga fora a palavra "antipadrão" como eles deveriam saber!

O Dockerfile na verdade evita a depuração normal e limpeza que estaria disponível se você usasse um script de construção ou algo realmente projetado para construir coisas, como ... um gerenciador de pacotes ou make.

Para mim, eu uso o mesmo DockerFile para todos os casos de uso (tornando-o um padrão!), Sugerindo que eu vá e mude meu DockerFile para cada uso diferente, realmente é um antipadrão.

E nenhum "suporte a configurações" não o corta de forma alguma, impondo uma estrutura onde simplesmente não é necessário.

O problema fundamental é que se você vincular o mount a dizer / etc / nginx, ele precisa ser rw para permitir a execução de scripts que ajustam as configurações (também conhecido como envsubst). E isso então muda a configuração de entrada (que precisa permanecer imutável) ... Você não obtém muito mais antipadrão do que um contêiner escrevendo em toda a sua configuração, então uma opção para copiar arquivos para o contêiner no momento da recriação é o necessário solução.

Em outras palavras, é um diretório de montagem de ligação rw no contêiner, mas ro no host. Sério, te mataria permitir isso?

Algo assim:

`` `

se o arquivo então sobrescrever

se o diretório, então, sobrescrever / anexar o conteúdo do destino

com conteúdo da fonte para manter a estrutura de destino original

fonte: arquivo : permissão: proprietário : grupo

svc:
cópia de:
- './source/filename:/path/ filename: ro : www-data'
- './source/dir:/path/ dir: ro : www-data'

# ou
svc:
cópia de:
- fonte: './source/file'
destino: '/ destino'
permissão: ro
dono: dono
grupo: grupo
- fonte: './source/directory'
destino: '/ destino'
permissão: ro
dono: dono
group: group```

Caso de uso: temos uma solução de contêiner não orquestrada onde temos os arquivos docker-compose de nosso aplicativo incl. Certificados SSL etc. dentro de um repositório Git e puxando-o para uma VM. Em seguida, ativamos o serviço e queremos mover, por exemplo, os certificados SSL, arquivos de configuração etc. para o volume do contêiner. Atualmente, isso não é possível sem um Dockerfile que o acompanha com um comando COPY em destaque. Não queremos mexer nos arquivos dentro do repositório git clonado. Se o aplicativo alterasse os arquivos, teríamos que limpar o repo todas as vezes.

@MartinMajewski então você pode montar o diretório com certificados como volume e apontá-lo na configuração do seu aplicativo.

Caso de uso (e pergunta de como fazer de uma vez):
Tenho postgres imagem com uma única variável de ambiente a ser definida no início: POSTGRES_PASSWORD . Quero defini-lo por meio do Docker Secret. O que eu preciso fazer é colocar meu próprio entrypoint.sh que exportará o segredo anexado para env var do contêiner em execução. Preciso adicionar este ponto de entrada de alguma forma em meu contêiner no lançamento. Sem Dockerbuild de duas linhas - não posso. Cópia de um único arquivo - não pode ser feito.

PS postgres é um exemplo. Suponha que ele não suporte _FILE env vars.

Problema de rastreamento interno https://docker.atlassian.net/browse/COMPOSE-89

Caso de uso: Karaf
Usando uma imagem de base de karaf que não desejo reconstruir toda vez que construo meu projeto, quero poder implantar meu aplicativo rapidamente e reconstruir o contêiner para cada construção. No entanto, preciso copiar um _features.xml_ e _jar_ para o diretório de implantação ao iniciar o contêiner.

Minha solução até agora era usar a imagem karaf como uma imagem base em outro Dockerfile (contando com overlayfs - que fica sem sobreposições eventualmente, forçando uma exclusão manual da imagem) e avast / gradle-docker-compose-plugin. Embora os comandos init certamente possam ser passados ​​como uma variável de ambiente, o conteúdo do features.xml não pode. Ele deve ser armazenado como um arquivo em um local específico no contêiner. No momento, só posso usar uma montagem de ligação de volume para fazer isso. Como coloco as coisas nesse volume em uma máquina remota? Eu preciso de mais lógica em meu script de construção (por exemplo, org.hidetake.groovy.ssh, que também complica o script de construção com senha secreta / lógica de chave). Se um cp docker-compose estivesse disponível, eu poderia simplesmente adicionar o comando de cópia necessário ao docker-compose.yml. O avast / gradle-docker-compose-plugin cuidaria da construção do contêiner e da cópia dos arquivos da minha saída de construção diretamente para o contêiner, sem nenhuma lógica extra de acesso ao sistema de arquivos remoto.

Este Dockerfile é adicionado à minha parte de compilação docker-compose.yml do script. No mínimo, este é um antipadrão, porque apenas adiciona sobreposições à imagem docker upstream com cada compilação (até que eu seja forçado a excluir manualmente a imagem - o que torna as compilações muito mais lentas).

FROM myregistry:443/docker/image/karaf-el7:latest

COPY karafinitcommands /usr/local/karaf/etc/

COPY features.xml \
     *.jar \
     /usr/local/karaf/deploy/

Acho frustrante que docker cp funcione bem para cópia em tempo de execução, mas docker-compose não tem mecanismo equivalente.

Achei que a ideia era vincular a montagem de um diretório local a / usr / local / karaf / deploy e colocar seus arquivos lá. Eu não esperaria ter que reconstruir a imagem ou usar um arquivo docker para obter isso.

Achei que a ideia era vincular a montagem de um diretório local a / usr / local / karaf / deploy e colocar seus arquivos lá. Eu não esperaria ter que reconstruir a imagem ou usar um arquivo docker para obter isso.

Certamente é alcançável dessa forma. Releia e observe que este é puramente um problema de conveniência: O contêiner é reconstruído pela compilação do Gradle, a próxima etapa lógica é: Como movo os novos arquivos de compilação para o "diretório local" montado em / usr / local / karaf / deploy? No meu caso, um "diretório local" é mais precisamente um "diretório de host" em que o host é um host remoto. Portanto, tenho que adicionar rsync ou qualquer outra coisa ao meu script de construção apenas para obter os arquivos lá e garantir que os antigos sejam substituídos e os extras removidos. Seria desnecessário se docker-compose cp estivesse disponível. Eu poderia utilizar meu cliente docker existente para a conexão docker daemon, que configurei por meio do encaminhamento de porta.

Os volumes do Docker podem ser removidos com cada construção. Os volumes de montagem Bind não podem. Eles serão preenchidos novamente apenas se estiverem vazios (mecanismo de proteção de persistência). Claro, esvaziar uma montagem de ligação em uma máquina remota requer certas permissões e lógica de acesso que podem ser evitadas com um cp docker-compose.

Novamente, uma cópia em um ambiente de tempo de execução pode ser obtida com docker cp. Essa é a parte frustrante.

Ah, ok, estou muito acostumado com minha própria configuração. Eu uso http://github.com/keithy/groan um script bash que implanta os bits e peças em servidores remotos e, em seguida, invocamos o docker.

Caso de uso: Google Cloud Build e artefatos de construção

Artefato necessário: o cliente da web (gerado automaticamente) reage às ligações do graphql. Você precisa do servidor em execução para criar os arquivos necessários para a compilação do cliente. A imagem do cliente possui as ferramentas para criar as ligações, dado um endereço de servidor. Portanto, você inicia a imagem do servidor no fundo e agora precisa executar o contêiner do cliente apontando para o servidor. Agora, como retirar os arquivos gerados do contêiner e colocá-los no diretório de host do "espaço de trabalho"? A montagem de diretórios não é permitida, pois você está em um diretório montado em um contêiner docker. Ser capaz de docker-compose cp aliviaria a dolorosa etapa de obter a identificação do contêiner.

Contar com $(docker-compose ps -q SERVICE) para direcionar o contêiner certo torna possível usar docker cli simples para tais operações centradas no contêiner. A introdução de um novo comando certamente o tornaria mais simples para os poucos casos de uso que o solicitarem, mas não é obrigatório. Para evitar mais duplicação de código entre compose e docker CLI, acho que esse problema deve ser resolvido.

Há um problema aberto em que o cache de compilação entre compose e plain docker é diferente, devido à versão do docker daemon compose que está usando, o que significa que você precisa usar pure compose para não quebrar caches em ambientes CI (https: // github .com / docker / compose / issues / 883) até que esses problemas sejam resolvidos, misturar comandos docker simples com comandos de composição quebra os caches. A configuração de composição especifica todos os tipos de configuração incorporada, eliminando a necessidade de especificar manualmente a configuração duplicada com comandos docker simples.

Contar com $(docker-compose ps -q SERVICE) para direcionar o contêiner certo torna possível usar docker cli simples para tais operações centradas no contêiner. A introdução de um novo comando certamente o tornaria mais simples para os poucos casos de uso que o solicitarem, mas não é obrigatório. Para evitar mais duplicação de código entre compose e docker CLI, acho que esse problema deve ser resolvido.

Isso é muito mais profundo do que "Poucos casos de uso mencionados" porque esses cenários são bastante comuns e modificar, construir imagem, modificar novamente, construir imagem, etc. é um desperdício de tempo em relação à capacidade de lidar com essas coisas por meio do docker-compose. O argumento "você pode fazer isso no docker cli, então faça lá" praticamente anula várias outras coisas que foram adicionadas ao docker-compose.

Esta edição está aberta há quase um ano e existem inúmeras outras discussões sobre ela fora desta edição. Definitivamente, não deve ser fechado a menos que seja realmente resolvido.

@dionjwa # 883 realmente precisa ser investigado (se ainda for relevante), pois docker-compose deve estar alinhado com docker CLI.

@ jadon1979 Não estou tentando bloquear esta solicitação de recurso, apenas notei que ela foi aberta há mais de 1 ano e nenhum dos principais mantenedores considerou importante o suficiente para introduzir um novo comando, nem um contribuidor propôs um PR para isto.
Só estou dizendo que, de acordo com o feedback sobre esta solicitação de recurso, e a falta de esforço de desenvolvimento para oferecer uma "maneira melhor", a solução alternativa proposta para usar uma combinação de docker-compose e docker cli, que você pode facilmente criar um alias em seu ambiente para mantê-lo simples de usar, é uma solução alternativa razoável.
Agora, se alguém abrir um PR para oferecer um novo comando cp , ficarei feliz em revisá-lo.

Ninguém contribuiu porque todos foram informados de que cada caso de uso era um
anti-padrão. E a cada poucos dias temos novos casos de uso postados, nenhum
anti-padrões.

Na segunda-feira, 18 de novembro de 2019 às 17:31 Nicolas De loof [email protected]
escrevi:

@dionjwa https://github.com/dionjwa # 883
https://github.com/docker/compose/issues/883 realmente precisa ser
investigado (se ainda for relevante) como docker-compose deve estar alinhado com
docker CLI.

@ jadon1979 https://github.com/jadon1979 Não estou tentando bloquear isso
pedido de recurso, acabei de notar que foi aberto há mais de 1 ano, e
nenhum dos principais mantenedores considerou importante o suficiente para
introduzir um novo comando, nem um colaborador propôs um PR para ele.
Só estou dizendo que, de acordo com o feedback sobre esta solicitação de recurso,
e falta de esforço de desenvolvimento para oferecer um "caminho melhor", a proposta
solução alternativa para usar uma combinação de docker-compose e docker cli, que você
pode facilmente criar um alias em seu ambiente para mantê-lo simples de usar, é um
solução alternativa razoável.
Agora, se alguém abrir um PR para oferecer um novo comando cp, eu ficaria feliz em
revê-lo.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=AAGRIF2NS64IYANNVTGFTULQUL3TZA5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEELZ6CQ#issuecomment-555196170 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/AAGRIFY7CULCUS3TDDTTHZLQUL3TZANCNFSM4EKAVONA
.

Meu caso de uso não é copiar coisas _para_ um contêiner, mas sim copiá-las _para fora_ do contêiner depois de executado. Isso pode ser feito a partir da CLI usando uma solução alternativa desajeitada que produz uma funcionalidade possivelmente degradada . Detalhes completos abaixo.

Sou um engenheiro de DevOps e confio muito em contêineres como uma alternativa ao inferno de dependência de agentes de construção bare-metal. Quando meu sistema de CI testa um repo, ele começa construindo a partir de um Dockerfile dentro desse mesmo repo e executando todas as verificações ( bundle exec rspec , npm test , etc) _inside the container_. Se houver artefatos de construção criados como documentação ou resultados de teste, simplesmente copio-os do contêiner com docker cp .

Para testes de integração, começamos a usar docker-compose para fornecer dependências de serviço (por exemplo, um servidor de banco de dados) para o contêiner que executa os testes. Infelizmente, a "solução alternativa do docker CLI" é menos útil neste caso para copiar arquivos.

Considere esta configuração: docker-compose-minimal.yml

version: "3"
services:
  artifact-generator:
    image: busybox

Vou criar o contêiner, executar um comando nesse contêiner, obter o ID do contêiner e tentar extrair o arquivo usando docker cp

$ # Prepare the images and (stopped) containers.  In this case there is only one.
$ docker-compose --file docker-compose-minimal.yml up --no-start
Creating network "docker-compose-cp-test_default" with the default driver
Creating docker-compose-cp-test_artifact-generator_1 ... done
$ # Determine the ID of the container we will want to extract the file from
$ docker-compose --file docker-compose-minimal.yml ps -q artifact-generator
050753da4b0a4007d2bd3514a3b56a08235921880a2274dd6fa0ee1ed315ff88
$ # Generate the artifact in the container
$ docker-compose --file docker-compose-minimal.yml run artifact-generator touch hello.txt
$ # Check that container ID again, just to be sure
$ docker-compose --file docker-compose-minimal.yml ps -q artifact-generator
050753da4b0a4007d2bd3514a3b56a08235921880a2274dd6fa0ee1ed315ff88
$ # OK, that looks like the only answer we're going to get.  Can we use that to copy files?
$ docker cp $(docker-compose --file docker-compose-minimal.yml ps -q artifact-generator):hello.txt ./hello-artifact.txt
Error: No such container:path: 050753da4b0a4007d2bd3514a3b56a08235921880a2274dd6fa0ee1ed315ff88:hello.txt
$ # Nope.  Let's take a look at why this is
$ docker container ls -a
CONTAINER ID        IMAGE                        COMMAND                   CREATED              STATUS                          PORTS               NAMES
9e2cb5d38ba0        busybox                      "touch hello.txt"         About a minute ago   Exited (0) About a minute ago                       docker-compose-cp-test_artifact-generator_run_dd548ee686eb
050753da4b0a        busybox                      "sh"                      2 minutes ago        Created                                             docker-compose-cp-test_artifact-generator_1

Como você pode ver, docker-compose ps realmente não tem conhecimento do ID do contêiner atualizado. Isto é um infortúnio. Isso não seria tão ruim se houvesse uma maneira de eu saber que run_dd548ee686eb está de alguma forma relacionado aos docker-compose run que executei, mas não vejo como fazer isso.

Há uma solução alternativa desajeitada para essa solução alternativa, que é adicionar --name ao comando de execução:

$ docker-compose --file docker-compose-minimal.yml run --name blarg artifact-generator touch hello.txt
$ docker cp blarg:hello.txt ./hello-artifact.txt
$ ls 
docker-compose-minimal.yml  hello-artifact.txt

Sucesso! ... meio

O problema aqui é que, se eu tiver várias compilações em execução em paralelo, preciso me dar ao trabalho de tornar --name s globalmente exclusivos. Caso contrário, terei colisões barulhentas no melhor caso e resultados corrompidos (sem erro, mas extraído o arquivo errado) no pior caso. Portanto, isso é complicado porque agora tenho que reinventar a geração de IDs de contêiner, em vez de apenas usar aquele que o Docker já criou.

No mínimo, gostaria de saber de alguma forma a ID do contêiner que resulta do comando docker-compose run .

@ndeloof

Contar com $ (docker-compose ps -q SERVICE) para direcionar o contêiner correto torna possível usar docker cli simples para tais operações centradas no contêiner.

Falso, veja a demonstração no comentário anterior.

Teremos novos casos de uso por anos aqui. Espere, quero dizer novo anti
padrões ...

Na sexta-feira, 13 de dezembro de 2019, 11h40, Ian, [email protected] escreveu:

@ndeloof https://github.com/ndeloof

Contando com $ (docker-compose ps -q SERVICE) para direcionar o contêiner certo
possibilitar o uso de docker cli simples para tais
operações.

Falso, veja a demonstração no comentário anterior.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=AAGRIF2NFPTKY3QKRIXQ5RTQYONHLA5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEG2E7QQ#issuecomment-565465026 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/AAGRIF3S4UHF5NG3VKYXJB3QYONHLANCNFSM4EKAVONA
.

Quem podemos mencionar para chegar aos mantenedores? Esse assunto é inútil até que comecem a falar conosco. Pode ser simples "isso não pode ser feito devido à arquitetura de software atual", qualquer coisa. Mas deixar esses problemas inertes não é algo que você gostaria de ver nesta solução altamente popular como o Docker ...

Nossa implantação cria a imagem do Docker com o bazel, faz o upload para o Docker Registry e, em seguida, usa os recursos do Terraform docker_container com upload estrofes para copiar os arquivos de configuração para o contêiner. Preciso migrar este processo de implantação para usar docker-compose em vez do Terraform. Estou surpreso que docker-compose não forneça nenhuma função para configuração por contêiner.

Esta edição está aberta há 2 anos. É por isso que o Kubernetes está ultrapassando o Docker em popularidade? O Kubernetes fornece funções de configuração e segredos. Equipe do Docker, pelo menos adicione a funcionalidade de configuração.

tbf docker-compose não é exatamente comparável ao k8s e não é recomendado para uso em produção. Destina-se ao desenvolvimento e teste rápido. docker swarm é algo a ser comparado ao k8s e, embora também seja muito simplista, possui recursos como configurações e segredos.

Se for apenas para desenvolvimento, esse é ainda mais motivo para esse problema
Deveria trabalhar. As regras "anti-padrão" de baixa qualidade nem deveriam ser assim
importante (digo péssimo porque é evidente pela abundância de uso normal
casos em que não é nada semelhante a um antipadrão).

Na terça, 3 de março de 2020 às 12h56 David Milum [email protected]
escrevi:

tbf docker-compose não é exatamente comparável ao k8s e não é recomendado
para uso em produção. Destina-se ao desenvolvimento e teste rápido. docker
enxame é a única coisa a comparar com k8s e embora também seja muito
simplista, possui recursos como configurações e segredos.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/docker/compose/issues/5523?email_source=notifications&email_token=AAGRIFZTKGRWMZZ5H6DG3FDRFUSEJA5CNFSM4EKAVONKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENUBMTQ#issuecomment-594024014 ,
ou cancelar
https://github.com/notifications/unsubscribe-auth/AAGRIF4NTQQSR2QQWPJT6PLRFUSEJANCNFSM4EKAVONA
.

Outro "anti-padrão":

Eu uso docker-compose para orquestração de contêineres durante o desenvolvimento local e k8s para produção.

Seguindo o conselho de Docker , implementei o script wait-for-it.sh para gerenciar a ordem de inicialização / desligamento do serviço.

Do jeito que está, a menos que eu queira montar um volume em cada serviço apenas para este arquivo, isso requer uma cópia do script em cada diretório contendo o Dockerfile de cada serviço.

Em vez disso, gostaria de manter uma única cópia do script wait-for-it em um diretório de nível superior que docker-compose então copia em cada contêiner ao ser executado localmente, já que tais questões são gerenciadas de outra forma em k8s, o que significa que não quero que essas preocupações poluam os Dockerfile s dos meus serviços.

Como Emerson escreveu certa vez: "Uma consistência tola é o duende das mentes pequenas, adorado por pequenos estadistas, filósofos e teólogos."

Talvez seja hora de ouvir seus usuários ...

@Phylodome você não pode usar verificações de integridade do contêiner e docker-compose depends_on ? É assim que garanto dependências saudáveis ​​de inicialização de contêiner.

Meu entendimento é que wait-for-it.sh é realmente um hack, já que seus próprios serviços devem ser resilientes às dependências que vão e vêm. A inicialização é apenas um caso individual disso.

@ianfixes "Seus serviços" se referem aos próprios serviços docker-compose, ou "nossos" serviços, como nos serviços escritos por nós que usa docker-compose? Não sei se você está escrevendo na função de "usuário" ou de desenvolvedor docker-compose.

"Seus serviços" referem-se aos próprios serviços docker-compose, ou "nossos" serviços, como nos serviços escritos por nós que usa docker-compose?

Os serviços que você cria como desenvolvedor devem ser resilientes. Isso está de acordo com estes documentos: https://docs.docker.com/compose/startup-order/

O problema de esperar que um banco de dados (por exemplo) esteja pronto é realmente apenas um subconjunto de um problema muito maior de sistemas distribuídos. Na produção, seu banco de dados pode ficar indisponível ou mover hosts a qualquer momento. Seu aplicativo precisa ser resiliente a esses tipos de falhas.

Para lidar com isso, projete seu aplicativo para tentar restabelecer uma conexão com o banco de dados após uma falha. Se o aplicativo tentar a conexão novamente, ele poderá eventualmente se conectar ao banco de dados.

A melhor solução é fazer essa verificação no código do aplicativo, tanto na inicialização quanto sempre que uma conexão for perdida por qualquer motivo. No entanto, se você não precisa desse nível de resiliência, pode contornar o problema com um script de wrapper:

E continua mencionando vários scripts de espera.

Eu poderia fazer várias coisas. Mas porque isso é apenas para desenvolvimento local, e porque eu tenho outras estratégias para lidar com verificações de serviço de produção em k8s, eu preferiria a implementação local mais simples e menos intrusiva, não conselhos genéricos de pessoas que não sabem os detalhes do porquê eu ' gostaria de fazer isso (por exemplo, problemas com montagem de volume para executar o desenvolvimento da IU através do servidor de desenvolvimento do Webpack).

Em qualquer caso, é apenas mais um na longa lista de casos de uso para esse suposto recurso que deve ser deixado ao critério do usuário.

Estou ouvindo raiva dirigida a mim e entendo por que seria frustrante ouvir "conselhos" não solicitados sobre a sua abordagem. Mas nem tenho certeza de como me desculpar; Citei o texto do URL que você mesmo chamou de "conselho do Docker", que diz _explicitamente_ que o script de espera é uma maneira de "contornar o problema". Se valer a pena, sinto muito mesmo.

Você não está ouvindo raiva. Você está ouvindo o tom exasperado de alguém que, ao pesquisar no Google o que deveria ser um recurso bastante óbvio, tropeçou em um tópico de cem comentários no qual um conjunto de mantenedores continuamente patrocinou e rejeitou os apelos da comunidade por um recurso inteiramente válido.

Eu não compartilhei minha experiência aqui b / c eu queria um pedido de desculpas. Eu o compartilhei simplesmente para adicionar à longa lista de evidências de que os usuários do Docker gostariam de flexibilidade adicional ao usar compose .

Claro, como qualquer ferramenta, essa flexibilidade vem junto com o potencial de abuso. Mas esse mesmo potencial, se não potencial pior, existe quando seus usuários devem encontrar soluções alternativas para seus casos de uso específicos que poderiam ser resolvidos de forma muito mais simples apenas adicionando esse recurso.

Além disso, desculpar-se com a iluminação a gás de seus usuários é uma aparência ruim.

Não sou mantenedor nem contribuidor deste projeto e peço desculpas por qualquer confusão aí. Parece que a pouca assistência que achei que poderia oferecer era indesejada e inútil, e sinto muito por desperdiçar seu tempo.

Quero esse recurso para um contêiner Go que faz parte do meu aplicativo distribuído. Como o arquivo .env precisa ser incluído na raiz do aplicativo Go, precisarei criar um .env separado para ele ... Enquanto, se eu tivesse esse recurso, poderia tenho meu arquivo .env nível superior e copia-o no contêiner Go quando eu construir. Isso significaria menos coisas que eu preciso controlar ...

Minha solução alternativa poderia ser criar esse arquivo por meio do contêiner Go Dockerfile ou apenas fazer um arquivo .env para esse contêiner. Mesmo assim, sempre que eu adicionar um novo env var, precisarei atualizá-lo em, possivelmente, dois lugares. Bom caso de uso aqui. Ou eu poderia apenas usar um script de shell para cp o arquivo para mim ...

+1 para o recurso COPY

já conseguimos isso no Kubernetes com carros laterais, e existem MUITOS casos de uso. Este NÃO é um antipadrão, apenas um dos recursos que mantém a composição do docker de volta.

Talvez eu esteja faltando alguma coisa, mas agora, quando estamos construindo nosso aplicativo por 5 minutos, todo esse tempo a pasta de construção está "em fluxo", e o aplicativo não iniciará devido à inconsistência.
Eu preferiria _copiar_ uma pasta de construção em um contêiner, então, quando for hora de iniciar o contêiner, ele assumirá o interno. Dessa forma, o aplicativo fica offline apenas por um segundo ou mais, quando para / inicia o contêiner.

Como isso é um antipadrão quando docker já o suporta? Faz sentido que docker-compose siga a usabilidade do docker - não fazer isso é em si um antipadrão.

O problema com isso é que ele é incrivelmente míope (daí o termo "antipadrão"), pois vai forçar você a repetir a operação toda vez que os contêineres forem recriados. Sem mencionar o fato de que ele escala muito mal (e se você tiver 10 contêineres? 20? 100?)

Acho que isso depende do desenvolvedor. A simples cópia de um único arquivo de configuração local tem uma sobrecarga insignificante. Não culpe a faca.


PS Meu caso de uso; Quero adicionar uma configuração a um contêiner Nginx em um projeto sem Dockerfiles.

Quem ainda sabe mais.
Eu precisava configurar um novo projeto e procurei por novos
ferramentas, Lando é muito melhor do que isso é uma loucura. Queria ter usado
mais cedo.
É mais rápido, fácil de entender, melhor suporte pronto para uso e
não tem (ex) mantenedores / contribuintes condescendentes.

@ chris-crone em relação ao seu comentário ...

Para arquivos de configuração ou dados de bootstrap, há Docker Configs. Eles funcionam de forma semelhante aos segredos, mas podem ser montados em qualquer lugar. Eles são compatíveis com Swarm e Kubernetes, mas não com docker-compose. Acredito que devemos adicionar suporte para eles e isso ajudaria com alguns dos casos de uso listados nesta edição.

Docker-compose está interessado em implementar o suporte de configuração para paridade com configurações de enxame?

Se houver um tíquete para isso (ou se eu precisar fazer um que também esteja bom), gostaria de assiná-lo e cancelar a assinatura desse incêndio de lixo. Pessoalmente, eu fecharia isso e criaria um link para isso, mas sou só eu.

@harpratap você está certo, mas a desvantagem é que / folder_in_container não deve existir ou deve estar vazio ou então será sobrescrito. Se você tiver um script bash como seu ponto de entrada, você pode contornar isso vinculando simbolicamente seus arquivos ao diretório originalmente pretendido depois de criar um volume em / some_empty_location

1 por ter uma funcionalidade de CÓPIA. Nosso caso de uso é para criar ambientes de desenvolvimento local rapidamente e copiar em configurações para as configurações de desenvolvimento.

Exatamente. Nem todos nós escalamos da mesma maneira. Minha empresa usa SALT para construir os arquivos .conf necessários para uma variedade de aplicativos. Uma compilação - com o básico - então docker-compose para criar as instâncias individuais com base em suas partes exclusivas: endereço MAC, IP, porta, licenças, módulos, etc. PODERIA ser feito a partir de uma linha de comando - mas muito mais fácil e menos sujeito a erros do docker-compose.

Eu tenho um caso de uso. Temos uma versão de teste que requer a configuração de SSL. Os certificados são gerados por um serviço no docker-compose ... Eu, então, adiciono esses certificados aos contêineres do cliente ... se eu montar, eu perco os certificados existentes e não posso colocá-los na compilação do docker porque eles não ainda não existe.

Consequentemente, eu tenho que executar 2 docker-compose - 1 para iniciar os serviços para criar os certificados e, em seguida, outro para construir os serviços e executar os testes. Bagunçado.

Eu vi muitos problemas aqui, onde os usuários sugeriram muitos casos de uso para um recurso, mas eles foram rejeitados porque um mantenedor pensa, é um antipadrão ou as pessoas não o usariam ou alguma outra história .

Embora possa parecer um antipadrão para uma pessoa, tenho certeza de que as 1000 pessoas que solicitaram o recurso, que pensam o contrário, também precisam ser ouvidas. Se alguma ajuda for necessária para desenvolver o recurso, acho que muitas pessoas podem dar uma mão.

Meu caso de uso: além das configurações, tenho algumas bibliotecas (RPMs) que preciso instalar em 5 dos meus containers de aplicativos Rails (Debian). Versões diferentes de Ruby / Rails, portanto, não posso usar a mesma imagem de base, então devo ser capaz de armazenar os arquivos em um único local e copiá-los para um contêiner durante a construção, porque não quero baixar 1,5 GB de dados durante a construção.

@gauravmanchanda

Meu caso de uso: além das configurações, tenho algumas bibliotecas (RPMs) que preciso instalar em 5 dos meus containers de aplicativos Rails (Debian). Versões diferentes de Ruby / Rails, portanto, não posso usar a mesma imagem de base, então devo ser capaz de armazenar os arquivos em um único local e copiá-los para um contêiner durante a construção, porque não quero baixar 1,5 GB de dados durante a construção.

Você já olhou para compilações de vários estágios para isso? Acho que seria uma solução mais robusta.

As compilações de vários estágios permitem que você use o mesmo Dockerfile para várias imagens. Isso permite fatorá-los e incluir apenas os bits necessários em cada imagem.

Um bom exemplo é o que usamos para construir o Docker Compose . Isso constrói usando Debian ou Alpine, mas nos permite fatorar código comum.

Em nossa configuração, aumentamos cerca de uma dúzia de simuladores com docker-compose. Os simuladores são iguais, mas um arquivo init é diferente para cada destino e esse arquivo é consumido na inicialização (é excluído quando o servidor está instalado e funcionando). Você está realmente sugerindo que deveríamos criar cerca de uma dúzia de imagens quase idênticas apenas porque um arquivo é diferente? Isso não faz sentido IMO.

Com docker, o sinalizador --copy-service pode ser usado para fazer isso. Existe alguma alternativa que possamos usar com docker-compose?

Olá @megaeater ,

aumentamos cerca de uma dúzia de simuladores com docker-compose. Os simuladores são iguais, mas um arquivo init é diferente para cada destino e esse arquivo é consumido na inicialização (é excluído quando o servidor está instalado e funcionando).

Este é um caso de uso interessante; algumas perguntas: Esses simuladores (ou partes deles) já foram executados em produção (ou seja, não na máquina do desenvolvedor ou em um CI)? Se o código estiver aberto (ou um sistema semelhante estiver), você poderia me conectar a ele para que eu possa dar uma olhada?

Também seria interessante saber por que você quer uma cópia em vez de montagem de ligação ou um volume para esses arquivos?

Você está realmente sugerindo que deveríamos criar cerca de uma dúzia de imagens quase idênticas apenas porque um arquivo é diferente? Isso não faz sentido IMO.

As imagens são baseadas em camadas exatamente por este motivo: todas as imagens farão referência às mesmas camadas, exceto a camada que inclui os diferentes arquivos.

O problema com coisas como uma cópia na criação de contêiner é que isso torna difícil pegar o mesmo código e executá-lo na produção (ou seja, exigir uma grande reescrita lógica) porque o padrão será frágil ou impossível em ambientes orquestrados.

Isso não quer dizer que nunca devemos implementar algo assim no Compose. Em vez disso, quando uma mudança significa que os usuários não serão capazes de reutilizar algo que funciona localmente na produção, gostamos de fazer uma pausa e ver se existe uma maneira mais robusta de atingir o mesmo objetivo.

Obrigado pelo comentário @ chris-crone

Não estamos executando o docker em produção, é apenas para fins de desenvolvimento. O problema de usar volume (se bem entendi) é que o simulador (de terceiros) tem esse script de inicialização que exclui o arquivo na inicialização. A execução do script é interrompida se a exclusão falhar, portanto, precisaríamos montá-lo como rw. E se a exclusão do arquivo for permitida, precisaríamos ter um mecanismo para criar um diretório temporário para fornecer esses arquivos para que os originais não sejam excluídos. Portanto, precisaríamos de algum tipo de script estranho para aumentar a composição em cima do docker-compose.

@ chris-crone Obrigado pelos links. Vou dar uma olhada e ver se funciona para nós 👍

Ei @ chris-crone, eu tentei usar compilações em vários estágios e isso nos ajudou a manter as bibliotecas / configuração em apenas um local e copiá-las, mas agora há problemas com .dockerignore sendo ignorados, não importa onde Eu coloco.

Ele funciona quando estou apenas usando o Docker com a nova opção DOCKER_BUILDKIT , mas não funciona ao usar docker-compose, tentei COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose build , mas ainda não funcionou. Alguma ideia?

Eu estava me perguntando se havia uma opção para especificar onde procurar .dockerignore na composição, quando me deparei com este problema https://github.com/docker/compose/issues/6022 , que novamente, foi fechado, porque 1 contribuidor acha que isso não é útil.

Isso é muito frustrante se eu estiver sendo honesto aqui!

Isso é crítico no MacOS, porque obter seus ciclos de desenvolvimento o mais próximo possível da produção é de suma importância; obviamente para práticas adequadas de Entrega Contínua. por exemplo, construir o contêiner, mas então vincular a montagem da sua nova versão do software em que você está trabalhando atualmente no contêiner para economizar nos tempos de ciclo de construção. Infelizmente, montagens de bind são extremamente caras, sendo 3 a 5 vezes mais lentas.

Por exemplo, o tempo de inicialização do tomcat é cerca de 3s para meu aplicativo em um contêiner. Adicione uma montagem de ligação de ~ / .bash_history e é 4s. Adicione uma montagem de ligação do meu aplicativo e geralmente é cerca de 18-20s. No Linux, o desempenho da montagem de ligação é semelhante ao de um sistema de arquivos local, mas não no MacOS. Escale isso para 100 vezes por dia e isso é significativo.

Isso sem incluir a lentidão que continua ao acessar o aplicativo pela primeira vez; até que os arquivos de código sejam armazenados em cache. Para mim, isso significa 3 minutos, incluindo lag pela internet conectando-se ao oráculo db monolítico para mudar uma pequena frase para outra coisa, e ver se ainda está parecendo bem. Droga covid-19, lol.

Idealmente, eu gostaria de poder apenas executar docker-compose novamente e "atualizar" meu aplicativo no contêiner em execução e pedir ao tomcat para recarregar. Eu poderia usar o gerenciador do tomcat para fazer o upload da mudança, mas também temos um aplicativo de back-end que não usa um contêiner gerenciado de nenhum tipo, então teríamos que usar uma solução diferente para isso.

Seria bom se docker-compose fosse voltado para o desenvolvimento também, não apenas para uma implantação de produção.

Este caso de uso é relevante para a discussão: https://github.com/docker/compose/issues/3593#issuecomment -637634435

@ chris-crone

@gauravmanchanda

Meu caso de uso: além das configurações, tenho algumas bibliotecas (RPMs) que preciso instalar em 5 dos meus containers de aplicativos Rails (Debian). Versões diferentes de Ruby / Rails, portanto, não posso usar a mesma imagem de base, então devo ser capaz de armazenar os arquivos em um único local e copiá-los para um contêiner durante a construção, porque não quero baixar 1,5 GB de dados durante a construção.

Você já olhou para compilações de vários estágios para isso? Acho que seria uma solução mais robusta.

As compilações de vários estágios permitem que você use o mesmo Dockerfile para várias imagens. Isso permite fatorá-los e incluir apenas os bits necessários em cada imagem.

Um bom exemplo é o que usamos para construir o Docker Compose . Isso constrói usando Debian ou Alpine, mas nos permite fatorar código comum.

Compilações em vários estágios são legais, mas sofrem com seus próprios problemas, pois você precisa executar todos os estágios no mesmo contexto, o que nem sempre é possível. Além disso, até onde eu sei, você não pode usar facilmente COPY --from com imagens definidas em outro Dockerfile e criadas com docker-compose build (presumo que você possa fazer isso construindo e marcando-as manualmente).

COPY em si é muito limitado, pois você só pode importar do seu contexto de construção. docker cp pode copiar de qualquer lugar para qualquer lugar, exceto que não pode copiar entre a imagem e o contêiner (algo como COPY --from ).

Meu próprio caso de uso é um pouco diferente (além de copiar arquivos de configuração somente leitura, montagens de volume local não são a melhor ideia quando você implanta em outra máquina) e eu diria que o que estou fazendo agora é um antipadrão ... . Tenho potencialmente várias imagens diferentes que geram pacotes de recursos JS + HTML + compilados e minimizados (pense em pequenos aplicativos angulares) e um único servidor nginx que atende a todos eles (nb construído a partir de uma imagem personalizada por causa de plug-ins).

Atualmente, o que tenho que fazer é copiar os pacotes "implantar" das imagens "construir" na inicialização. Idealmente, isso deve ser feito na criação do contêiner ou na construção, mas o último exigiria a criação de outra imagem em cima do "nginx modificado".

Imagem do seguinte layout de projeto (subprojetos podem residir em repositórios separados e não se conhecerem):

app1/
  src/
    ...
  Dockerfile
app2/
  src/
    ...
  Dockerfile
app3/
  src/
    ...
  Dockerfile
nginx/
  ...
  Dockerfile
docker-compose.yml

Cada um dos arquivos app{1,2,3}/Dockerfile contém um alvo / estágio build que compila o aplicativo para /usr/src/app/dist . nginx/Dockerfile tem apenas um estágio e constrói uma imagem semelhante a nginx/nginx , mas com todos os plug-ins necessários (sem configurações).

docker-compose.yml:

version: '3.8'
services:
  app1-build:
    build:
      context: app1/
      target: build
    image: app1-build
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        rm -vfr /dist-volume/app1 \
        && cp -vr /usr/src/app/dist /dist-volume/app1 \
        && echo "Publishing successful"
    volumes:
      - 'dist:/dist-volume'

  app2-build:
    build:
      context: app2/
      target: build
    image: app2-build
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        rm -vfr /dist-volume/app3 \
        && cp -vr /usr/src/app/dist /dist-volume/app3 \
        && echo "Publishing successful"
    volumes:
      - 'dist:/dist-volume'

  #... same thing for app3-build

  nginx:
    build:
      context: nginx/
    image: my-nginx
    volumes:
      - 'dist:/var/www'
      - # ... (config files etc)

volumes:
  dist:

Agora, isso é obviamente não ideal, cada imagem de construção de aplicativo é executada desnecessariamente e termina rapidamente, as imagens implantadas residem em um volume compartilhado (presumo que isso tenha impacto negativo no desempenho, mas não consegui verificar ainda). Se copy ou copy_from fosse uma opção docker-compose, o mesmo poderia ser escrito como:

version: '3.8'
services:
  # assuming the images have default entrypoint and cmd combination that immediately returns with success.
  app1-build:
    build:
      context: app1/
      target: build
    image: app1-build

  #... same thing for app2-build app3-build

  nginx:
    build:
      context: nginx/
    image: my-nginx
    copy:
      - from: app1-build  # as image or service, both have their pros and cons, service would mean an image associated with this service
         source: /usr/src/app/dist
         destination: /var/www/app1
      - from: app2-build
         source: /usr/src/app/dist
         destination: /var/www/app2
      - from: app3-build
         source: /usr/src/app/dist
         destination: /var/www/app3
    volumes:
      - # ... (config files etc)

Meu caso de uso não está na etapa de construção ou na etapa de inicialização. Estou buscando arquivos gerados dentro de um contêiner ou todos os contêineres de um serviço, esses contêineres são executados em um Docker Engine remoto. Até agora, estou fazendo algo como docker-compose ps -qa <service> | xargs -i docker cp {}:<there> <here> . Eu só queria poder me limitar a docker-compose exclusivamente em meu script.

@ chris-crone

Também seria interessante saber por que você quer uma cópia em vez de montagem de ligação ou um volume para esses arquivos?

Você gosta de autoflagelação? Nesse caso, recomendo executar um aplicativo usando uma montagem de ligação no MacOS. 🤣 Veja meu post anterior para os detalhes.

Isso não quer dizer que nunca devemos implementar algo assim no Compose. Em vez disso, quando uma mudança significa que os usuários não serão capazes de reutilizar algo que funciona localmente na produção, gostamos de fazer uma pausa e ver se existe uma maneira mais robusta de atingir o mesmo objetivo.

@ chris-crone, acho que é um grande sentimento, porque muitas vezes as pessoas implementam antipadrões para docker, como não gerenciar a configuração e os dados de forma efêmera.

Eu me pergunto se poderíamos de alguma forma fazer o docker e a Apple trabalharem juntos na correção de problemas de desempenho com montagens de ligação. Para mim, pelo menos, não precisaria mais de uma opção docker compose cp, porque usaria montagens de ligação para desenvolvimento. No momento, porém, é muuuuito doloroso usar montagens de ligação. Posso mudar para uma máquina virtual com Linux, pois meu Mac apenas bytes.

@megaeater

Não estamos executando o docker em produção, é apenas para fins de desenvolvimento. O problema de usar volume (se bem entendi) é que o simulador (de terceiros) tem esse script de inicialização que exclui o arquivo na inicialização. A execução do script é interrompida se a exclusão falhar, portanto, precisaríamos montá-lo como rw. E se a exclusão do arquivo for permitida, precisaríamos ter um mecanismo para criar um diretório temporário para fornecer esses arquivos para que os originais não sejam excluídos. Portanto, precisaríamos de algum tipo de script estranho para aumentar a composição em cima do docker-compose.

Hmm .. Se você pudesse entrar em contato com o fornecedor do simulador, acho que é a melhor maneira de corrigir esse problema. Talvez você possa contornar isso com um script de ponto de entrada para o simulador que move os arquivos conforme necessário; concedido isso seria confuso.

@gauravmanchanda

ele nos ajudou a manter as bibliotecas / configuração em apenas um local e copiá-las, mas agora há problemas com .dockerignore sendo ignorados, não importa onde eu o coloque.
Ele funciona quando estou apenas usando o Docker com a nova opção DOCKER_BUILDKIT , mas não funciona ao usar docker-compose, tentei COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose build , mas ainda não funcionou. Alguma ideia?

Ainda bem que as construções de vários estágios ajudaram! Qual versão do Docker e do docker-compose você está usando? Eu tentaria com o mais recente e veria se o problema ainda existe. Deve respeitar o arquivo .dockerignore.

@Marandil , parece que docker build não está lidando com a estrutura do seu projeto (isto é: estrutura de diretório) que é o problema. Você pode usar algo como docker buildx bake (https://github.com/docker/buildx) para resolver esse caso de uso. Note que buildx está sendo trabalhado, então não é superestável ainda, mas visa resolver algumas das coisas que você está atingindo.

@itscaro , obrigado por sua contribuição! O que fazemos internamente para gerar coisas em contêineres é usar docker build para gerar o resultado de uma imagem FROM scratch . Isso só funciona nos casos em que você precisa da saída de um único contêiner.

@TrentonAdams , temos trabalhado para melhorar o desempenho do sistema de arquivos para Docker Desktop, mas é complicado. O problema subjacente é ultrapassar os limites da VM. Os bits de compartilhamento de arquivos foram reescritos recentemente (você pode habilitar a nova experiência usando a alternância "Usar gRPC FUSE para compartilhamento de arquivos" nas preferências) e isso deve resolver alguns dos problemas de alto uso da CPU que as pessoas estavam vendo. Temos alguma documentação sobre ajuste de desempenho aqui e aqui .

@ chris-crone

@Marandil , parece que docker build não está lidando com a estrutura do seu projeto (isto é: estrutura de diretório) que é o problema. Você pode usar algo como docker buildx bake (https://github.com/docker/buildx) para resolver esse caso de uso. Note que buildx está sendo trabalhado, então não é superestável ainda, mas visa resolver algumas das coisas que você está atingindo.

Obrigado, vou analisar docker buildx bake . Parece promissor, mas não consegui encontrar nenhuma boa referência ou documentação para ele, e as páginas em docs.docker.com são bastante vazias (cf. https://docs.docker.com/engine/reference/commandline/buildx_bake /). Até agora, encontrei https://twitter.com/tonistiigi/status/1290379204194758657 fazendo referência a alguns exemplos (https://github.com/tonistiigi/fsutil/blob/master/docker-bake.hcl, https: // github .com / tonistiigi / binfmt / blob / master / docker-bake.hcl), que pode ser um bom ponto de partida, mas dificilmente uma boa referência.

@TrentonAdams , temos trabalhado para melhorar o desempenho do sistema de arquivos para Docker Desktop, mas é complicado. O problema subjacente é ultrapassar os limites da VM. Os bits de compartilhamento de arquivos foram reescritos recentemente (você pode habilitar a nova experiência usando a alternância "Usar gRPC FUSE para compartilhamento de arquivos" nas preferências) e isso deve resolver alguns dos problemas de alto uso da CPU que as pessoas estavam vendo. Temos alguma documentação sobre ajuste de desempenho aqui e aqui.

@ chris-crone Inferno sim, muito obrigado! Há uma melhoria de 3-4s com a nova opção, e usar "em cache" me dá o mesmo desempenho que correr fora do contêiner, então isso é ENORME para mim. Estou vendo tempos de inicialização tão baixos quanto 2800 ms para nosso aplicativo, então não é mais 11-18s. YAY! Não preciso de nada além de cache, porque estou apenas recriando os contêineres todas as vezes.

@chris-crone Há um lugar onde devo postar material de desempenho para ajudar com o ajuste de desempenho e feedback no MacOS? Estou me perguntando por que um contêiner recém-iniciado com montagem de ligação seria lento quando não estiver usando cached . Deve haver alguma coisa estranha onde ele vai e volta verificando cada arquivo na inicialização se eles estão em sincronia, mesmo quando é novo?

Caso de uso: Eu executo um contêiner e ele modifica um arquivo (especificamente, o Keycloak modifica seu arquivo de configuração com base em variáveis ​​de ambiente, etc.). Quero uma cópia desse arquivo em meu disco local para que possa verificar o resultado dessa modificação e acompanhar meu progresso ao longo do tempo conforme modifico os scripts do contêiner. Atualmente, preciso encontrar a nova ID do contêiner a cada vez para que possa usar docker cp .

Caso de uso:
desenvolvendo no docker.
Preciso propagar meu arquivo de bloqueio para a máquina host ou ele será substituído quando o contêiner montar a pasta do projeto.

Caso de uso: preciso copiar um arquivo contendo uma chave secreta. O aplicativo executado dentro do contêiner lê esse arquivo na memória e o exclui do disco.

Caso de uso: estou executando testes de unidade c ++ em um contêiner do docker. Quero simplesmente copiar o código para uma imagem existente a cada execução.

1) Fazer isso com um dockerfile separado COPY significa que o código é gravado em uma imagem nova e desnecessária e eu preciso excluir essa imagem para garantir que a próxima execução crie uma nova imagem com o código mais recente.

2) Fazer isso com docker-compose volumes yaml config significa que o Docker chown o código-fonte como root:root (impedindo totalmente o meu IDE de fazer edições até eu chown de volta!)

@ shin- estou seguindo um antipadrão ao executar testes de unidade em um contêiner? Qual é a maneira não anti-padrão de resolver isso?

.... Eu estou mantendo a opção 1, pois é o menos doloroso. Mas eu vejo docker-compose suportando uma configuração de cópia sendo um aprimoramento incrível! pelo menos para este fluxo de trabalho!

@soulseekah Usar segredos na composição não é melhor para esse caso de uso?

Encontrei uma solução alternativa que funciona para mim:

  1. Crie o Dockerfile com
    COPY a_filename .
  2. Crie a imagem usando o Dockerfile
    docker build -t myproject:1.0 .
  3. Edite o docker-compose para usar a imagem que você acabou de criar
version: "3.7"
services:
  app:
    image: myproject:1.0
    ports:
      - 3000:3000
    networks:
       - mynetwork
       - internal
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: not_so_secret_password # don't do this 
      # https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/
      MYSQL_DB: appdb
    deploy:
      resources:
        limits:
          cpus: '0.75'
          memory: 100M

Não é uma solução perfeita, mas funciona no meu caso de uso.

@soulseekah Usar segredos na composição não é melhor para esse caso de uso?

Infelizmente, isso requer enxame da última vez que tentei :(

@soulseekah Usar segredos na composição não é melhor para esse caso de uso?

Infelizmente, isso requer enxame da última vez que tentei :(

@soulseekah Talvez use a solução alternativa que eu uso (acima de você)?

@ChristophorusReyhan o problema com essa solução é indicado no comentário

Fazer isso com um dockerfile COPY separado significa que o código é gravado em uma imagem nova e desnecessária e eu preciso excluir essa imagem para garantir que a próxima execução crie uma nova imagem com o código mais recente.

Embora seja uma solução de trabalho, pode levar a alguma manutenção indesejada. Por exemplo, para limpar a imagem indesejada _ ao mesmo tempo que preserva todas as imagens de seu interesse_:

docker-compose up && docker-compose down --rmi local

Mas certifique-se de que todas as imagens de seu interesse tenham uma tag personalizada e que a imagem de teste / fictícia não

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

29e7e280-0d1c-4bba-98fe-f7cd3ca7500a picture 29e7e280-0d1c-4bba-98fe-f7cd3ca7500a  ·  3Comentários

giggio picture giggio  ·  3Comentários

squeaky-pl picture squeaky-pl  ·  3Comentários

bergtwvd picture bergtwvd  ·  3Comentários

dazorni picture dazorni  ·  3Comentários