Compose: Defina os serviços que não são iniciados por padrão

Criado em 20 ago. 2015  ·  244Comentários  ·  Fonte: docker/compose

Os usuários freqüentemente definem scripts de manutenção, suítes de teste, sistemas de depuração em seus arquivos Compose que eles não querem executar quando fazem docker-compose up .

Deve haver alguma maneira de definir quais serviços são iniciados por padrão, mas ainda podem ser executados manualmente fazendo docker-compose up servicename ou docker-compose run servicename ... .

Soluções possíveis

1) Recomende aos usuários que usem um arquivo Compose separado
2) Adicionar uma opção aos serviços para que não sejam iniciados por padrão
3) Adicione uma opção de configuração de nível superior para definir os serviços padrão
4) Adicione um conceito de algo como um serviço, mas é apenas para comandos únicos ("scripts", "tarefas", etc ...)

(Por favor, sugira outros se você tiver ideias.)

Os pontos de dados:

arerun kinfeature

Comentários muito úteis

2) Adicionar uma opção aos serviços para que não sejam iniciados por padrão

Eu voto na opção 2. por exemplo, algo como uma diretiva start: false . As vantagens são que evitamos a necessidade de vários arquivos compose.yml ou arquivos de configuração extras, você pode apenas ler um compose.yml para ter uma ideia de toda a pilha de aplicativos.

Todos 244 comentários

+1 para a opção 1

Acho que adicionar serviços que não fazem parte de uma composição, mas que precisam ser vinculados / anexados a ele, é uma má escolha de design. Existem alguns outros casos de uso que seriam resolvidos permitindo alguma forma de sintaxe de inclusão. Resolver vários problemas com um único recurso é sempre bom.

Alguns desses problemas (aqueles que lidam com contêineres somente de dados, # 942, o último comentário de @ cpuguy83) já foram corrigidos por # 1754, não acho que precisamos mais considerá-los um problema (após 1.5 )

Desenvolvemos extensões Magento. Para fazer isso, precisamos de uma maneira simples de executar uma loja da web em uma pilha LAMP. O Compose torna isso fácil. Mas também queremos executar o phpunit, várias ferramentas de análise estática, construtores de documentação, etc. Na verdade, a grande maioria dos nossos "serviços" são apenas comandos, como docker-compose run --rm phplint . Idealmente, um comando não qualificado como

docker-compose up -d

iria apenas iniciar um serviço de longa duração (_serviços_ reais por assim dizer) e não iria disparar outros efeitos como o phpunit, desnecessariamente. (Também é importante que isso não acione coisas fora de ordem, como a execução de testes Selenium antes que o serviço da web esteja ativo.)

Tudo o que realmente estamos tentando fazer é tirar a dor do gerenciamento do ambiente dos desenvolvedores, não executar serviços de produção. Não sei se o comentário de @dnephin é representativo da direção que o Compose está

@kojiromike , o que há em (1) que é inadequado para o seu caso de uso? É apenas sobre a semântica do comando ( docker-compose run --rm phplint vs. docker-compose --file phplint.yml up )?

É que docker-compose up -d tenta 'iniciar' o phplint e docker-compose ps relata que o 'serviço' do phplint está inativo. Na realidade, isso não é um contêiner de serviço, é um contêiner de ferramentas, não deve ter o conceito de subir / descer. Pelo que entendi, os contêineres de ferramentas são adotados pelo docker (é como você executaria algo como redis-cli, claramente não um 'serviço') e embora eu os use mais no desenvolvimento, acho que eles têm um lugar para produção também; como, digamos, awk instalado em máquinas de produção ou em contêineres, por que não executá-lo em um contêiner com links para obter um comportamento previsível dele.

: +1: Eu sempre quero criar um contêiner tests junto com meus outros serviços para encapsular testes de unidade em execução. Minha "solução alternativa" é definir o comando como "/ bin / true" e executar o contêiner com o comando de teste de unidade especificado na CLI. Ser capaz de especificar quais containers devem começar em up time seria ótimo!

(aliás, bom trabalho, pessoal)

cc @jameydeorio

@ryneeverett A semântica é uma parte disso. É um problema de autodocumentação e localizabilidade. Atualmente, dizemos aos desenvolvedores docker-compose run --rm foo bar . Nós os convidamos a criar uma função shell ou alias, mas não mantemos um alias / rcfile padrão para projetos. (Não queremos padronizar as coisas fora dos contêineres; queremos usar Docker _to_ padronizar.) Adicionar um novo arquivo para alguns comandos cria uma hierarquia de importância: O arquivo docker-compose.yml se torna o arquivo "padrão" para importantes coisas, e o "outro" arquivo torna-se menos importante.

A outra coisa é apenas manter as relações entre os serviços se torna mais oneroso. Só porque queremos que algo não seja executado por padrão não significa que não use link ou volume de um serviço de longa duração. extends na verdade não fornece todos os recursos que precisaríamos para vincular serviços a "comandos" (serviços de execução única). Mesmo que tivesse, se tivermos que usar vários arquivos yaml, seremos forçados a usar extends onde, de outra forma, não precisaríamos.

extends não fornece, na verdade, todos os recursos de que precisaríamos para vincular serviços a "comandos" (serviços de execução única). Mesmo que tivesse, se tivermos que usar vários arquivos yaml, seremos forçados a usar extensões onde, de outra forma, não precisaríamos.

@kojiromike Isso é o que eu suspeitava. Eu me pergunto se você ficaria satisfeito com a melhoria de extends support + alguma maneira de fazer subcomandos (que seriam funcionalmente idênticos a extends ) dentro de um único docker-compose.yml . Mas talvez o último seja o mesmo que (4).

2) Adicionar uma opção aos serviços para que não sejam iniciados por padrão

Eu voto na opção 2. por exemplo, algo como uma diretiva start: false . As vantagens são que evitamos a necessidade de vários arquivos compose.yml ou arquivos de configuração extras, você pode apenas ler um compose.yml para ter uma ideia de toda a pilha de aplicativos.

Acho que nossa solução proposta para https://github.com/docker/compose/issues/1987#issuecomment -139632238 resolverá isso. Os serviços "admin" podem ser definidos em uma configuração separada e adicionados com -f quando um comando admin precisa ser executado em uma composição.

@dnephin A solução em # 1987 (comentário) _sobre_ "serviços administrativos", mas _não_ lida com "contêineres somente de dados", certo? Você ainda teria que usar a solução alternativa command: /bin/true .

Você não deve precisar de contêineres somente de dados com compose, pois o compose irá lidar com a troca dos volumes por contêineres recriados para você.

@ cpuguy83 No exemplo a seguir, o contêiner de dados não é realmente necessário, mas se eu quiser alterar o volume, preciso apenas olhar para um local designado.

nginx:
  image: nginx:1.9
  volumes_from:
  - data

php:
  image: php:5.6-fpm
  volumes_from:
  - data

data:
  image: debian:jessie
  volumes:
  - ./:/app

No entanto, concordo que este é um caso secundário e adicionar sintaxe adicional provavelmente não vale a pena. Só estou dizendo que a solução proposta não resolve esse caso.

É verdade que algum comando ainda é necessário para volumes de dados, então você teria que usar uma imagem mínima para oferecer suporte a esse comando.

Não estou completamente atualizado com a nova API de volumes que está sendo lançada, mas minha esperança é que possamos adicionar uma seção volumes: para compor que irá lidar com o volume de dados de uma maneira melhor (em vez de exigir um contêiner para eles).

Isso não significa necessariamente que seja a escolha certa, mas acho que a curva de aprendizado / facilidade de compreensão deve ser considerada.

Eu sinto que (2) é o mais fácil de compreender. Eu realmente não tenho uma maneira de confirmar isso, mas meu instinto diz que a maioria das pessoas que não estão intimamente familiarizadas com todas as opções de docker-compose que se deparam com o problema que estamos tentando resolver aqui dizem: "Gostaria que houvesse alguma maneira de fazer com que esse contêiner _não inicie_ quando eu executar docker-compose up " e eles virem start: false e pronto, terminamos e felizes.

Eles não dizem: "Se ao menos eu pudesse criar um segundo arquivo com uma história estranha de links para resolver isso ..." (embora eu saiba que https://github.com/docker/compose/issues/ 1987 # issuecomment-139632238 ajuda com a "história estranha de links", sim?).

(4) foi meio vago, mas uma avenida dedicada para o caminho para roteiros e eventos únicos como esse se encaixa nesse projeto de "faz sentido".

Hoje eu estava procurando exatamente (2) mas acabei com minha solução menos favorita, um segundo arquivo YML. Meu caso de uso:

Eu tenho alguns contêineres e todos eles estão vinculados ao mesmo contêiner mongo . Gostaria de oferecer a mim mesmo e à equipe a capacidade de carregar acessórios no banco de dados mongo e descobri que a maneira mais fácil de fazer isso é carregar o contêiner mongo com um nome diferente fixtures que se vincular ao mongo e executar mongorestore --host mongo --port 27017 --drop /dump . Como não queremos carregar os acessórios o tempo todo, parecia natural tê-lo com start: false mas acabamos tendo um arquivo YML separado para os dois contêineres fixtures e mongo .

Funciona bem, mas start: false é IMO muito mais limpo. Se eu tivesse 10 ou mais permutações desse assim chamado container de acessórios, então sim start: false seria uma má ideia e eu escolheria (1) .

Só tinha que fazer um arquivo de composição onde alguns serviços não deveriam ser executados com o comando docker-compose up -d . Para mim, a opção (2) seria a melhor solução para o meu problema.

Eu também encontrei isso. Não tenho certeza de qual eu acho que é a melhor solução, mas o que importa para mim é que preciso da capacidade de construir imagens que são utilizadas como parte de uma composição. Eles são para contêineres efêmeros, mas preciso que a imagem esteja pronta para uso para que eu possa executar o contêiner sob demanda.

Oi! mesmo problema aqui, feliz que haja um bom problema de agrupamento, ótimo trabalho!

No meu caso, tenho uma pilha python trabalhando com alguns contêineres com serviços. Tudo está funcionando bem, mas acabei de encontrar uma caixa fora da pilha. Estou gerenciando dependências estáticas com o bower e quero executar o comando bower dentro de um contêiner, é apenas um script que executamos de vez em quando.

Seria ótimo executar este script dentro da estrutura de composição que temos. Eu imagino algo como:
docker-compose run node bower install

Então eu gosto da 2ª da 4ª opção. Só precisa que o serviço não inicie, não é necessário: P

Se houver algum consenso, poderia tentar enviar um pull-req para algo como "reiniciar"
começo: sempre
talvez ... não sei.

Outra votação para a opção 2.

Eu preferiria a opção 2 também. Os novos Docker Data Containers podem ser especificados em um arquivo docker-compose, mas não precisam estar em execução para serem usados.

Opção 2 para mim também

A opção 2 seria ótima.

+1 para a opção 2

+1 para a opção 2. Manter vários arquivos e digitar seus nomes é apenas perda de tempo. Um único sinalizador booleano governaria todos eles. : cervejas:

+1 para a opção 4,
Se devo escolher um segundo favorito, sua opção 2.

É verdade que a melhor opção é 2,4 se eu puder marcar ambos com +1, então isso é o que eu faço, se não, vou com a maioria e voto em 2.

Votação para 2

ambos 2 e 4 são bons de ter.
+1 para 2

Não acho que seja necessário introduzir um novo conceito de tarefas. Estes leem muito bem na minha opinião e são possíveis sem muitas modificações:

// 'task' being a service that manages all my tasks, probably with some custom entrypoint script
docker-compose run task tests

// 'tests' being a service specifically for testing with the default command set to run my tests
docker-compose run tests

A "solução" atual com o arquivo de composição separado não é realmente uma solução na minha opinião. Como @xaka disse, ninguém quer digitar tudo isso:

docker-compose -f default-file.yml -f additional-tasks-file.yml  run task myTask

O que você vai acabar com é um script ./run-task que adiciona todo o clichê antes de myTask para você. Mas agora você adicionou outro ponto de entrada e interface ao seu aplicativo de vários contêineres. Os desenvolvedores veem docker-compose.yml e pensam: _ "Ótima, um aplicativo de escrita. Eu sei como lidar com isso!" _ E agora você tem que dizer a eles: _ "Certo, você pode administrá-lo com docker-compose como qualquer outro aplicativo de composição ... oh, mas espere ... há também este script adicional que você precisa saber ... "_

start: false / up: false / some-additional-flag-to-a-service: false é provavelmente a coisa mais simples de implementar, mas provavelmente também a mais clara e fácil de entender. E melhoraria muito a usabilidade.

o que @sherter disse. :seta para cima:

: +1: para isso. dockerfile separado é uma grande dor, especialmente quando as redes estão envolvidas

A abordagem start: true|false é muito limitada. E se alguns serviços forem usados ​​para teste, outros para administração e o resto para operação normal?

Eu preferiria adicionar a noção de agrupamento aos serviços.

    myservice:
       group: `admin`

Se o atributo group não for definido, default é assumido.
Dessa forma, poderíamos iniciar os serviços padrão e administrativos usando docker-compose up -g admin -d .

Melhor ainda, faça groups um array.

A criação de classes de grupo de serviços parece ser um recurso poderoso, mas também parece tangencial a esse problema.

Na versão 2 do docker-compose, cada contêiner é declarado dentro do item de nível superior services: .
Declarar um serviço com start: never para executar um script parece errado.
Portanto, considerando o novo formato, não deveríamos declarar um item extra de nível superior além de _serviços_, _volumes_ e _redes_?

Minha proposta:

  • adicione um novo item de nível superior scripts: , transients: (ou pense em um nome melhor) à v2.
  • dentro dos transientes, você pode definir um contêiner como faria com qualquer serviço
  • a única diferença é que eles não vão _iniciar por padrão_, pois se destinam apenas a uso temporário.

Exemplo:

version: "2"

services:
  web:
    image: myapp
    networks:
      - front
      - back
    volumes:
      - /usr/src/app/
  redis:
    image: redis
    volumes:
      - redis-data:/var/lib/redis
    networks:
      - back

scripts:
  bower:
    image: my_image_with_bower
    volumes_from: web
    working_dir: /usr/src/app/static
    command: "bower"
// maybe would be great to place something like "bower $@"
// to define where you want the cli arguments to be placed, by default at the end.

volumes:
  redis-data:
    driver: flocker

networks:
  front:
    driver: overlay
  back:
    driver: overlay

E então você pode executar:

docker-compose script bower <EXTRA_CMD_ARGUMENTS |  default nothing>

docker-compose script bower install

Preocupações:

  • Parece OverPowered criar outro item de nível superior apenas com o propósito de gerenciar o início, mas é derivado do fato de que o novo formato está declarando o comportamento no nível superior.
  • Estou tentando imaginar flexibilidade extra (e problemas) que isso pode adicionar.

Por último, no _recurso de grupos_, parece bom, mas se você tiver tantos agrupamentos, não vejo o problema de criar arquivos docker-compose para cada um deles. Provavelmente, o recurso que você deseja é a herança do arquivo docker-compose , isso seria incrível!

PD: @bfirsh talvez se você gostar da ideia, você pode adicioná-la às "Sugestões possíveis"

No segundo, porém, esta é uma reformulação da 4ª sugestão por causa dos novos serviços de declaração de formato iminentes.

Votação para a opção 2: mais clara, mais fácil de ler e não precisa aprender novos conceitos
Só quero um serviço que não inicia por padrão

Que tal algo como disabled: true

@ cpuguy83 Isso parece implicar que todo o serviço está desativado, mesmo para run . Eu acharia isso confuso.

@qcho hmm, agora que me familiarizei com o Docker desde 1.6, posso ver do que você e @gittycat estão falando. Nesse sentido, gosto muito da abordagem de

groups: # if no groups, all services are in the "default" group by…default
    - foo
    - bar
services:
  foo:
    image: imagine
    groups: foo
  bar:
    image: energy
    groups: bar
  baz:
    image: money
    # no groups, so "default"
   quux:
    image: word
    groups:
      - bar
      - default

Enquanto isso, na casca ...

docker-compose up -d # Up all services in default group, so 'baz' and quux
docker-compose up -d --groups foo # Up all services in the foo group
docker-compose up -d --groups foo,default # You get the idea
docker-compose run --rm bar somecommand # We never started 'bar', so it can be a one-off command

Uma abordagem como essa seria incrível e evitaria a necessidade desse tíquete, mas vai além de seu escopo.

@kojiromike Acho que não. É assim que os sistemas init se referem aos serviços que não devem iniciar automaticamente.

Também é simples e qualquer "confusão" pode ser resolvida com documentação.
Também acho muito menos confuso do que esse agrupamento, que não tem nenhuma relação com o conceito de início de serviço.

@ cpuguy83 Acho que a semântica de "serviços" é exatamente o que é confuso em primeiro lugar. Eu concordo que a questão do agrupamento é o aumento do escopo. Nesse sentido, prefiro a abordagem da opção 4 / @qcho , onde eles diferenciam claramente "serviços" de "coisas que não são serviços".

Esse é o ponto, por que eu deveria colocar um contêiner que nunca executará um serviço na categoria "serviço ... desativado". Parece um patch feio que alguém fez e não é intuitivo.

Talvez a "versão 2" do formato devesse ter levado esse problema em consideração. Por exemplo, outra especificação pode ser

version: 3?
containers:
  webserver:
    ...
  database:
    ...
  cache:
    ...
  some_script_container:

services: (they are groups):
  production:
    webserver:
      ...
    database:
      ...
    cache:
      ...
  development:
    webserver:
      ... DEFINE SOME CUSTOM DEV STUFF ABOVE basic container definition
    database:
      ...
    cache:
      ...     

Ok agora temos serviços próprios, com definição de grupos. Posso iniciar a produção ou o grupo de serviços de desenvolvimento. Ou apenas execute um script no some_script_container. uma vez que não está definido em nenhum serviço, ninguém será iniciado

@qcho Depende da definição de um serviço, mas em qualquer caso - eu

Então, digamos que escrever adote algo como um objeto job .

  1. trabalhos só são executados uma vez
  2. trabalhos são iniciados após serviços
  3. empregos devem sair
  4. ???

Agora, o Compose também precisa manter algum estado local sobre o trabalho, o que ele não faz atualmente.

É por isso que adicionar um simples auto-up: false ou autorun: false é a maneira mais fácil e menos assustadora (scopewise) de lidar com isso.

@ cpuguy83 Acho que você está estendendo o que estou dizendo com algo mais complexo. Não pretendo docker-compose sabendo sobre qualquer tarefa ou fluxo de trabalho. Scripts externos podem ser feitos para isso. O que pretendo é que docker-compose defina a pilha inteira para que um aplicativo execute.

Posso me imaginar criando um script e mantendo o estado que você está dizendo. Mesmo chamando o script antes do início do serviço, não apenas depois. O que não imagino é eu mesmo analisando o arquivo do compositor porque preciso verificar quais volumes preciso importar ou que configuração preciso extrair dele em um contêiner desconhecido para executar algum script que se aplique a ele. Então, acho que docker-compose deveria me dar esse contêiner; executar o script e manter o estado é meu problema.

Eu não vejo porque as pessoas continuam dizendo isso

services:
  my-script-container:
    auto-up:false

É mais simples do que:

scripts/containers/transients/you_name_it:
  my-script-container:

É o mesmo nível de complexidade. Mas menos hacky semanticamente.

Para obter as ideias em um tópico, referência # 2803

Caso de uso: você tem um projeto com muitos componentes e usuários que escolher e escolher qual instalar, mas ele compõe o arquivo instala todos eles.

Proposta: adicionamos uma opção de colocar no docker-cmpose.overrider.yml para excluir uma imagem definida no docker.compose

ie

alguma imagem:
excluir: sim

O comportamento seria ignorar essa entrada no docker-compose.yml

Você pode me dizer o que a equipe pensa, eu tenho interesse em fazer a mudança.

A votação para o nº 2 também ... acabei de encontrar essa necessidade hoje.

A proposta de @jimzucker também funcionaria, embora eu goste da ideia de ver "start: false" no arquivo .yaml principal para informá-lo imediatamente de que esse 'serviço' não será executado a menos que você o chame explicitamente. Caso contrário, você (ou no meu caso o usuário final / desenvolvedor para quem entregou os arquivos docker-compose) precisa se lembrar de procurar um arquivo de substituição.

+1 para 2. Tenho uma situação em que preciso construir uma imagem docker como parte da composição, mas ela não funciona como um serviço. Os outros serviços (que têm docker sock montada dentro deles) executam contêineres da imagem de vez em quando.

+1 para 2. E +1 para "auto-up" ou "auto-run" como texto.

E os casos de grupos de serviços (conforme explicado por @gittycat) não podem ser tratados por meio de variáveis ​​de ambiente ala "auto-up: $ {ADMIN}"?

Também vejo casos de uso reais para marcar serviços em docker-compose.yml para não serem iniciados automaticamente com um simples docker-compose up mas, em vez disso, para serem iniciados apenas explicitamente.

A solução 1) é uma maneira possível agora, mas na minha opinião é muito complicada, pois é preciso especificar um ou mais arquivos yml em vez de apenas chamar docker-compose up e ter que dividir ou até mesmo duplicar os arquivos.

