Neste post vou falar um pouco sobre Docker Compose e como usá-lo em desenvolvimento, estou usando Docker version 1.10.2
e docker-compose version 1.6.2
.
Que diabos é Docker Compose?
O Docker Compose é uma ferramenta para definição e execução de aplicações Docker multi-container. Isso significa que com ele você pode definir várias aplicações como container e executá-las de uma única vez sem precisar executar várias vezesdocker build -t [myuser]/[appname] . && docker run [myuser]/[appname]
. Isso é uma mão na roda gigante :).
Como o Docker Compose pode me ajudar?
Usando o compose em apenas um arquivo você define as dependências do seu ambiente: banco de dados, bancos nosql, variáveis de ambiente, serviços e etc e em seguida com apenas um comando você sobe todo essa pilha e já pode usar. Sua equipe agora precisa apenas executar:git clone [repo] && docker-compose build && docker-compose up
e já pode trabalhar.
Hands ON
Vamos imaginar uma app simples, um hello world por exemplo :D, farei este teste usando Ruby, Primeiro de tudo temos que criar umDockerfile
, nele iremos definir a imagem que iremos usar e os comandos necessários para importar nossa app para o container.
RUBY - Dockerfile
FROM ruby
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install
ADD . /app/
Em seguida vamos criar um arquivo chamado docker-compose.yml
e definir os serviços nele. Serviços são uma espécie de alias para o containers que vão ser criados ex: web - para aplicações web, db - para banco de dados. Você pode definir quantos serviços quiser, desde que possuam nomes diferentes, pois quando os containers forem levantados esses "apelidos" serão usados na comunicação entre eles.
Obs: para saber mais sobre a questão de versão do docker-compose acesse https://docs.docker.com/compose/compose-file/#versioning
Ruby - docker-compose.yml
version: '2'
services:
web:
build: .
command: bundle exec ruby hello.rb
ports:
- "3000:3000"
volumes:
- .:/app
environment:
PORT: 3000
Depois de definido o Dockerfile
e o docker-compose.yml
vamos agora fazer nossos apps helloworld.
Para ruby ireo usar o Sinatra.
Ruby - estrutura do diretório
.
├── docker-compose.yml
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── hello.rb
└── scripts
└── run
Ruby - Gemfile
source 'https://rubygems.org'
gem 'sinatra'
gem 'sinatra-contrib'
Ruby - hello.app
require 'sinatra'
require "sinatra/reloader" if development?
set :bind, '0.0.0.0'
set :port, ENV['PORT']
get '/' do
"You are in home"
end
get '/:name' do
"Hello #{params['name']}!"
end
Executando os containers
Para executar os containers vamos rodar o seguinte o comando no root da aplicaçãodocker-compose up
. Esse comando fara com que os containers sejam levantados e os comandos definidos no docker-compose.yml e no Dockerfile sejam executados.
Como vocês devem ter percebido na estrutura de diretórios tem uma pasta chamada scripts
, com um script chamado run
. Eu faço isso para facilitar minha vida, nesse script tem apenas uma linha com o comando citado acima, então quando quero rodar os containers apenas faço ./scripts/run
.
Após rodar o comando é só acessar localhost:3000 para a aplicação Ruby, qualquer alteração feita na aplicação será replicada no container por conta do mapeamento de volumes que fizemos no docker-compose.yml
volumes:
- .:/app
Executando comandos dentro do container
Caso precisem executar comandos dentro do container vocês pode fazer da seguinte maneira:docker-compose run web [comando]
ex:
$ docker-compose run web ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
Instalando novas depedências no projeto
Sempre que uma nova dependência for adicionada ao projeto é necessário executardocker-compose build
para que uma nova imagem seja criada com as dependências instaladas.
É isso aí pessoal, divirtam-se!!! O reposótio com os exemplos está aqui: https://github.com/gwmoura/hello-docker-compose;)