Seguindo o Docker + Laravel =? Quero falar sobre uma maneira bastante incomum de usar o utilitário docker-compose.
Para iniciantes, para aqueles que não sabem por que a composição do docker é necessária. Este é um utilitário que permite executar em um host separado um conjunto de serviços relacionados empacotados em contêineres de janela de encaixe. A versão inicial foi escrita em python e pode ser instalada de duas maneiras:
- via gerenciador de pacotes do sistema operacional (
apt install docker-compose
para Ubuntu e yum install docker-compose.noarch
for Centos) - via gerenciador de dependência python (
pip install docker-compose
)
O problema com o primeiro método é o que normalmente ocorre nos repositórios do sistema operacional docker-compose da versão antiga. Esse é um problema se você precisar usar a versão mais recente do daemon do docker ou usar recursos específicos para uma versão específica do formato de arquivo docker-compose.yaml (uma matriz de recursos suportados por versões de formato e versões do utilitário docker-compose pode ser encontrada no site oficial do docker).
Agora desenvolvedores de docker reescreveu o utilitário em movimento , cometeu um erro, na verdade empacotou o script python com o ambiente em um único pacote e o forneceu como um arquivo binário, o que permite a instalação da seguinte maneira (este é o método recomendado atualmente):
Examinamos a versão mais recente em https://github.com/docker/compose/releases e a baixamos
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
definir os direitos para executar o aplicativo
$ sudo chmod +x /usr/local/bin/docker-compose
Além disso, você pode definir o preenchimento automático para os interpretadores de comandos bash e zsh
verifique a instalação
$ docker-compose --version docker-compose version 1.22.0, build 1719ceb
Eu acredito que um único binário é muito legal, porque não precisamos extrair dependências python. Sim, e em geral - talvez nosso ambiente python esteja completamente quebrado na máquina de destino, que queremos configurar !!!

Exemplo de confusão no ambiente python
Mas ainda existe um quarto caminho, sobre o qual eu queria falar. Essa é a capacidade de executar o docker-composer através do docker. De fato, já existem imagens oficiais coletadas no Docker Hub ( https://hub.docker.com/r/docker/compose/ ). Por que eles podem ser necessários?
- se queremos trabalhar com várias versões do docker-compose ao mesmo tempo (embora geralmente a última versão estável seja suficiente)
- se não temos python ou não queremos usá-lo (por exemplo, temos uma distribuição leve do CoreOS Container Linux )
- uso em pipelines de CI / CD.
Vamos tentar!
Como costumamos lançar contêineres:
$ docker-compose up -d
Por meio de um utilitário empacotado em um contêiner de docker:
$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$PWD:/rootfs/$PWD" -w="/rootfs/$PWD" docker/compose:1.13.0 up -d
Muito detalhado, hein? O cérebro pode ser quebrado para lembrar todos esses parâmetros. Portanto, tentaremos facilitar nossa vida e escrever um wrapper na linguagem shell. Mas primeiro, vejamos os parâmetros passados:
--rm
- remove o contêiner temporário após a parada, ou seja, não deixamos lixo no sistema-v /var/run/docker.sock:/var/run/docker.sock
- sem isso, o docker-compose não poderá se conectar ao daemon do docker no host-v "$PWD:/rootfs/$PWD" -w="/rootfs/$PWD"
- permite encaminhar o diretório atual dentro do contêiner para que o utilitário veja o arquivo de composição de encaixe
Ainda não temos a capacidade de interpolar valores no arquivo de composição de encaixe. Este é o processo pelo qual o utilitário substitui variáveis de ambiente em um arquivo YAML. Por exemplo, em um fragmento
version: "2.1" services: pg: image: postgres:9.6 environment: POSTGRES_USER: ${POSTGRES_DB_USER} POSTGRES_PASSWORD: ${POSTGRES_DB_PASSWORD}
as variáveis POSTGRES_DB_USER
e POSTGRES_DB_PASSWORD
serão lidas no ambiente. Isso torna possível modelar arquivos de encaixe com um certo grau de conveniência. I.e. precisamos capturar o ambiente da máquina host e transferi-lo para dentro do contêiner.
Vamos resolver o problema escrevendo um script bash.
#!/bin/sh # TMPFILE=$(mktemp) # env > "${TMPFILE}" # VERSION="1.13.0" # docker-compose docker run \ --rm \ -e PWD="$PWD" \ --env-file "${TMPFILE}" \ -v /var/run/docker.sock:/var/run/docker.sock \ -v "$PWD:/rootfs/$PWD" \ -w="/rootfs/$PWD" \ docker/compose:"${VERSION}" \ "$@" # rm "{$TMPFILE}"
Apareceram linhas adicionais:
-e PWD="$PWD"
- por precaução, encaminhe o diretório atual--env-file "${TMPFILE}"
- aqui todas as outras variáveis de ambiente são transferidas da máquina hostdocker/compose:"${VERSION}"
- o nome da imagem, pegue a versão da variável"$@"
- essa construção permite que você use o script como se fosse o utilitário docker-compose, ou seja, transmite de forma transparente seus argumentos para o contêiner do docker.
Podemos salvar o script, por exemplo, em /usr/local/bin/docker-compose
, defina o sinalizador eXecute e use-o. O script acima não finge estar 100% livre de erros ou deficiências e é mais uma ilustração do método.
Nós mesmos usamos pipelines de CI / CD dessa maneira. Isso até economiza algum tráfego até certo ponto. A imagem de destino da janela de encaixe é obtida do cache local.