Como eu realmente gostaria de ver algo como a solução 2) (como muitos outros também), implementei uma prova de conceito disso no # 3047 para que você possa brincar um pouco com isso para ver se seria viável solução.

+1 para a opção 2

+1 para a opção 2

+1 para a opção 2

+1 para ambas as opções 2 e 4

+1 para as opções 2 e 4

+1 para a opção 4. alguma configuração não deve ser permitida para scripts (por exemplo: reiniciar: sempre)

com a opção 2, poderia haver este caso estranho:

service:
  run_tests:
    build: ./tests/
    restart: always
    auto-start: "false"

o que isso significa?

@mathroc : Significa: "Não inicie automaticamente este contêiner quando a composição for executada. Quando este contêiner parar (após ter sido iniciado explicitamente), reinicie independentemente do código de saída." O que há de estranho nisso?

@niko oh certo, eu deveria pensar um pouco mais sobre isso antes de postar ...

alterando meu "voto" para +1 para a opção 2

1 para a opção 2, eu preciso disso em vários projetos.

pingando @bfirsh @dnephin :
Você poderia nos dar uma atualização sobre este assunto? Visto que a maioria dos comentários aqui são a favor da opção 2, há atualmente algum plano para implementar algo assim (ou a opção 3/4)?
Eu poderia polir minha solicitação pull (# 3047) e concluí-la com testes e documentação se você considerasse mesclá-la então.

Obrigado.

+1 para a opção 2

+1 para a opção 2

+1 para a opção 2

Acho que a opção 1 pode funcionar, mas precisamos de uma maneira melhor de reduzir o detalhamento de:

docker-compose -f docker-compose.yml -f docker-compose.tests.yml up

Talvez pudesse adicionar um sinalizador simplificado / augment? docker-compose --augment tests up e resolva automaticamente se é uma variação de docker-compose.yml - caso contrário, o usuário precisaria ser explícito.

Eu realmente gosto da ideia de uma nova palavra-chave de nível superior, talvez suites e commands ?

A seguinte configuração permitiria:

docker-compose run -s application
docker-compose run -c cache-clear

suites:
    application:
        services:
            - database
            - memcached
            - application
    tests:
        extends: application
        services:
            - application

commands:
    cache-clear:
        service: application
        workdir: /var/www
        command/entrypoint: php app/console ca:cl

Posso ver no código que já existe a noção de serviços "únicos" (IMHO usado apenas quando docker-compose run é chamado.
Pode ser reutilizado?
Se eu rotular um recipiente com com.docker.compose.oneoff=True , ele tentaria iniciá-lo?

Caso contrário, voto na opção 2.

Acabei de tropeçar nisso, então aqui estão meus dois casos de uso:

  1. variáveis ​​de ambiente "globais": a abordagem sugerida aqui é usar extends , com a qual estou bem ... mas agora preciso definir image para aquilo de que estou estendendo , e nem mesmo pode usar scratch (então acabou com https://hub.docker.com/r/tianon/true/).
  2. Serviços de "dimensionamento": por padrão, tenho uma instância do MongoDB, mas para alguns testes, gostaria de definir uma segunda instância inativa, que posso abrir para esses testes. Aqui, usar extends em um arquivo diferente parece uma ideia viável (ainda aprendendo sobre docker / docker-compose e as melhores práticas envolvidas).

+1 para a opção 2

+1 para a opção 2

+1 para a opção 2
Parece uma mudança simples ...

+1 opção 2,

no caso de uso de vários contêineres compartilhando um conjunto comum de envs e configurações, faz sentido construir um contêiner de base para estender, mas nunca realmente iniciar o contêiner

auto-start:true|false

Tendo uma boa solução desde setembro passado chamada rocker-compose , recomendo executar: _sempre_ | _uma vez_ | _Nunca_. Eu também gosto de state: _running_ | _ran_ | _criado_ também.

não sou fã de usar um projeto separado apenas para esse recurso, acabei roubando o comando True asm code do projeto tianon / true até que seja implementado

Eu também pensei inicialmente que a opção 2 seria a melhor, mas agora estou começando a achar que seria muito restritiva e logo após adicioná-la, a necessidade de executar tarefas uma vez apareceria. Na verdade, estou trabalhando em um projeto agora em que preciso dos seguintes casos de uso:

  • dentro da pilha, quero ser capaz de definir contêineres que são executados uma vez na implantação inicial e quaisquer execuções futuras são acionadas apenas externamente (por exemplo, programação / evento, via chamada de API, etc.) para que possam inicializar / atualizar o estado do contêiner de serviço principal dentro da mesma pilha (por exemplo, dados / esquema do banco de dados, preenchendo volumes de dados, etc.)
  • dentro da pilha, eu quero ser capaz de definir contêineres que são acionados apenas externamente para que possam ser usados ​​para encapsular tarefas utilitárias / administrativas (por exemplo, inspeção de estado / dados, etc.) e processos que são acionados na programação (por exemplo, backup) ou por eventos externos (por exemplo, acionar um processo em alterações em um balde S3)

No meu caso, a distinção entre state: created (executado 0 vezes) e state: ran (executado> = 1 vezes) é importante porque algumas das tarefas de utilitário / admin podem ser destrutivas e devem ser usadas apenas em certas circunstâncias, como serviços de migração.

Dado que agora estou mais inclinado para state: running | ran | created como em rocker-compose ou opção 4 com _task_ ou _job_ object de nível superior + capacidade de expressar uma dependência para que um serviço possa acionar uma tarefa para ser executada antes / depois de si mesmo .

Eu gostaria de mencionar que isso é importante para meu caso de uso. Eu uso docker-compose para criar um ambiente de teste e executar um conjunto de testes. O problema de iniciar todos os contêineres de uma vez é que não posso permitir facilmente que os contêineres de serviço (como banco de dados ou trabalhadores de aipo) sejam inicializados antes de executar o conjunto de testes.

Seria preferível ser capaz de realizar algo como:

$ docker-compose --file="docker-compose-testing.yml" up -d --exclude=tests
$ sleep 5
$ docker-compose --file="docker-compose-testing.yml" run --rm tests

Você pode imaginar algo mais elaborado do que sleep 5 poderia ser escrito para verificar se a inicialização ocorreu, mas não é necessário para o snippet de exemplo.

Eu não li uma opção sobre uma bandeira CLI. Portanto, eu proporia que um sinalizador --exclude fosse adicionado à lista de opções. O sinalizador --exclude diria ao comando up para não iniciar o contêiner especificado. O sinalizador --exclude seria analisado de forma que vários contêineres pudessem ser excluídos da inicialização conforme necessário.

: +1:

Pesando outro caso de uso em que a opção 2 seria uma solução adequada: iterar em um novo subserviço em um aplicativo existente. A maioria dos desenvolvedores no projeto não vai precisar do novo serviço ainda, e você definitivamente não quer problemas com ele atrapalhando seu trabalho, mas você também pode querer evitar manter um branch fora da árvore por um longo período de Tempo.

Um arquivo separado "docker-compose-experimental.yml" _pode_ funcionar, mas significa que toda a documentação para trabalhar nesse componente precisa ser escrita de uma maneira enquanto o componente ainda é experimental e, em seguida, revisada quando se tornar parte do conjunto padrão de serviços.

+1 para a opção 2

+1 para a Opção 2

+1 para a opção 2

+1 para a opção 2

+1 para a opção 2

@acran Eu gostaria que você enviasse sua solicitação de pull para ver se podemos obter alguma tração movendo isso para a frente, talvez se você rebase para eliminar o conflito em # 3047, ele será detectado, não tenho certeza de como chamar a atenção para isso.

@jimzucker well # 3047 já é um pull request e ainda estou esperando por alguns comentários dos desenvolvedores: decepcionado:

Veja meu comentário acima : tornar o PR digno de fusão ainda requer alguns polimentos, ou seja, atualizar documentos relacionados e casos de teste. Mas prefiro não fazer esse trabalho sem saber que essa abordagem será considerada integrada pelo upstream. Caso contrário, meus esforços sobre isso poderiam ser inúteis ...

+1 opção 2

@acran , gostaria de ajudá-lo a atualizar documentos relacionados e casos de teste. Tudo bem?

+1 opção 2

ou talvez definir um tipo de Job, como no Kubernetes?

+1 para a opção 2

Temos um docker-compose com vários serviços e um deles (o banco de dados) deve ser iniciado no ambiente de desenvolvimento, mas não no ambiente de produção. Portanto, temos que manter dois arquivos docker-compose. A opção 2 é exatamente o que procuramos!

: +1: para a opção 2

+1 opção 2

@acran , estou entrando em conectores aqui em SF para descobrir o processo / canal certo para obter feedback para que isso possa avançar, fique ligado;)

👍 para a opção 2

+1 para a opção 2

+1 opção 2

+1 opção 2

Também vou votar na opção 2

Outra ideia: agora que temos networks e volumes , poderíamos adicionar uma opção images também. Isso seria uma dica para o Compose de que essas imagens precisam ser extraídas ou construídas para que o aplicativo funcione, mas elas não seriam executadas quando você fizer docker-compose up .

Isso funcionaria para dois casos de uso, bem na minha cabeça:

1) O problema comum aqui, onde você deseja que algum tipo de comando de gerenciamento seja executado. docker-compose run pode voltar a executar imagens se o serviço não existir.
2) Aplicativos como este que executam imagens Docker, mas não estão funcionando o tempo todo.

/ cc @dnephin @aanand @

Exceto que seria bom ser capaz de configurar todas as opções que um contêiner de curto prazo precisaria (ou seja, os volumes / pontos de montagem, redes, links, nome, etc) no arquivo docker-compose para que você não tem que continuar a adicioná-los sempre que precisar executar esse contêiner ...

Em 13 de setembro de 2016, 03:58:41 CDT, Ben Firshman [email protected] escreveu:

Outra ideia: agora temos networks e volumes , poderíamos
adicione uma opção images também. Isso seria uma dica para compor que esses
as imagens precisam ser extraídas ou construídas para que o aplicativo funcione, mas elas
não seria executado quando você fizer docker-compose up .

Isso funcionaria para dois casos de uso, bem na minha cabeça:

1) O problema comum aqui, onde você quer algum tipo de gerenciamento
comando para executar. docker-compose run pode recorrer a imagens em execução
se o serviço não existir.
2) Apps comoeste que corre
Imagens do Docker, mas não estão em execução o tempo todo.

/ cc @dnephin @aanand @

Você está recebendo isso porque comentou.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/docker/compose/issues/1896#issuecomment -246618909

Enviado do meu dispositivo Android com K-9 Mail. Por favor desculpe minha brevidade.

Eu concordo com @mgriego nisso. Pense em um contêiner de geração de construção - seria melhor ter o comando e as opções configurados e apenas docker-compose up foo e fazer a construção e a saída.

Tentando obter mais compreensão aqui: A opção 2) é apenas um caso especializado do mais geral "queremos um initial_scale em docker-compose.yml "? (ver # 1661, # 2496 et. al.)

@ankon de forma alguma.

adicione uma images [seção]

@bfirsh isso começa a se mover na direção que tomei com https://github.com/dnephin/dobi. Eu deixei de ter "seções" (e usei apenas itens de nível superior para cada recurso). Acho que seria difícil fazer isso funcionar com o modelo Compose.

  1. networks e volumes nunca são operados diretamente, eles são apenas criados conforme necessário por um contêiner. Dividir as imagens em suas próprias seções não mudará o comportamento que temos agora, apenas tornaria a configuração do Compose mais complicada. Se você quiser apenas construir uma imagem, execute docker-compose build .
  2. Não creio que realmente resolva os problemas identificados neste problema. As pessoas querem contêineres, não apenas a imagem

Relendo o tópico e a discussão em # 2496 sobre a declaração de restrições de escala no arquivo de composição, estou começando a preferir a Opção 4 (ou seja, uma nova seção de nível superior) em vez da Opção 2.

Especificamente, um nome de seção como utilities seria um bom ajuste: componentes que normalmente não são necessários, mas quando você precisar deles, você deseja pré-configurar os outros componentes aos quais eles estão vinculados, em vez de precisar fazer com que as pessoas construam um encantamento docker run adequado.

Essa abordagem cobriria não apenas comandos administrativos únicos, mas também serviços auxiliares de depuração e introspecção, como pgweb e flor de aipo (que são muito úteis para serem executados em desenvolvimento, mas normalmente você não desejaria em produção devido à segurança adicional área de superfície de ameaça que eles criam).

Definir a semântica desses novos "não serviços" também fica muito mais fácil: eles são _exatamente_ o mesmo que services (incluindo todas as mudanças futuras nesse formato), com a única exceção de que comandos não qualificados como docker-compose build , docker-compose pull e docker-compose up ignoram completamente - se você quiser que qualquer componente listado em "utilitários" em vez de "serviços" seja processado, você precisa nomeá-lo especificamente (embora haja poderia talvez ser uma opção --all , semelhante à atual para docker-compose rm ). No entanto, a CLI para interagir com esses utilitários pelo nome seria idêntica àquela para interagir com os serviços normais (ao contrário do status quo, onde você precisa especificar o arquivo de configuração do utilitário extra), e docker-compose cuidaria de evitar conflitos de nome entre as definições de serviço e utilitário.

Embora a proposta de dimensionamento em # 2496 possa ser (ab) usada para obter esse comportamento, ainda parece uma solução alternativa, em vez de um recurso projetado adequadamente.

Gosto desse design, @ncoghlan.

Em vez de utilities que tal nomeá-lo apenas .services ? Isso naturalmente indica que services e .services usam exatamente a mesma semântica, a única diferença é que .services não são executados por padrão. É muito semelhante a nomes de arquivos que não são exibidos por padrão. Suponho que a desvantagem é que a distinção entre os dois é um pouco sutil.

Gosto da ideia básica sobre a qual @ncoghlan fala lá, mas…

  1. Não concorde que _todos_ os comandos não qualificados devem ignorar esses utilitários por padrão. Em minha opinião, todos os comandos devem ser executados normalmente, exceto aqueles que resultariam em um contêiner em execução. (Então, basicamente, up e start .)
  2. Com relação ao comentário de

@bfirsh @ncoghlan Concordo totalmente com @dnephin :

Não creio que realmente resolva os problemas identificados neste problema. As pessoas querem contêineres, não apenas a imagem

O que eu - e acho que a maioria das pessoas aqui - precisamos para o fluxo de trabalho desejado são serviços simples; eles são definidos como qualquer serviço normal, eles são iniciados / interrompidos como serviços normais, etc.
A _única_ diferença é que eles não são iniciados automaticamente por um simples docker-compose up por padrão, mas apenas quando especificados explicitamente (ou puxados como uma dependência).

Portanto, não vejo nenhuma necessidade de uma nova seção de nível superior ou um conceito completamente novo para esses contêineres únicos, mas apenas um parâmetro de configuração opcional por serviço.
Implementei isso em minha solicitação de pull # 3047 como uma prova de conceito. É uma mudança muito pequena, mas satisfaria totalmente meus casos de uso. Portanto, se houver algo mais que eu possa fazer para mesclar isso, por favor, me avise (=

Para quem deseja testar isso, aqui estão os comandos para criar e executar docker-compose em um contêiner:

# download and build
git clone [email protected]:acran/compose.git -b auto_up
cd compose
docker build -t docker-compose .

# create an example docker-compose.yml
cat > docker-compose.yml <<EOF
version: "2"
services:
  foo:
    image: busybox
    auto_up: false
    command: echo foo
  bar:
    image: busybox
    auto_up: false
    command: echo bar
    depends_on:
      - foo
  baz:
    image: busybox
    command: echo baz
EOF

# start all default services only, i.e. baz
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -ti -v $(pwd):$(pwd) -w $(pwd) docker-compose up

# start service foo only
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -ti -v $(pwd):$(pwd) -w $(pwd) docker-compose up foo

# start service bar, foo is pulled in as a dependeny
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -ti -v $(pwd):$(pwd) -w $(pwd) docker-compose up bar

# clean up all services, i.e. foo, bar and baz
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -ti -v $(pwd):$(pwd) -w $(pwd) docker-compose down

@acran , gostaria de ajudá-lo a atualizar documentos relacionados e casos de teste. Tudo bem?

@ dattran-vn01 é claro, eu ficaria feliz: smiley:

@acran em seu exemplo, o único comando que possui comportamento diferente do Compose atual é o primeiro, e esse comportamento pode ser realizado usando up baz .
Você também pode realizar a mesma coisa usando vários arquivos do Compose.

Ter alguns comandos operando em uma lista diferente de serviços padrão parece muito confuso e é um dos motivos pelos quais não gosto desse recurso.

@acran em seu exemplo, o único comando que possui um comportamento diferente do Compose atual é o primeiro, e esse comportamento pode ser realizado usando up baz.
Você também pode realizar a mesma coisa usando vários arquivos do Compose.

@dnephin sim, exatamente, eu sei, e nesse exemplo seria a maneira mais fácil.
Mas imagine isso com 10 serviços e apenas um serviço único (como "init" ou "backup" / "dump"): nesse caso, você teria que listar todos os serviços na linha de comando, exceto aquele único - fora do serviço como docker-compose up service1 service2 ... service10 (veja abaixo). Em especial, você teria que se lembrar de todos os serviços e controlar manualmente todas as alterações no docker-compose.yml .

Eu também sei sobre a possibilidade de usar vários arquivos YAML, veja meu primeiro comentário acima , e isso, além de fornecer explicitamente todos os serviços na linha de comando, de fato cobre a maioria dos casos de uso declarados aqui; mas parece mais uma solução alternativa para usar.

Aqui está outro exemplo docker-compose.yml para visualizar o problema:

version: "2"
services:
  init:
    image: busybox
    auto_up: false
    command: echo "I do one-time initializing"
  service1:
    image: busybox
    command: echo "I'm service #1"
  service2:
    image: busybox
    command: echo "I'm service #2"
  service3:
    image: busybox
    command: echo "I'm service #3"
  service4:
    image: busybox
    command: echo "I'm service #4"
  service5:
    image: busybox
    command: echo "I'm service #5"
  service6:
    image: busybox
    command: echo "I'm service #6"
  service7:
    image: busybox
    command: echo "I'm service #7"
  service8:
    image: busybox
    command: echo "I'm service #8"
  service9:
    image: busybox
    command: echo "I'm service #9"
  service10:
    image: busybox
    command: echo "I'm service #10"

Um simples docker-compose up _with_ o atributo auto_up inicia aqui todos os serviços, exceto o serviço init . Para conseguir o mesmo sem isso, seria necessário digitar um comando muito mais longo com 10 serviços ou dividir o arquivo YAML e especificar vários arquivos.

Portanto, o recurso solicitado aqui é mais sobre conveniência e digitar menos no cli e não sobre um recurso completamente novo.

Com relação à opção "usar vários arquivos de configuração" (que de fato é a melhor opção disponível atualmente), o problema de usabilidade com ela é que ela se parece com isto na prática:

$ docker-compose up one-shot-command
ERROR: No such service: one-shot-command
$ docker-compose up -f docker-compose.yml -f docker-compose-utils.yml one-shot-command
# Actually goes & does the requested thing

A discrepância então infecta _todos_ a documentação e automação de seu projeto: você deve garantir que _dois_ arquivos de composição estejam disponíveis para qualquer pessoa que queira executar comandos de utilitário, você deve garantir que a invocação completa seja fornecida para comandos no arquivo de utilitário e, se houver algum comando ou o serviço é rebaixado de "sempre em execução" para "apenas executado quando explicitamente solicitado", você precisa encontrar qualquer invocação que não forneça os nomes dos arquivos de configuração e adicioná-los.

Isso é tudo _fazível_, é apenas irritante em comparação a ser capaz de dizer no arquivo de composição "Só execute quando eu pedir explicitamente, nunca execute por padrão".

Alguém uma vez me disse: _ "Se várias pessoas inteligentes não conseguem decidir qual abordagem é a melhor, geralmente nenhuma delas é muito ruim. O pior é não fazer nada."

Este cartão parece ser um excelente exemplo disso :)

Dado que o docker agora suporta o conceito de serviço nativamente para comandos de longa execução, acho que a melhor abordagem seria adicionar uma nova seção chamada comandos, que permite a mesma funcionalidade dos serviços, exceto para políticas de reinicialização, que devem ser proibidas.

Em minha configuração, tenho serviços no docker-compose que são necessários para executar minha infraestrutura (nginx, banco de dados, servidor da web, filas de mensagens ...). Também defini serviços adicionais que só preciso por motivos de depuração (por exemplo, um banco de dados web gui).

Eu gostaria que os serviços de "depuração" NÃO iniciassem automaticamente, mas se eu quiser adicioná-los, posso fazê-lo com um simples docker-compose up -d database-gui e ele é adicionado.

Além disso: às vezes eu mudo de ideia e quero que um desses serviços sempre inicie ... => Com a opção 2) Eu posso apenas mudar aquele sinalizador

=> Vote na opção dois, porque é simples e parece satisfazer os requisitos de todos aqui. Todas as outras soluções parecem um excesso de engenharia para mim ... Adicionando complexidade à configuração com base em casos de uso raros ou apenas imaginários, não na necessidade prática.

Só aqui para adicionar meu +1. Estou executando em aplicativos Django e ao executá-los no docker seria bom ter um contêiner que executaria shell ou testes ou para esse assunto, migre comandos. Mas não quero executar nenhum desses sempre que iniciar o aplicativo. Embora o uso de vários arquivos de configuração funcionasse, isso exigiria digitação, script ou aliasing de linhas de comando de quilômetros de extensão. Se eu quisesse fazer isso, não usaria o compose de forma alguma, eu apenas faria o shell script de meus contêineres (ou python os script ... talvez adicione um arquivo YAML unificador para armazenar configurações de contêiner ... espere ...) não quero fazer nada como docker-compose -f common.yml -f dev.yml -f local.yml -f commands.yml up migrate apenas para executar migrações de banco de dados no meu contêiner. A alternativa é usar /bin/true como comando e fazer algo como docker-compose -f common.yml -f dev.yml -f local.yml up commands 'python3 manage.py migrate' que também não é elegante. Portanto, ter comandos únicos armazenados em algum lugar da configuração seria muito útil para mim. Qualquer uma das opções 2, 3 e 4 funcionaria para mim.

Eu gostaria de sugerir que você dê uma olhada no dobi , que é uma ferramenta na qual tenho trabalhado parcialmente com base no feedback deste tópico.

O compose foi projetado para iniciar serviços de longa duração que formam um "ambiente".
dobi está focado em tarefas de construção de projeto sequencial.

As coisas que você está procurando (executar um shell, executar testes de unidade, executar migração) são todas tarefas de projeto, portanto, se encaixam muito melhor no modelo dobi.

dobi e compose funcionam muito bem juntos, você pode iniciar o compose a partir do dobi usando um recurso de composição .

compose=dev-environment:
  files: [docker-compose.yml, local.yml]
  project: 'theprojectname'

que você pode executar usando:

dobi dev-environment

Há um exemplo de integração de composição e execução de migrações db aqui: https://github.com/dnephin/dobi/tree/master/examples/init-db-with-rails

Existem exemplos de muitos fluxos de trabalho (incluindo a execução de testes, iniciar um shell interativo, liberar e construir imagens mínimas) aqui: http://dnephin.github.io/dobi/examples.html

+1 para 2). Em nosso ponto de vista, é desnecessário pensar e discutir casos de uso incomuns, como comandos únicos, mas nós apenas queremos ter serviços reais que são criados e prontos para uso, mas podem ser iniciados sob demanda quando necessário (e o padrão não consome Recursos).

"casos de uso incomuns"? você executa migrações de banco de dados? você executa testes de unidade? você executa fiapos? webpack?

Sim corro mas isso pode ser conseguido e controlado dentro de containers, na minha opinião. Mas não quero depreciar sua visão ou demandas, não vamos acender essa discussão. Nossos requisitos no docker compose não estão necessariamente em conflito.

Acabei de encontrar este tópico tentando encontrar uma maneira de criar um contêiner docker-compose para um script que apaga o banco de dados em meu contêiner mysql e recarrega o esquema de um dump baixado. É um processo muito longo e destrutivo, então não quero que ele seja executado toda vez que eu ativar os serviços, mas ele também precisa ser executado dentro do conjunto composto de contêineres usando seu próprio dockerfile.

Chame-os de tarefas, comandos, o que for, mas sou meio SOL sem isso.

Tropecei nisso procurando por outra coisa, só queria chip em um caso de uso ... Descobrimos que nossos desenvolvedores eram os mais capazes de definir quais dados deveriam ser copiados de seus serviços. Como o arquivo docker-compose.yml está em suas mãos e os volumes nomeados são usados, decidimos usá-lo para definir as estratégias de backup ... Aqui está um exemplo resumido de nosso antigo docker-compose.yml que estávamos usando.

version: '2'
services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    restart: always
    ports:
      - "5555:5555"
    volumes:
      - gitlab_config:/etc/gitlab
      - gitlab_logs:/var/log/gitlab
      - gitlab_data:/var/opt/gitlab
      - certificates:/etc/gitlab/ssl
      - registry_data:/var/opt/gitlab/gitlab-rails/shared/registry
  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    restart: always
    volumes:
      - certificates:/etc/gitlab-runner/certs
      - /var/run/docker.sock:/var/run/docker.sock
volumes:
    gitlab_config:
      driver: local
    gitlab_logs:
      driver: local
    gitlab_data:
      driver: local
    certificates:
      driver: local
    registry_data:
      driver: local

Para poder fazer o backup dos dados de volumes, decidimos usar um contêiner busybox para tar os dados necessários, mas ele precisa ser flexível e fazer apenas os volumes que os desenvolvedores desejam fazer backup. Finalmente, devemos ser capazes de fazer backup de cada volume separadamente. Para conseguir isso, adicionamos 3 serviços a todos os nossos docker-compose.yml

  boot:
    image: busybox
    depends_on:
      - gitlab
      - gitlab-runner

  backup:
    image: busybox
    volumes:
      - gitlab_config:/data/gitlab_config
      - gitlab_data:/data/gitlab_data
      - registry_data:/data/gitlab_data
      - /backups/latest:/backup
    command: find . -type d -maxdepth 1 -mindepth 1 -exec tar cvf /backup/{}.tar {}  \;
    working_dir: /backup

  restore:
    image: busybox
    volumes:
      - gitlab_config:/data/gitlab_config
      - gitlab_data:/data/gitlab_data
      - registry_data:/data/gitlab_data
      - /backups/latest:/backup
    command: find . -type f -iname "*.tar" -maxdepth 1 -mindepth 1 -exec tar xvf {} \;
    working_dir: /backup

Os serviços de backup e restauração precisam apenas ser configurados usando os volumes, os comandos farão o resto. Estamos planejando adicionar um pouco de configuração para poder escolher quais volumes fazer backup ou restaurar, mas por agora, faremos todos eles ... Já que não queremos que esses 2 serviços sejam iniciados em cada docker-compose comando up, precisávamos especificar todos os serviços que queríamos, o que pode ser entediante ... Então, adicionamos um serviço fictício chamado boot, tudo que ele faz é depender de todos os serviços que precisam ser executados e apenas chamamos este quando docker-compose up.

Isso aqui está cheio de pequenos hacks, mas nos permite executar facilmente docker-compose up backup para ter nosso backup armazenado no host / backups / mais recente e, a partir daí, executar nossa lógica de versionamento / poda.

Espero que ajude alguém que está tentando conseguir algo semelhante ... Mas no final, sendo capaz de apenas dizer ao docker-compose para não inicializar esses 2 serviços, não precisaríamos de um terceiro e complicar nosso docker-compose comandos.

Em desenvolvimento, temos atualmente 4 arquivos docker-compose:

  • docker-compose.yml : define os principais serviços necessários para operar totalmente nosso aplicativo, por exemplo, redis, MySQL, php-fpm, processador de fila Laravel, nginx, Solr
  • docker-compose-utils.yml : Define os serviços utilitários necessários para executar tarefas de desenvolvimento, por exemplo, gulp, npm, artisan (Laravel), composer, redis-cli, geralmente executado com os serviços acima
  • Mais 2 arquivos docker-compose para definir o ambiente e os volumes para os serviços acima

Essa configuração funciona bem, pois, fora do Docker, temos dependências mínimas para nosso ambiente de desenvolvimento. A desvantagem são as linhas de comando pesadas necessárias para especificar todos os arquivos .yml necessários para executar utilitários simples.

Desenvolvemos em macOS, Windows e Linux. Além disso, muitas de nossas tarefas de desenvolvimento exigem algum tipo de parametrização (por exemplo, criar uma migração de banco de dados, executar um comando composer / artisan / npm com seus próprios argumentos), então criei schmich/runx como um cross-install zero executor de tarefas de plataforma para agrupar nossas tarefas de desenvolvimento comuns.

Por exemplo, isso nos permite dizer runx migrate: make create_some_table para efetivamente executar docker-compose -f docker-compose.yml -f docker-compose-utils.yml -f docker-compose-dev.yml -f docker-compose-utils-dev.yml run --rm artisan migrate:make create_some_table , ou runx npm outdated para visualizar nossas dependências JS desatualizadas.

Eu não usei dobi mencionado acima, mas runx parece semelhante em espírito, embora menos adaptado para um ambiente Docker. Em última análise, desejo evitar dependências em todos os lugares, exceto onde absolutamente necessário: para os próprios serviços e para os scripts de utilitário necessários no desenvolvimento.

Alguma novidade? Eu acho que esse recurso seria muito bom de ter! Eu voto pela solução de uma configuração de nível superior como default onde podemos especificar qual serviço deve ser executado.
O serviço dummy boot é bom, porém prefiro deixar o processo em primeiro plano, portanto, quando terminar este trabalho, posso simplesmente fechar o terminal para encerrar tudo. Também é bom ter a saída anexada por padrão e isso não acontece com o serviço fictício.

Já que noboby comentou casos de uso usando arquivos .env, aqui está o meu:

Eu tenho 4 arquivos de composição: docker-compose.yml, docker-compose.local.yml, docker-compose.prod.yml e docker-compose.ci.yml. Para cada ambiente, tenho um .env diferente:

CI .env:
COMPOSE_PROJECT_NAME=foo
COMPOSE_FILE=docker-compose.yml:docker-compose.ci.yml
WEB_PORT=8081
...

Test/dev/etc .env:
COMPOSE_PROJECT_NAME=foo
COMPOSE_FILE=docker-compose.yml:docker-compose.local.yml
WEB_PORT=80
...

E assim por diante...

Os usuários e / ou scripts não precisam se preocupar com quais arquivos de composição usar, pois os ambientes já estão configurados individualmente.

Mas eu tenho uma instância de manutenção para executar eventualmente, ela não pode ser configurada dentro do principal docker-compose.yml e uma solução seria criar um docker-compose.worker.yml e executar uma linha de comando com 3 opções "-f" que mudam com cada ambiente. Isso é muito sujeito a erros para ser uma opção utilizável.

A solução que encontrei foi criar um diretório "trabalhador", colocar o arquivo yml lá, vincular o arquivo .env superior a este diretório e criar arquivos docker-compose. [Ci | local | prod] vazios .yml (caso contrário, eu teria para alterar o valor da variável COMPOSE_FILE).

Isso funciona bem, mas está longe de ser o ideal. Qualquer outra solução do OP resolveria isso sem qualquer confusão.

Acho que a discussão aqui, os muitos casos de uso de exemplo, bem como o fato de que existem frequentemente problemas duplicados para isso, torna bastante claro que existe uma demanda real de muitos usuários pela possibilidade de "Definir serviços que não são iniciados por padrão "

Portanto, eu realmente gostaria de mover a discussão aqui de _se_ isso deve ser implementado mais para _como_ isso deve ser implementado. Poderíamos talvez todos concordar com isso ?

Em relação a _como_ isso pode ser feito, @bfirsh listou algumas opções no comentário de abertura:

1) Recomende aos usuários que usem um arquivo Compose separado

Esta é a única solução disponível atualmente para este caso de uso. Mas, como dito acima, neste caso é mais uma solução alternativa, pois requer a digitação manual de longas linhas de comando e a lembrança de quais arquivos do Compose incluir para qual comando executar.
Claro, em uma configuração de CI ou implantação automatizada para produção, isso não é um problema, já que a linha de comando precisa ser definida apenas uma vez e nunca ser digitada manualmente. Portanto, trata-se apenas de conveniência em ambientes não automatizados, ou seja, de desenvolvimento, que, de acordo com o manual docker-compose, é um dos principais casos de uso do próprio Compose:

Juntos, esses recursos fornecem uma maneira conveniente para os desenvolvedores iniciarem um projeto. O Compose pode reduzir um “guia de introdução ao desenvolvedor” de várias páginas a um único arquivo Compose legível por máquina e alguns comandos.

Ter que digitar algo como docker-compose -f docker-compose.yml -f docker-compose-utils.yml run init apenas para inicializar uma configuração local não parece _conveniente_ para mim, mas sim algo que pode ser encontrado em _um “guia de introdução ao desenvolvedor” de várias páginas _.

E para considerar a opção 1b) aqui:

Recomende aos usuários que usem um script / ferramenta wrapper para usar arquivos Compose separados

Se eu tiver que obter ferramentas e dependências adicionais apenas para isso, por que usar docker-compose em primeiro lugar? Uma vez que tudo que docker-compose faz poderia - em teoria - ser feito apenas com um script de shell personalizado e o cliente nativo docker diretamente.
Vejo a principal vantagem de docker-compose em sua interface de usuário padronizada (eu clono um projeto, vejo um docker-compose.yml lá e sei que só preciso executar docker-compose up para começar) . Sempre ter que saber qual arquivo de composição usar para o que enfraquece drasticamente essa vantagem.

2) Adicionar uma opção aos serviços para que não sejam iniciados por padrão
3) Adicione uma opção de configuração de nível superior para definir os serviços padrão

Essas duas opções fazem basicamente o mesmo: definir quais serviços devem (não) ser iniciados por padrão em um arquivo de composição , opção 2) colocando serviços individuais na lista negra, opção 3) colocando um conjunto de serviços na lista de permissões globalmente.
Considerando que na maioria das vezes há mais serviços padrão do que "serviços únicos" em um único arquivo de composição, é provavelmente mais fácil colocar um serviço na lista negra do que ter que colocar todos os outros na lista branca e atualizar a lista toda vez que um serviço padrão é adicionado ou removido. Também com a opção 2) mesclar vários arquivos de composição é provavelmente mais fácil.

4) Adicione um conceito de algo como um serviço, mas é apenas para comandos únicos ("scripts", "tarefas", etc ...)

Acho que a opção 4) é apenas uma especialização da opção 2) ou 3), pois na maioria dos exemplos acima os contêineres únicos desejados são basicamente definidos como qualquer outro serviço e não fazem nada mais ou menos como os serviços normais - exceto que eles não é iniciado por padrão. (Ou perdi alguma diferença significativa para um "serviço").

Portanto, na minha opinião, a opção 2) é a melhor escolha aqui, pois requer o mínimo de alteração, mas ao mesmo tempo é flexível o suficiente para satisfazer a maioria (ou todos?) Os casos de uso mencionados aqui e ser muito conveniente de usar ao mesmo tempo.
No entanto, ficaria igualmente feliz em ver algo como a opção 3) ou 4) mesclada com o upstream. Então, depois de mais de um ano de discussão aqui, há algum prazo para quando ou se isso vai acontecer?

Concordo que a opção 2 é provavelmente a menos invasiva. O único recurso que vejo que a opção 4 pode fornecer é a capacidade de executar comandos em contêineres existentes (usando o mecanismo docker exec). Por exemplo, se tudo que eu quero é executar uma migração de banco de dados ou testes de unidade, pode não haver razão para criar um contêiner separado inteiro para ele se eu já tiver um contêiner executando meu aplicativo. Dito isso, os contêineres são leves e eu ficaria perfeitamente satisfeito com a opção 2.

@MadWombat Tenho o mesmo sentimento sobre a opção 4, é por isso que propus outro recurso para este caso de uso: # 4096. há sobreposição com o recurso descrito aqui, mas acredito que poderia ser útil por si só ou adicionalmente a este

@mathroc Eu mencionei a opção 4 usando docker exec, pois @acran perguntou se havia alguma diferença significativa entre as opções 2 e 4. Não posso, no entanto, vir com um caso de uso da vida real em que você desejaria especificamente executar um comando em um contêiner existente em vez de trazer outro contêiner semelhante para o propósito. Pode haver algum cenário com conexões persistentes limitadas a algum serviço ou algum outro recurso limitado que já está sendo usado por contêineres existentes, mas não consigo pensar em nenhum.

O único recurso que vejo que a opção 4 pode fornecer é a capacidade de executar comandos em contêineres existentes (usando o mecanismo docker exec).

Esse é realmente um novo caso de uso que justificaria (e exigiria) a introdução de um novo conceito de nível superior diferente de serviços. Mas, desde que os comandos não precisem ser executados por meio de docker exec dentro do contêiner de serviço já existente, o conceito de serviço existente deve ser suficiente.

Não posso, entretanto, apresentar um caso de uso da vida real em que você deseje especificamente executar um comando em um contêiner existente em vez de abrir outro contêiner semelhante para esse propósito.

O caso mais próximo que posso pensar é algo como alterar um arquivo de configuração dentro do contêiner e disparar uma recarga pelo aplicativo; usando o exemplo de @mathroc de # 4096:

version: "2"
services:
  my_service:
    image: my/service
shortcuts:
  start-debugging:
    service: my_service
    command: echo "debug=true" > /etc/myapp/conf.d/debug.conf && mydaemon --reload-config
  stop-debugging:
    service: my_service
    command: echo "debug=false" > /etc/myapp/conf.d/debug.conf && mydaemon --reload-config

Embora relacionado a esse problema, o # 4096 tem seus próprios casos de uso e talvez a opção 4) possa ser movida para lá?

Já se passou mais de um ano de discussões e parece que não estamos mais decididos a tomar uma decisão. @bfirsh deve apenas escolher um estilo e ir com ele: smile:

+1

+1, seria um recurso muito útil de se ter.

E outro +1 para a opção 2, com algo como auto-start: false ou enabled: false .

Meu caso de uso é estender serviços. Não é possível estender serviços que tenham depends_on definidos, então o que eu gostaria de fazer é definir um modelo de serviço e, em seguida, estender vários serviços a partir dele. Obviamente, o modelo deve ser construído, mas não executado automaticamente.

Criei minha própria solução, fique à vontade para usar.
Ainda está em beta :)

https://github.com/jonathanborges/picles-docker

Muitas opções excelentes aqui. A necessidade do recurso é real.

A opção 2 é claramente a mais popular, ocorrências:

1 -> 4
2 -> 52
3 -> 3
4 -> 10

Outro 👍 para a opção 2

Podemos lidar com isso facilmente em um serviço de "ferramentas" com um ponto de entrada inicial ou comando que simplesmente retorna. Em seguida, executamos este serviço com um comando alternativo para fazer o que queremos (por exemplo, testa ou semeia os dados). Por exemplo

docker-compuse up -d
docker-compose run tools tests

Sim, o serviço de ferramentas aparecerá como "interrompido" em docker-compose ps . Se isso for inaceitável, a opção de vários arquivos de https://github.com/docker/compose/pull/2051 funciona. por exemplo

docker-compose -f docker-compose.yml -f docker-compose-tools.yml up -d
docker-compose -f docker-compose-tools.yml logs -f tools

Embora pareça que muitos auxiliares de orquestração estão sendo escritos para essa necessidade e eu sou culpado de trabalhar em um também :).

Pessoalmente, acredito que há soluções alternativas suficientes (como as duas acima; ser criativo com seus pontos de entrada / contêineres e / ou usar a abordagem de vários arquivos com um alias / auxiliar de shell) e a composição pode ser mantida simples.

@briceburg veja a discussão acima : o problema aqui não é sobre uma funcionalidade ausente que não poderia ser feita de outra maneira. Existem _são_ soluções alternativas para quase tudo que as pessoas aqui desejam alcançar. Mas são soluções alternativas e hacks sujos em vez de um caso de uso normal de docker-compose.

É uma questão de conveniência, sobre não ter que digitar docker-compose -f docker-compose.yml -f docker-compose-tools.yml up à mão no cli, é sobre não ter que se lembrar se era docker-compose run tools tests ou docker-compose run utils tests ou mesmo ter que confiar em um _múltiplas páginas “guia de primeiros passos do desenvolvedor” _ mas, em vez disso, tem uma interface unificada e simples para o desenvolvedor.

Mais uma vez, enviar Cópias @bfirsh, @dnephin: você poderia fornecer _qualquer_ feedback para esta questão? Há alguma esperança de que possamos ver algo assim no roteiro de docker-compose ??

@briceburg para um ambiente simples talvez uma solução alternativa seja aceitável, mas às vezes não é. Olhe minha configuração:

rancher<strong i="7">@rancher</strong>:~/servers/sgi/docker$ ls -l 
total 64
-rwxrwxr-x 1 rancher rancher  303 Dec  8 20:05 cleanup.sh
drwxrwxr-x 3 rancher rancher 4096 Dec 16 15:26 conf
drwxrwxrwx 4 rancher rancher 4096 Dec 15 20:03 data
-rw-rw-r-- 1 rancher rancher   94 Dec 14 19:40 docker-compose.amt.yml
-rw-rw-r-- 1 rancher rancher  295 Dec  8 20:05 docker-compose.auth.yml
-rw-rw-r-- 1 rancher rancher  332 Dec  8 20:05 docker-compose.ci.yml
-rw-rw-r-- 1 rancher rancher  112 Dec  8 20:05 docker-compose.dbext.yml
-rw-rw-r-- 1 rancher rancher  347 Dec 14 19:40 docker-compose.dbint.yml
-rw-rw-r-- 1 rancher rancher  688 Dec 15 16:31 docker-compose.full.yml
-rw-rw-r-- 1 rancher rancher   81 Dec  8 20:05 docker-compose.local.yml
-rw-rw-r-- 1 rancher rancher  288 Dec 15 16:31 docker-compose.yml
-rwxrwxr-x 1 rancher rancher  721 Dec 14 19:40 redeploy.sh
-rwxrwxr-x 1 rancher rancher  861 Dec  8 20:05 setup.sh
-rwxrwxr-x 1 rancher rancher   66 Dec  8 20:05 shutdown.sh
-rwxrwxr-x 1 rancher rancher  269 Dec 14 19:40 startup.sh
drwxrwxr-x 2 rancher rancher 4096 Dec 14 19:40 worker

Tenho 8 arquivos de composição (que utilizo em combinações múltiplas) além dos que estão no diretório worker , onde configuro os containers 'não inicie por padrão'. O diretório worker (com um arquivo .env vinculado ao pai e alguns arquivos de composição vazios para conformidade com a variável .env COMPOSE_FILE do pai) é minha solução alternativa, mas minha vida será muito mais fácil quando tivermos uma solução para esse assunto.

@vipseixas , é difícil avaliar a sanidade desta solução a partir de uma lista de arquivos - embora sim, eu concordo que ter a capacidade de não iniciar automaticamente um serviço está OK. Estou apenas sugerindo que você use um ponto de entrada / comando padrão que não faz nada para os serviços que você _não_ deseja iniciar automaticamente. Por exemplo, o contêiner simplesmente sai por padrão ... e executa esses serviços com um comando alternativo por meio da execução subsequente do docker-compose.

Na maioria dos casos, você desejará garantir que as verificações de integridade sejam aprovadas em serviços / contêineres dependentes antes de executar os testes - por exemplo, jenkins está ATIVADO e em execução (aceitando conexões em: 8080 ou qualquer outro) antes da execução desses testes. No passado eu usei dockerize para isso.

Se eu fosse propor uma solução mágica, seria permitir definir um perfil de composição via variáveis ​​ambientais (por exemplo, DOCKER_COMPOSE_PROFILE = "testes"), e permitir que os serviços sejam dependentes de um perfil - onde todos os serviços são padronizados como "padrão "perfil ou qualquer outro. Eu também garantiria que os serviços que dependem de outro serviço também sejam _dependentes_ do HEALTHCHECK desses serviços. Então algo como

app:
  image: myapp:v1

tests:
  image: myapp:tests
  dependencies:
    - profile: "tests"
    - service: "app"
      healthcheck: true
# run the things
docker-compose up -d

# test the things
DOCKER_COMPOSE_PROFILE="tests" docker-compose up -d
DOCKER_COMPOSE_PROFILE="tests" docker-compose logs -f

+1 para a opção 2.

Muitos aqui propuseram novos recursos interessantes, mas qual é o cerne da questão aqui? Eu voto para mantê-lo o mais simples possível.

Da forma como está hoje, assumimos que todos os serviços em nosso docker-compose.yml serão ativados em docker-compose up . Estamos todos trabalhando com nossos próprios scripts de bootstrap personalizados, makefiles, ferramentas de compilação, etc. e, felizmente, docker-compose e docker expõem uma extensa API para gerenciamento de contêineres individuais, uma vez que a pia da cozinha está 'levantada'.

Minha única necessidade, a necessidade básica que me trouxe a esta discussão, é especificar que um dos serviços que defini não é algo que desejo "ativado" por padrão, por qualquer motivo.

Qual é o recurso mais simples possível que "faz tudo" para todos nós? É uma pequena atualização da especificação docker- compose.yml ( autostart: false

Eu voto a favor: "APENAS FAÇA ALGO PARA NÓS, OBRIGADO." Votamos, agora precisamos de pelo menos uma resposta. 4 DEUS!

Qual é o recurso mais simples possível que "faz tudo" para todos nós? É uma pequena atualização da especificação docker- compose.yml (

Isso é muito melhor do que qualquer outra alternativa :)

@drew-r o quê?
image

@ jonathanborges1542 É docker-compose scale servname=2 . Não há equivalente no arquivo docker-compose.yml .

@drew-r scale: 0 atualmente diz ao docker daemon para enviar SIGTERM / SIGKILL para todos os contêineres do serviço. Isso eliminaria qualquer trabalho de manutenção, mesmo que ainda não tenha concluído seu trabalho. Esse é o comportamento esperado. Alterar isso seria um péssimo caso de sobrecarregar o que é um comportamento claro agora.

@gittycat entendo, mas o que queremos aqui é digitar "docker-compose up" e tudo estará pronto. Então, nesse caso, não funcionaria.

Acompanho este tópico há mais de um ano (a maioria das postagens está no docker).
Acredito que um novo "emprego" de nível superior convivendo com "serviços", "volumes" e "redes" seja a melhor opção. Essa é a opção 4 na lista de OP acima.
É também uma proposta no repo Docker.
https://github.com/docker/docker/issues/23880

@briceburg

é difícil avaliar a sanidade desta solução a partir de uma lista de arquivos

A intenção era apenas mostrar que tenho muitas combinações de arquivos e que usar várias opções "-f" é muito sujeito a erros para ser feito manualmente.

Estou apenas sugerindo que você use um ponto de entrada / comando padrão que não faz nada para os serviços que você prefere não iniciar automaticamente.

Às vezes, não há como escapar da desgraça. Mas eu prefiro minha solução: eu uso um diretório diferente que nunca será "composto" para que não haja containers inutilmente parados poluindo meu ambiente. É por isso que tenho um diretório de trabalho com um ".env" vinculado ao pai ".env".

Se eu fosse propor uma solução mágica, seria permitir definir um perfil de composição por meio de variáveis ​​ambientais (por exemplo, DOCKER_COMPOSE_PROFILE = "testes")

ESSA seria a melhor solução. Mas eu não acho que os desenvolvedores estão inclinados a aumentar a complexidade ...

Quero construir uma imagem de base, "estender" isso no mesmo docker-compose.yml e iniciar apenas a segunda imagem, o que não é possível em uma etapa no momento. Com a opção 2 será, mas talvez a maneira melhor e mais limpa seja ter um "estágio de construção" e um "estágio de execução", onde a criação de imagens de base é feita. No momento, tenho que executar 2 comandos e não apenas um.

+1 @ drew-r # 1661

Esse problema será implementado em algum momento ou é apenas algo que os desenvolvedores de composição não querem fazer? Seria bom saber para que a comunidade comece a procurar outra solução.

Já agora, voto na opção 2.

Obrigado

+1 para a opção 2.
No entanto, respeitaria dependências explícitas ... links etc?

Se eu estiver especificando qual serviço abrir com docker-compose up [service] , é raro que eu queira iniciar qualquer serviço diferente do serviço em questão e suas dependências.

Outro voto para a opção 2. Há até um PR para isso (https://github.com/docker/compose/pull/3047) que @acran foi gentil o suficiente para criar, então o esforço dos desenvolvedores de composição deve ser bem pequeno, pois eles só precisam revisá-lo (e é muito curto e simples) e não escrever nenhum código.

Se os desenvolvedores de composição não quiserem fazer isso, eles devem declarar de uma vez por todas, fechar o tíquete e bloqueá-lo para evitar comentários.

@msabramo compose é basicamente prejudicado pelo que é decidido no nível do motor docker.

A solicitação é rastreada no repo do docker engine https://github.com/docker/docker/issues/23880
É daí que virá a decisão / trabalho.

Eu sugiro que este assunto seja encerrado.

@gittycat compose ainda pode ter a opção de dizer ao mecanismo para iniciar um serviço ou não. Este é um pedido muito válido.

Desisto do docker na produção, há muitos problemas. Então eu migro para vagabundo.

Outro voto para 2)

Outra votação para 2 e 4.

Apenas para apontar um caso de uso, alguns serviços possuem dependências circulares, necessidade de geração de arquivos de configuração, execução de suítes de teste entre muitas outras possibilidades. Podemos separá-lo do Docker ou usar outras ferramentas, mas isso adiciona complexidade desnecessária à configuração do projeto.

Ter um comando simples para configuração e / ou para testes tornaria as coisas muito mais limpas.

Outro voto para 2!

Eu tinha lido este tópico, mas decidi criar um novo post (https://github.com/docker/compose/issues/4650), que foi fechado e fui encaminhado para cá. o ponto que eu gostaria de enfatizar é que, embora a maior parte da discussão neste tópico envolva sinalizadores para desabilitar contêineres em execução, meu caso de uso é de um terceiro estado: criar contêineres.

Eu gostaria não apenas de evitar que um contêiner seja executado, mas de nunca poder criar o contêiner em primeiro lugar (no meu caso de uso, tenho um processo orientado pelo usuário que faz isso)

@ekkis Estou curioso para saber como isso aconteceu. Meu caso de uso envolve referir-se à imagem do contêiner principal e configurar "ações" alternativas, poderia ser feito usando algo como bash, mas faz mais sentido usar o Docker.

Você poderia fornecer mais detalhes sobre o seu problema?

@frnco , não tenho certeza se entendi sobre o que você gostaria de mais detalhes. há casos em que você deseja construir uma imagem sem precisar da criação de containers. o meu é um desses casos. Eu quero uma determinada imagem construída junto com um monte de outras imagens, mas esta em particular será usada por um processo que escrevi. Não quero ter dois processos separados para construir e ter um sinalizador para build-only poderia resolver esse problema

@ekkis eu sugiro que você dê uma olhada no # 963, parece relacionado ao que você está procurando.

+1 para a opção 2

+1 para a opção 2

+1 para a opção 2

+1 para a opção 2

+1 para a opção 2

+1 para a opção 2

: +1: para a opção nº 2 com uma pergunta sobre qualquer estimativa deste recurso? Qual é a melhor solução alternativa? Até onde posso imaginar, preciso listar todos os meus serviços, como:

docker-compose up service1 service2 service3

... e omitir aqueles que não quero iniciar por padrão

Há alguma maneira de nós, da comunidade de código aberto, ajudarmos a contribuir com esse recurso que parece muito solicitado?

+1 para a opção 2.
Uma maneira de especificar 'estágio' seria ótimo. Digamos que o serviço funcione apenas na produção.

+1 para a opção 2.

Vote na opção 2

up filtragem de comandos docker-compose up service1 service3

: +1: para as opções 2 e 4

Neste ponto, parece que a opção 2 é o que os usuários desejam. Quais são as próximas etapas para fazer isso acontecer?

Aqui para +1 para a opção 2, deparei com esse problema esperando que essa funcionalidade já existisse.

+1 na Opção 2

... e mais um +1 para a opção 2

+1 para a opção 2

+1 para a Opção 2 :-)

+1 para as opções 2 e 4

Olá a todos,
+1 opção 2

IMHO, a opção será muito útil em ambientes locais, quando você tem aplicação baseada em micro-serviços ou com arquitetura hexagonal; como desenvolvedor, posso executar apenas os elementos necessários para meu trabalho mais próximo;

A opção 2 é aquela que a maioria dos usuários deseja. A decisão sobre isso ainda precisa ser tomada ou o desenvolvimento sobre isso já começou e está sendo rastreado em outro lugar?

Acho que quando terminar a universidade em alguns meses e tiver mais tempo, será muito mais rápido implementar esse recurso sozinho (embora eu não tenha aprendido Python, no qual acho que o compor está escrito), mas vi que imensa quantidade de votos e solicitações, por dois anos, sem nenhum avanço, e a auto-implementação parece ser a solução para os próximos 5 anos (até que essa funcionalidade seja implementada oficialmente).

claro que +1000 para a opção 2

+1 opção 2

Faria alguma diferença se eu votasse na opção 2? 'parece improvável que sim.

Os comentários aqui se tornaram amargos ultimamente e nenhum feedback novo realmente apareceu, o que está me fazendo considerar o bloqueio deste tópico. Por favor, seja civilizado ao interagir aqui.

Esta é a posição oficial atual da equipe de mantenedores sobre o assunto. Embora ainda esteja em consideração se queremos adicionar este recurso, ou um semelhante, como uma opção de conveniência, não é uma prioridade pelos motivos destacados e porque existem outras ferramentas que são mais adequadas para isso.

@ shin- Antes de bloquearmos isso, posso obter clareza se a comunidade está disposta a desenvolver a equipe principal, se isso atender aos padrões da equipe? Nos tópicos há uma implementação e um membro da comunidade querendo completá-la, eles estavam apenas procurando alguma confirmação de que não seria um desperdício de seu investimento. Se pudermos obter algum feedback, rastrearei esses tópicos para mover para ver se podemos mover isso para o encerramento.

@jimzucker Não - porque o problema aqui não é a implementação; uma implementação básica levaria meio dia para o desenvolvedor médio. O que nos preocupa aqui é uma questão fundamental de design.

  1. O que é um serviço? Por design, um serviço é um processo claramente definido e de longa duração que interage com outros serviços para formar um aplicativo. Essa é a suposição básica sob a qual o Compose opera e orienta nosso design para a maioria, senão todos os recursos que implementamos.
  2. Por essa definição, um "serviço que não é iniciado por padrão" não é realmente um serviço [1] - é mais uma tarefa predefinida, rodando em um contêiner e agindo no aplicativo, ao invés de fazer parte dele.
  3. Portanto, é errado (fundamentalmente por design) chamá-lo de serviço. Nesse ponto, precisamos considerar a criação de um novo tipo de definição em seu arquivo Compose (vou chamá-lo de "tarefa" para abreviar, a terminologia exata não importa aqui).
  4. Como as tarefas são processos inerentemente de execução curta, elas usam um conjunto diferente de opções em comparação com os serviços. Por exemplo, podemos intuir que as tarefas não precisam expor portas [2]. Por outro lado, uma opção como o arquivo CID, que geralmente é inútil para serviços, pode ser realmente útil para tarefas.
  5. Agora, na maioria dos projetos, as tarefas tendem a ter cadeias de dependências (é por isso que no mundo tradicional, não contêiner, temos Makefiles) - então precisamos ter pelo menos uma implementação básica de cadeias de dependências, com paralelismo e sendo capaz de dizer se aquela tarefa de compilação de JAR que sempre leva 10 minutos realmente precisar ser executada novamente.
  6. Então, alguns serviços realmente dependem da execução de tarefas antes de poderem ser iniciados, adicionando outro nível de complexidade à maneira como calculamos e tratamos as dependências.
  7. E algumas tarefas precisam de alguns serviços para serem executados (por exemplo, migração de banco de dados).

Neste ponto, isso se tornou um trecho de código inteiramente novo que provavelmente corresponde ou ultrapassa cmake em termos de escopo e complexidade. É por isso que resistimos a implementar isso por tanto tempo - em parte porque não é para isso que o Compose foi projetado, mas também porque [3] simplesmente não temos tempo ou recursos para implementar ou manter esse recurso precisaria se tornar para ser verdadeiramente útil às pessoas.

Espero que isso esclareça as coisas um pouco mais. Eu sei que as pessoas ficaram chateadas e desapontadas com a resposta (ou falta dela) neste tópico, e eu não tenho certeza se isso vai aliviar isso de alguma forma, mas aí está.

[1] Algumas pessoas mencionam o desejo de ter "serviços opcionais", mas esse não é o caso de uso mais comum mencionado neste tópico. A maioria das pessoas deseja o recurso de "tarefa", pelo que posso dizer.
[2] Tenho certeza que alguém vai me contradizer com um exemplo de tarefa que não precisa expor portas, o que só vai mostrar que o exercício de decidir quais opções são aplicáveis ​​a cada conjunto não é trivial.
[3] E neste ponto quero dizer "eu", já que sou o único mantenedor trabalhando ativamente em docker-compose no momento.

@ shin- eu entendo o ponto. O que estou buscando são "serviços opcionais" em suas notas de rodapé e os casos de uso para isso, não a ideia de tarefas, podemos de alguma forma concordar sobre como podemos progredir nesse ponto, já que essa é a parte do tópico que estou tentando defender e meus ingressos claramente nesse caminho foram fechados em favor deste tópico. Se pudermos separar isso dos pontos que você definiu claramente como 'tarefas', podemos fazer alguns progressos. Quando as pessoas estão fazendo um +1 para a opção 2 na minha leitura, é para o serviço opcional. Fico feliz em colocar isso off-line para discutir e então podemos voltar ao fórum, estou em [email protected]

@ shin- seu ponto # 2 está errado. um serviço é um serviço independentemente de estar em execução. existem inúmeros casos de uso em que os serviços dependentes modificarão o comportamento quando a dependência não estiver disponível, portanto, sua camada de aplicativo não pode, não deve, exigir que todos os "serviços" estejam disponíveis o tempo todo

se você pensar nisso nos termos mais tradicionais, considere que um servidor web é um "serviço", mas pode ser encerrado ou configurado para não iniciar por padrão em um determinado host, mas ninguém o consideraria outra coisa senão um serviço

Acho que muitas pessoas que estão solicitando esse recurso não querem executar tarefas, mas serviços opcionais. Por exemplo, se você tiver um conjunto de microsserviços em execução como contêineres do Docker e implantar todos eles como um serviço completo, talvez algum dia seus requisitos mudem e você não precise executar todos os contêineres em todos os seus servidores porque, nesse caso, você não precisa de uma funcionalidade específica incluída em um contêiner não obrigatório.

Além disso, acho que este é um bom recurso para o ambiente de desenvolvimento; se você está corrigindo um bug em um contêiner específico, não precisa iniciar todos os contêineres para ele.

Exatamente, com um campo booleano simples, poderíamos facilmente habilitar / desabilitar serviços do arquivo .env e evitar a edição do arquivo yaml.

@ekkis Acho que você está confundindo tolerância a falhas e dispensabilidade um pouco. Além disso, veja minha nota de rodapé sobre o assunto, onde reconheço que existem alguns casos de uso.

Todos: lembre-se de que se alguns serviços forem opcionais para seu aplicativo, já é possível lidar com isso com os recursos atuais. A maneira recomendada de fazer isso é ter um arquivo Compose separado que pode ser incluído ou excluído usando o sinalizador -f . Eles não são um argumento muito convincente para adicionar essa opção.

@ shin- Agradeço por dedicar seu tempo para ter esse diálogo conosco. Concordo que existem várias maneiras de fazer isso, pois você sugere vários arquivos yml, você também pode passar uma lista de serviços, mas estes não são convenientes e levam a erro do usuário criando risco operacional. Especialmente no caso de um produto comercial, queremos distribuir um arquivo de composição e, por padrão, obter o comportamento comum desejado e fornecer instruções para opções avançadas, um arquivo torna tudo isso muito mais organizado para desenvolvimento, CI / CD e distribuição. A adição de variáveis ​​ENV com padrões foi uma grande ajuda para nós e eliminou a necessidade de ter muitos arquivos yml, esta será mais uma etapa para gerenciar um único arquivo que descreve a implantação.

Existe alguma forma em que a equipe principal estaria disposta a aceitar uma contribuição neste LMK.

@shin , não fiz nenhuma referência a tolerância a falhas ou dispensabilidade. Eu apenas fiz uma observação sobre a definição de um "serviço", ou seja, se o serviço é executado ou não, não é inerente à definição

@ shin- Eu concordo totalmente com @ekkis : não ser iniciado _por padrão_ não viola a definição de ser um serviço, portanto, seu ponto 2. é uma suposição que não é _necessariamente_ verdadeira e assim são os pontos consecutivos, uma vez que são baseados em a suposição de 2.

Por exemplo: quando eu desenvolvo um aplicativo usando um banco de dados mysql, geralmente defino um _serviço_ adicional phpmyadmin . Este é um verdadeiro serviço: longa execução, portas expostas, dependentes de outros serviços.
Mas eu não quero iniciar este serviço _por padrão_, mas apenas _ sob demanda_ / em desenvolvimento.
Atualmente eu percebo isso colocando este serviço em um docker-compose.yml e iniciando-o fornecendo os dois arquivos para docker-compose - exatamente como você sugeriu acima.

Então, sim, já existem maneiras possíveis de conseguir isso; seja dividindo os serviços em vários arquivos ou simplesmente usando uma ferramenta diferente de docker-compose . Mas, como já escrevi acima : este problema não é sobre um recurso / funcionalidade totalmente novo ou um novo conceito (ou seja, _tarefas_), mas sobre a conveniência , especialmente em ambientes de desenvolvimento .
Ter que digitar docker-compose -f docker-compose.yml -f docker-compose-tools.yml up é tudo menos conveniente e, portanto, docker-compose não cumpre suas próprias promessas :

Juntos, esses recursos fornecem uma maneira conveniente para os desenvolvedores iniciarem um projeto. O Compose pode reduzir um “guia de introdução ao desenvolvedor” de várias páginas a um único arquivo Compose legível por máquina e alguns comandos.

Quais serviços iniciar ou quais yml arquivos usar em qual ambiente é algo que pode ser encontrado em _múltiplas páginas “guia [s] de introdução do desenvolvedor” _ - se for encontrado ...

Então, na minha opinião e como @jimzucker escreveu, a maioria dos + 1s aqui são realmente para "serviços opcionais" ao invés de um novo conceito de tarefas. Pelo menos todos eles ficam melhores com um booleano simples para sinalizar um _service_ para ser iniciado por padrão ou não.

Como meu PoC mostra, a mudança de código necessária - para "serviços opcionais" - é bastante gerenciável e fornece para a maioria das pessoas aqui um grande benefício em conveniência. Opção 2 - lida como "_possibilidade de marcar um serviço opcional_" - é um meio-termo razoável para resolver esse problema.

@ shin- você não concordaria em dar aos usuários a possibilidade de marcar serviços como opcionais - mas eles ainda são serviços - os ajudaria muito?
Quando reduzido a "marcar _serviços_ como opcionais / não iniciados por padrão", esse problema / uma solicitação de pull para isso seria aceito e mesclado?

@shin , para acrescentar ao ponto de @acran acima, posso querer que docker-compose construa apenas certos serviços porque esses serviços serão executados por outros serviços usando nomes . considere que toda vez que eu faço "up" eu recebo um monte de "serviços" chamados project_app_1 , project_otherapp_1 , etc. eles não fazem sentido, pois eles precisam ser executados usando informações em um banco de dados (eu tenho um serviço mestre que os inicia) . então eu sempre tenho que ir matá-los. então, para mim, um sinalizador NO_RUN ou BUILD_ONLY faz todo o sentido. isso seria conveniente

@acran

você não concordaria que dar aos usuários a possibilidade de marcar serviços como opcionais - mas eles ainda são serviços - os ajudaria muito?

Discordo sobre o quanto isso ajudaria - acho que "muito" é exagero. Em seu exemplo, apenas ter um docker-compose.phpmyadmin.yml que pode ser opcionalmente incluído não é mais oneroso ou complexo (em termos de instruções "guias do desenvolvedor") do que definir uma variável de ambiente / modificar uma definição de serviço dentro do arquivo principal.
Também estou considerando a possibilidade de dar aos desenvolvedores "armas de fogo" quando não for estritamente necessário.

Quando reduzido a "marcando serviços como opcionais / não iniciados por padrão", esse problema / uma solicitação pull para isso seria aceito e mesclado?

Veja acima - assim que este recurso estiver disponível, as pessoas começarão a usá-lo para outras coisas além do seu propósito pretendido e esperam que implementemos um novo conjunto de recursos para suportá-lo. Também cc @jimzucker ; Atualmente, não consigo pensar em uma implementação que impeça esse cenário de se desenvolver. Se eu pudesse, esse problema já teria sido encerrado há muito tempo.

@ekkis Se você nunca deseja iniciar esses serviços sozinho, por que exatamente é um problema

@shin se um docker-compose.yml pode ser usado para construir um serviço, é uma ferramenta muito útil para centralizar meu processo de construção. na verdade, faz muito sentido que eu queira (condicionalmente) criar um serviço antes de executá-lo e aplaudo essa funcionalidade

portanto, o arquivo docker-compose também é meu makefile . mas só porque construo algo não significa que quero executá-lo. não faz sentido para docker-compose presumir que eu quero executar um serviço, inventar um nome para ele e executá-lo sem parâmetros / variáveis ​​de ambiente adequados / etc.

francamente, não tenho certeza se entendi qual é a objeção a este patch simples. seria muito útil para mim

Eu claramente apontei em meu post anterior porque a posição oficial da equipe era que você não deveria usar seu arquivo Compose como um Makefile. Se você acredita que estamos errados e ainda deseja fazê-lo, essa é sua prerrogativa, mas é um pouco absurdo insistir que adicionemos recursos para apoiá-lo.

@canela-

Em seu exemplo, apenas ter um docker-compose.phpmyadmin.yml que pode ser opcionalmente incluído não é mais trabalhoso ou complexo (em termos de instruções "guias do desenvolvedor") do que definir uma variável de ambiente / modificar uma definição de serviço dentro do arquivo principal.

Na verdade, ainda não pensei em envolver variáveis ​​de ambiente aqui. Meu fluxo de trabalho desejado "serviços opcionais" finalmente permitiria:

  • Eu copio / clono um novo projeto
  • Vejo que há um (único) arquivo docker-compose.yml nele, portanto, eu sei, tudo o que tenho a fazer é executar docker-compose up e o aplicativo é compilado e executado
  • Agora eu quero iniciar um dos serviços opcionais para fins de desenvolvimento (por exemplo, depuração adicional, phpMyAdmin). Tudo o que tenho que fazer é docker-compose up phpmyadmin .

Para mim, isso é _muito_ mais conveniente do que usar vários arquivos docker-compose.yml e, pelo que entendi, para a maioria das outras pessoas aqui também. A vantagem de ter "serviços opcionais" aqui é

  • para o desenvolvedor não ter que duplicar nada entre vários arquivos ou ter que considerar cuidadosamente quais definições colocar em qual arquivo, mas apenas ter que definir um sinalizador booleano ( auto_up: false ) em um serviço
  • para o usuário não ter que saber / lembrar quais arquivos incluir para quais serviços: eu preciso executar

    • docker-compose -f docker-compose.phpmyadmin.yml up

    • docker-compose -f docker-compose.yml -f docker-compose.phpmyadmin.yml up ou mesmo

    • docker-compose -f docker-compose.phpmyadmin.yml -f docker-compose.yml up ?

  • em vez disso, a única coisa que o usuário precisa _saber_ é que existe um serviço chamado phpmyadmin e o usuário sabe imediatamente como iniciá-lo.

Veja acima - assim que este recurso estiver disponível, as pessoas começarão a usá-lo para outras coisas além do seu propósito pretendido e esperam que implementemos um novo conjunto de recursos para suportá-lo

Não me interpretem mal, não apenas entendo sua preocupação aqui, mas concordo com ela: sempre haverá usuários que dobrarão este - ou qualquer outro (!) - recurso para se adequar aos fluxos de trabalho desejados, mesmo que os recursos nunca tenham sido feitos para funcionar usado assim.
MAS para qualquer solicitação de "serviços opcionais" que faltam recursos de uma "tarefa", você pode _então_ facilmente argumentar que os serviços não são tarefas e as tarefas precisam ser apresentadas como um novo conceito primeiro e, portanto, não são suportadas (ainda). Ou seja, qualquer coisa mais do que apenas marcar um serviço como opcional é um passo em direção ao conceito de tarefas (por exemplo, opção 4) e há uma distinção clara entre eles.

Com o recurso de marcar um _serviço_ como opcional, ainda estamos do lado direito desse corte. "O recurso em si não é muito complexo de implementar, mas _pode_ levar os usuários a usá-lo incorretamente", sendo atualmente o único argumento real (embora válido!) Contra esse recurso é bastante insatisfatório como uma razão para não implementá-lo - pelo menos para os usuários que poderiam obter mais conveniência ao usá-lo da maneira correta ™.

Estou prestes a rebasear minha solicitação de pull # 3047 para o mestre atual e fazer qualquer polimento necessário para que isso seja aceito, por favor, me avise;)

Meu caso de uso é que não enviamos todas as nossas imagens para docker hub ou quay, nem temos nosso próprio registro, e ser capaz de marcar um serviço como não-para-ser-executado-por-padrão significa que podemos tem uma imagem de base definida em docker-compose.yml que não é iniciada e, em seguida, outros contêineres usando ou construindo sobre ela.

Eu estaria inclinado a usar um fork docker-compose que implementa este recurso apenas para este recurso singular.

@ shin- Embora eu ache que todos nós entendemos seu ponto e simpatizamos com ele, não acho que "pode ​​ser mal utilizado" é um bom argumento para algo com - claramente - muitos casos de uso viáveis. Claro que _será_ mal utilizado. É exatamente assim que o software e as novas ideias crescem; de usar a tecnologia não inteiramente como deveria ser. A web não seria o que é hoje se não tivéssemos feito mau uso de toda a tecnologia fornecida nos últimos 25 anos.

De qualquer forma.
Na sua opinião - simplificado - a diferença entre um serviço e uma tarefa é o tempo de vida. Faz sentido, e entendo que você os veja como dois conceitos diferentes e sinta que é uma lata de vermes em potencial. Mas essa distinção não é esclarecida ou exposta em nenhuma parte da documentação. Nem é apontado em lugar nenhum que docker não se destina a ser usado para girar processos temporais.
O que quero dizer é que, se a equipe do docker tem uma posição forte sobre isso, isso deve ficar claro desde o início.
Além disso. Tarefa ou serviço, há claramente uma sobreposição. E marcar um serviço como opcional definitivamente não é algo que pertence exclusivamente ao lado da tarefa.
De um ponto de vista prático, definitivamente concordo com @acran - ter um único arquivo docker-compose é muito melhor DX, simplifica muito e é menos sujeito a erros do que ter vários arquivos docker-compose.

Hehe, eu me lembro das discussões ferozes que tivemos quando estávamos fazendo lobby para permitir que "navegadores" para exibir imagens, com o principal argumento dos opositores é que ele é chamado de protocolo de transferência
Desculpe pelas reminiscências de um velho peido no AT.

@ shin- se o docker-compose não deve ser usado como um makefile, então ele não deve fornecer a funcionalidade makefile. se me permite construir meus projetos (bravo!) então assumir a posição de que não é um makefile é ridículo

@ shin- look, vocês não precisam implementar nenhum recurso que não desejem, não importa quão irracionais sejam seus motivos ou quão útil seja o recurso. apenas torna a ferramenta menos útil para aqueles de nós que a usam. nós somos os usuários, conhecemos os casos de uso - e as ferramentas são tão úteis e valiosas quanto atendem aos casos de uso

isso para mim é apenas uma pequena irritação, eu tenho que matar manualmente um monte de coisas que são geradas sem uma boa razão _ toda vez que eu inicio meus serviços_. para outros pode ser um impedimento, a irritação vai variar em gravidade

Eu entendo que a posição oficial é que devemos usar dobi, mesmo que seja um exagero para o que precisamos. mas essa posição oficial não explica a base de sua relutância em aceitar um RP útil. ainda podemos usar dobi quando a demanda no docker-compose é muito grande ou a sobreposição é suficiente para migrar, mas esta é uma mudança muito pequena que tornaria todas as nossas vidas muito melhores

e, incidentalmente, não estou sendo "áspero", mas travar o fio para evitar discussões adicionais seria simplesmente antidemocrático e autoritário. o código aberto é construído com base no princípio da abertura e ficaria triste em ver este projeto administrado usando censura e táticas ditatoriais

@rysiekpl Este é um problema que estamos tentando resolver de uma maneira diferente, consulte https://github.com/docker/cli/pull/452 (uma vez que a sintaxe for deliberada, ela fará o seu caminho para Compose e v2 como bem)

@creynders Acho que isso é uma caracterização incorreta - ninguém está dizendo que serviços opcionais não deveriam existir (e de fato, como indiquei, existem maneiras de declará-los usando arquivos separados). Isso é mais semelhante a debater se não fechar explicitamente uma tag <img> é válido e se nosso navegador específico deve suportá-lo ou não.

Além disso, para o seu ponto:

Mas essa distinção não é esclarecida ou exposta em nenhuma parte da documentação. Nem é apontado em lugar nenhum que docker não se destina a ser usado para girar processos temporais.

Este é na verdade o primeiro parágrafo da página https://docs.docker.com/compose/overview/ (grifo meu):

Compose é uma ferramenta para definir e executar aplicativos Docker de vários contêineres. Com o Compose, você usa um arquivo Compose para configurar os serviços do seu aplicativo. Então, usando um único comando, você cria e inicia todos os serviços de sua configuração.

@ekkis Estou muito feliz que Compose seja de fato útil para seus projetos! Espero não parecer insincero em tudo isso, está tudo bem se é assim que você deseja usar o software. O que estou dizendo, porém, é que ir mais longe nessa direção provavelmente pioraria as coisas a longo prazo. Todos nós sabemos o que acontece com aplicativos que tentam fazer muitas coisas (embora eu ache que o Emacs conseguiu: stick_out_tongue:)

Não acho que estava sendo "autoritário", mas talvez não tenha me expressado direito. Minha intenção era encorajar as pessoas a permanecerem civilizadas e positivas em suas interações. O tópico ainda está desbloqueado e continuará a ser, desde que as pessoas não sejam maldosas ou indelicadas.

você cria e inicia todos os serviços de sua configuração.

e acho que nosso argumento é que deveria ter lido "criar e / ou iniciar", embora, para ser justo com a linguagem, não seja necessário indicar o OR porque está implícito no AND. em outras palavras, é verdade que você pode criar e iniciar um serviço, mas não há implicação de que ele deve fazer as duas coisas

Todos nós sabemos o que acontece com aplicativos que tentam fazer muitas coisas

sim, posso perceber que você está gerenciando as fronteiras do domínio

Eu não acho que estava sendo "autoritário"

Eu amo o movimento de código aberto. podemos ter nossas divergências, mas ainda estamos nisso juntos. as guerras dentro da comunidade bitcoin foram terríveis e acho que ainda estou me recuperando disso, então obrigado por permanecer do lado da civilidade

como um pensamento de despedida, eu pediria que você revisse https://github.com/docker/compose/issues/4650 que não é o mesmo que o pedido neste tópico (como você indicou ao fechá-lo), mas acomoda meu uso caso, ou seja, que o sinalizador que está sendo discutido aqui não é binário, mas trinário

Eu realmente gosto da ideia de definir vários arquivos. No entanto, incluir todos os arquivos com multi -f incluindo o original parece ser um exagero total.

Na verdade, existe uma maneira mais prática, que funciona para mim (veja PS abaixo): coloque todos os serviços que você não deseja executar em docker-compose.override.yml . E use docker compose -f docker-compose.yml up para inicialização normal (note que este é um comando único). Em todas as chamadas consecutivas, a substituição será originada ...

No geral, tudo isso é muito pouco intuitivo e um pouco insatisfatório. Adicionando um adicional:

  • uma opção para desativar serviços faz sentido, especialmente para substituições mais complexas

  • A opção -f é mínima, mas não muito intuitiva, outra opção -F <name> que apenas adiciona substituições adicionais seria muito bem-vinda (isto é, docker-compose..yml. Uma alternativa seria usarcomo um diretório em que todos os arquivos .yml são originados: junto com os links simbólicos, isso seria similarmente poderoso como /etc/apache/sites.available -> /etc/apache/sites.enabled

Por outro lado: qualquer um poderia fornecer um script (função) empacotador simpe para seu shell para emular este comportamento ...

PS: meu caso de uso é definir um depurador como um serviço. Obviamente, este serviço não é necessário o tempo todo, mas precisa dos links (também por razões de segurança) para funcionar corretamente.

Outro caso de uso para o qual a Opção 2 é excelente:

Digamos que você tenha uma equipe de pessoas trabalhando no mesmo projeto. Alguns deles têm acesso aos serviços gerenciados da AWS, mas alguns deles precisam executar os recursos correspondentes como contêineres locais. Portanto, dependendo do meu fluxo de trabalho, _sempre_ ou _nunca_ precisarei de contêineres Redis e MySQL em minha constelação de composição.

Vou afirmar que o gerenciamento de vários arquivos de composição é estúpido para este caso de uso. A quantidade de sobreposição é cômica. Manter vários arquivos é uma merda - eles _serão_ fora de sincronia e causarão confusão. Estou francamente um pouco chocado que alguém levou essa opção a sério para _qualquer_ caso de uso.

Ser capaz de habilitar e desabilitar serviços rapidamente, sem comentar grandes blocos de configuração (estranho em YAML, muito confuso se cometido acidentalmente), é ótimo por si só. Mas se o compor algum dia conseguir interpolar variáveis ​​na configuração, esse recurso se tornará exponencialmente mais poderoso. Até então, é _meramente_ útil.

Concordo totalmente com @campadrenalin.

Toda essa discussão, no meu entender, é basicamente um grande número de pessoas fornecendo um grande número de boas razões para implementar a Opção 2, e os desenvolvedores se recusando porque alguém hipoteticamente poderia interpretar mal a existência desse recurso e solicitar alguns outros recursos não relacionados .

OT:

Mas se o compor algum dia conseguir interpolar variáveis ​​na configuração, esse recurso se tornará exponencialmente mais poderoso.

Este recurso não está disponível há muito tempo? Consulte https://docs.docker.com/compose/compose-file/#variable -substitution. Eu estou usando-o para permitir a personalização do nosso ambiente dev Compose usando o .env arquivo - por exemplo, localização de código fonte, porta mapeamento etc. Desde arquivo compor a versão 2.1 até a variável de estilo shell default ( ${VARIABLE:-default} / ${VARIABLE-default ) é compatível.

Toda essa discussão, no meu entender, é basicamente um grande número de pessoas fornecendo um grande número de boas razões para implementar a Opção 2, e os desenvolvedores se recusando porque alguém hipoteticamente poderia interpretar mal a existência desse recurso e solicitar alguns outros recursos não relacionados .

Acho que este é - talvez um tom um pouco áspero, mas válido em essência - um ótimo resumo de @rysiekpl.
Então, @ shin-, chegamos mais perto de uma decisão sobre esse assunto? Quer apenas fechá-lo ou implementar / aceitar um PR para a opção 2?

Eu vejo e entendo totalmente suas preocupações, mas também vejo que as vantagens superam o risco de alguém potencialmente abusar disso, já que é uma mudança um tanto pequena, mas oferece a muitas pessoas muito mais possibilidades para fluxos de trabalho muito mais _convenientes_.

Como docker-compose parece ter sido abandonado a longo prazo em favor do docker stack de qualquer maneira, sugiro que todos mudem para o novo formato v3 e a ferramenta docker stack assim que possível.

Usando uma pilha em um enxame (mesmo em 1 nó), você pode especificar isto:

        deploy:
            mode: replicated
            replicas: 0

Ter zero réplicas basicamente desativa a execução do serviço.

Você só precisará de alguma outra ferramenta para gerar esse yml se quiser aplicar substituições de variáveis ​​de ambiente, como envsubst.

Você pode então usar um marcador de posição em seu yml:

        deploy:
            mode: replicated
            replicas: ${R}

E processe desta forma:

export R=0
docker stack deploy stack1 --compose-file=<(envsubst <docker-compose.yml) 

Portanto, se docker-compose se tornará obsoleto a longo prazo, qual é exatamente o problema de mesclar a solicitação pull que já existe ? Quero dizer, se docker-compose está indo bem, como "alguém vai solicitar recursos estranhos" é um problema real?

Como docker-compose parece ser abandonado em longo prazo em favor do docker stack

Portanto, se docker-compose for descontinuado a longo prazo

espera, o que é? docker-compose é fundamental para muitas pessoas em seu fluxo de trabalho de desenvolvimento, que quase não precisa de um gerenciador de enxame. Você poderia me indicar alguma declaração oficial de Docker a esse respeito?

Posso estar lendo errado, mas parece que o docker swarm e o docker stack estão intimamente ligados aos docker cloud services. Essas coisas são configuráveis ​​em um sistema autônomo e offline?

Essas coisas são configuráveis ​​em um sistema autônomo e offline

sim, você pode usá-los offline.

Para mim, parece que as pilhas do docker-swarm acabarão sendo um superconjunto dos recursos do docker-compose. Acho que os arquivos descritores já são muito semelhantes. Felizmente, essa transição não será muito difícil. O maior aborrecimento que posso ver é gerenciar o enxame separadamente da (s) pilha (s). Mais sobrecarga para mim, já que não tenho interesse em executar aplicativos compostos em mais de um nó.

Ou talvez eu esteja entendendo mal tudo ...?

+1 na opção 2!
E eu acho que a redução do docker compose em favor do swarm stack será uma grande desvantagem para a comunidade. Docker compose é tão simples e fácil de usar !!

@tberne eu concordo com isso. docker-compose é simples e simples é uma coisa boa. devemos votar para mantê-lo

Heh, que discussão extensa! Não preste muita atenção a este comentário, apenas meus dois centavos.

No início, concordei com a maioria em apenas adicionar uma espécie de bandeira enabled .
Então eu vi uma proposta para ramificar as definições por grupos e considerei uma boa ideia.
Então eu li sobre o Dobi, experimentei, assegurei-me de que ele não poderia ser usado no meu projeto agora e continuei lendo.
Então eu li os argumentos de @ shin- e os considerei bons o suficiente, apesar de também concordar com alguns contra-argumentos.

Minha solução atual é criar alguns yamls docker-compose e escrever alguns scripts de empacotamento bash para não executar docker-compose manualmente.

Por exemplo, é assim que executo contêineres que executam um site ( ./docker/scripts/up script):

#!/usr/bin/env bash

def_opts="-d"

cd "$(dirname "$0")"/../

# A separate bash file with functions like: get_args, add_hosts...
. ./functions.sh

docker-compose -p ${PROJECT} up ${def_opts} $(get_args "options services" "$@") && \

# Adding host to /etc/hosts
add_hosts "$HOSTS" web && \
add_hosts "$HOSTS_MAIL" mail

Grande +1 para a Opção 2 ou 3.

+1 para a Opção 2 ou 3.

Além disso, o conceito de "grupo" proposto parece interessante!

+1 para a opção 2

_Há tantos +1 on option x , que nem consigo encontrar o extrato original. Em vez disso, use os botões de reação abaixo das postagens._

Para adicionar uma nova ideia:

Não podemos simplesmente definir uma escala padrão para 0 ?

web:
  image: busybox:latest
  command: echo 'scaled'
  scale: 0

Você deve apenas fazer a opção 2 (mas talvez não inicie em vez disso ou algo assim) porque as pessoas têm esperado anos agora, em seguida, envolvendo docker-compose com seus próprios gerenciadores de configuração porque a ferramenta é muito limitada, o que frustra o ponto, pois está fazendo o que docker compose deveria fazendo. Em dois anos, alguém poderia criar sua própria composição docker mais poderosa. Esse problema está aberto há muito tempo.

No longo prazo, deve haver alguma consideração sobre o verdadeiro agrupamento de opções. Alguns são relevantes apenas para construir, alguns apenas para executar e alguns são mútuos (você realmente quer uma camada de aninhamento pelo menos para executar ou apenas separar e ter uma seção de construção, problema resolvido). Atualmente, embora muitas coisas sejam problemáticas na configuração, eu só quero refazer tudo na versão 5, mas acertando naquele momento (principalmente representando o real em um domínio de nível técnico em vez de tentar fazer com que ele mapeie um uso domínio baseado ou excessivamente simples, em vez disso, crie uma camada de configuração para esses objetivos em cima da correta, você não pode fazer isso ao contrário). Acho que por causa desse estado de coisas, a solução rápida se justifica.

+1 para a opção 2 ou 4

Se não houver planos para adicionar esse recurso atualmente, quero que a maneira de executar esses serviços (ou tarefas) em uma composição seja escrita nos documentos do docker-compose.

Este é um tópico antigo e concordo que docker-compose não se importará com _serviços que não serão executados desde o início_.

Mas eu também normalmente adiciono um serviço test , então aqui está o que eu fiz:

  1. Substitua entrypoint do serviço.
  2. No novo entrypoint , verifique se há um tty disponível ( docker-compose run usa --tty por padrão, enquanto up não).

    # Check if there is a tty
    if [ ! -t 1 ] ; then
      echo "No tty available."
      exit 0
    fi
    

    Isso sempre fará com que o serviço saia quando executado sem tty (com docker-compose up , por exemplo) enquanto ainda executa como esperado com docker-compose run

@paulodiovani Isso parece mais um hack do que uma solução.

1 para uma solicitação de recurso.
hacks como ter comandos que não fazem nada significa que mesmo se o contêiner não for executado, ele ainda terá que ser construído, inicializado etc.

Resolvi isso em meu projeto fornecendo um script bash simples que chama o comando docker-compose apropriado com base nos argumentos fornecidos.

Agora, se eu fizer ./docker-compose.sh -e testing up , o resultado será o mesmo de docker-compose -f docker-compose.yml -f docker-compose.testing.yml up .
Se eu apenas fizer ./docker-compose.sh up , obtenho, como você esperaria, docker-compose up normais.

Portanto, minha opção -e ${environment} (abreviação de --env ) é basicamente um apelido para -f docker-compose.yml -f docker.compose.${environment}.yml . Isso resulta em docker-compose.yml sendo o arquivo de composição base / padrão e arquivos como docker-compose.testing.yml sendo suas extensões.

Isso resolve de alguma forma o problema de @acran de o usuário não saber quais arquivos incluir (e em qual ordem) para o comando docker-compose , impondo padrões sãos. Não é uma solução muito robusta, pois alguns podem usar combinações de composição de arquivo mais complexas, mas acho que docker-compose deve ser capaz de fazer algo semelhante. A maioria dos arquivos docker-compose provavelmente começam com docker-compose. e terminam com .yml qualquer maneira, então porque eu sempre tenho que digitar um comando tão longo ( docker-compose -f docker-compose.yml -f docker-compose.testing.yml up ) se eu só precisar de um único serviço adicional para meu ambiente de teste?

Não há necessidade de envsubst, docker-compose config faz as variáveis ​​de ambiente e, em seguida, docker stack pega de stdin:

docker-compose config | docker stack deploy --prune --compose-file -

Vamos usar as substituições docker-compose .env também.

@kogli Acho que o problema aqui é escolher uma opção. Todos têm prós e contras. Como eu disse antes:

Cada solução será melhor para alguns casos de uso e pior (ou até mesmo inútil) para outros. Se algo for implementado, os mantêm para sempre, então acredito que eles são sábios em não se apressar.

@ shin- Acho que é você quem deve perguntar: faz sentido considerar isso? Considerando a posição atual da equipe, o quão difícil é projetá-la e as muitas ferramentas que existem, não seria mais fácil simplesmente dizer às pessoas que isso não vai acontecer? A maioria das pessoas, senão todos os que comentaram aqui, encontraram uma maneira de lidar com isso.

Fechar isso parece muito bom, além disso, você pode se concentrar nas coisas que importam, e ninguém se pergunta se eles devem fazer uma solicitação de pull e como atender a todas essas necessidades ao mesmo tempo. Eles podem simplesmente construir outra coisa e talvez até publicá-la para ajudar outras pessoas.

Só para constar : minha solução não foi perfeita, mas muito melhor do que os 2 dias que levei para instalar as dependências e consertar um monte de coisas e fazer o projeto rodar (e já usava Docker). Apenas 3 comandos, com Docker e Docker Compose como as únicas dependências. Sim, havia mais código do que eu queria. Sim, há uma ordem de merda para executar comandos. E sim, há um pouco mais para se manter em mente. Uma página Wiki cobriu isso. Muito bom, se é que posso dizer, o que significa que o Docker Compose fez o seu trabalho , eu também precisava de algo mais .

A questão é: se estiver fora do escopo, é perda de tempo continuar discutindo isso. Muitas pessoas param por aqui para perguntar sobre isso e dar sua opinião, antes de tentarem decidir o que fazer. Eles ainda encontrarão ou construirão outra coisa se for fechado, apenas mais rápido. E você ganha um fio a menos para cuidar.

Edit: Acabei de pensar em uma boa maneira de colocá-lo: se não houver critérios claros para aceitar RP e não houver ninguém na equipe principal envolvido com isso ou planejando dar uma olhada em um futuro próximo, não é um " problema ", apenas uma ideia.

Não vejo razão para bagunçar a lista de questões, acredito que muitas ideias aqui são boas, mas acho que elas pertencem a outro lugar, para o bem ou para o pior. Já faz quase 3 anos, e na chance de que um dia a situação mude, você sempre pode reabrir isso, ou abrir um novo fascículo sobre isso.

Esse recurso leva cerca de um dia para implementar porque é muito simples. Porém, após 2 anos de discussões, ainda nada. Triste.

@rubycut Sim, é o que acontece quando os chamados "princípios superiores" substituem a usabilidade e a facilidade de uso. Eu entendo perfeitamente que os desenvolvedores não querem obstruir o produto com recursos ilógicos. No entanto, esse recurso específico altamente solicitado realmente parece fazer sentido. É triste quando os desenvolvedores pensam que sabem mais do que seus usuários. (Novamente, eles costumam fazer. Mas nem sempre. Não desta vez.)

@rubycut Talk é barato, mostre-me o código. Se puder, envie seu PR, se não puder, apenas denuncie e aguarde.

@wangwenpei Você está brincando comigo? Em primeiro lugar, você não é o mantenedor deste projeto. Se os mantenedores aceitarem essa idéia e colocarem a tag "procura-se ajuda", tenho certeza de que alguém poderia contribuir com a solicitação de pull. Mas eles disseram que não estão interessados. Então, por que se preocupar puxará a solicitação se ela não for aceita.

Apenas para sua informação, "o código" já está lá: # 3047

@wangwenpei bem, # 3047, aí está o pedido de puxar ...
esperando para obter pelo menos algum feedback sobre ele há mais de dois anos. Foi fechado recentemente

pelos motivos destacados em https://github.com/docker/compose/issues/1896#issuecomment -322285976

o que me irrita bastante para ser honesto porque os argumentos fornecidos em https://github.com/docker/compose/issues/1896#issuecomment -322285976 não se relacionam de forma alguma com a solicitação pull:

  1. O que é um serviço? Por design, um serviço é um processo claramente definido e de longa duração que interage com outros serviços para formar um aplicativo. Essa é a suposição básica sob a qual o Compose opera e orienta nosso design para a maioria, senão todos os recursos que implementamos.
  2. Por essa definição, um "serviço que não é iniciado por padrão" não é realmente um serviço [1] - é mais uma tarefa predefinida, rodando em um contêiner e agindo no aplicativo, ao invés de fazer parte dele.

Não vejo a afirmação By that definition, a "service that is not started by default" is not really a service como verdadeira. Um serviço que não é iniciado por padrão é apenas um serviço que não é iniciado por padrão, nada mais, nada menos neste ponto. Ser iniciado por padrão ou não não diz nada sobre o serviço ser demorado ou não, ser parte do aplicativo ou não, apenas diz que não deve ser iniciado por padrão.

E isso também é exatamente o que a mudança na solicitação pull faz: adicionar a capacidade de marcar um serviço para ser iniciado por padrão ou não.
Não há necessidade de introduzir um novo conceito, como tarefas para fazer isso. Na verdade, todos os outros argumentos em https://github.com/docker/compose/issues/1896#issuecomment -322285976 seguem da falsa premissa de 2. e, portanto, não são aplicáveis ​​ao pull request que não tenta fazer nada outro.

Apenas para completar:

[1] Algumas pessoas mencionam o desejo de ter "serviços opcionais", mas esse não é o caso de uso mais comum mencionado neste tópico. A maioria das pessoas deseja o recurso de "tarefa", pelo que posso dizer.

Sim, houve exemplos de tarefas únicas, mas também houve exemplos para serviços _real_ de acordo com sua definição, ou seja, casos de uso legítimos para este recurso.
Ser capaz de usar isso para _também_ executar tarefas únicas, não posso aceitar como um argumento válido contra isso. é possível definir um _service_ que não é de longa duração, não expondo quaisquer portas e não é uma parte essencial da aplicação de uma forma totalmente válida docker-compose.yml .

Na verdade, essa também é uma das soluções alternativas sugeridas! Apenas divida as _tarefas_ em docker-compose.yml separados.
As outras soluções alternativas mencionadas são usar seus próprios scripts caseiros (dependentes da plataforma), o que contradiz totalmente o propósito declarado de docker-compose, veja meu comentário acima , ou simplesmente mudar para outra ferramenta, ou seja, jogue fora seu perfeitamente conjunto de ferramentas funcionando bem apenas para obter este pequeno recurso em conveniência que poderia ser facilmente implementado em seu conjunto de ferramentas atual (docker-compose).

O único argumento real levantado contra a implementação mais básica da opção 2 - ou seja, ter _uma maneira_ de dizer a docker-compose para não iniciar um serviço específico por padrão, e nada mais, nenhum conceito novo ou qualquer coisa - é que isso poderia be_somehow_ ser mal utilizado por _alguns_ usuários.
Mas esse argumento é bastante fraco em comparação com a demanda por ele e os casos de uso legítimos levantados aqui ...

@canela-

mas também porque nós [3] simplesmente não temos tempo ou recursos para implementar ou manter o que esse recurso precisaria para ser verdadeiramente útil para as pessoas.
[3] E neste ponto eu quero dizer "eu", já que sou o único mantenedor trabalhando ativamente no docker-compose no momento.

Por um lado, destacar que há apenas um mantenedor ativo e, por outro lado, apenas ignorar as solicitações de pull e, portanto, desperdiçar qualquer oportunidade de talvez envolver outros desenvolvedores no projeto não é algo que eu poderia compreender.
As mudanças de código fornecidas em # 3047 já _do_ implementam um recurso que seria _realmente útil para [muitas] pessoas_ - talvez não _todos_ as pessoas com _todos_ seus_ casos de uso, mas a maioria das pessoas aqui.

Todos os requisitos adicionais - ter que introduzir conceitos completamente novos, gerenciamento de novas dependências, até uma complexidade semelhante a cmake - simplesmente seguem de uma premissa falsa!

Eu me deparei com esse problema há apenas alguns dias porque estava procurando um recurso como este.

Como infelizmente não foi implementado, e pelo que pude constatar, a alternativa oficialmente suportada é usar vários arquivos yaml.

Bem, acho a ideia de usar vários arquivos yaml para serviços não executados por padrão uma alternativa pobre em comparação ao uso de um arquivo yaml para todos os serviços que contêm uma configuração adicional para cada serviço não executado por padrão.

Então, aqui está o meu +1.

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