|
|
Esta página descreve as propriedades utlizadas nos arquivos Dockerfile e docker-compose que são utlizados em alguns projetos do Labes e faz parte do [Catálogo do LabES](../home).
|
|
|
|
|
|
## Definição
|
|
|
|
|
|
### O que é Docker, Dockerfile e Docker Compose?
|
|
|
|
|
|
Docker é uma forma de rodar aplicações em seu computador sem precisar instalar nada além do Docker. Ele funciona criando um ambiente isolado para a aplicação, chamado de **container**, que contém tudo o que a aplicação precisa para rodar. Isso inclui o código da aplicação, as bibliotecas necessárias e até mesmo o sistema operacional. Essas informações são armazenadas em um arquivo chamado **Dockerfile**, que é usado para criar o container.
|
|
|
|
|
|
Para aplicações mais complexas, onde são necessárias várias aplicações rodando juntas, o Docker oferece o **docker-compose**. O docker-compose é uma ferramenta que permite definir e rodar aplicações em vários containers, chamados de serviços, de forma simples e rápida. Ele usa um arquivo chamado **docker-compose.yml** para definir as propriedades de cada serviço e como eles se comunicam.
|
|
|
|
|
|
## Como usar/aplicar?
|
|
|
|
|
|
### Como rodar uma imagem Docker ?
|
|
|
|
|
|
Para rodar uma imagem Docker, basta usar o comando `docker run` seguido do nome da imagem. Por exemplo, para rodar a imagem `node:14`, basta rodar o comando `docker run node:14`. Caso seja necessário, é possível passar opções adicionais para o comando, como as portas que serão expostas ou os volumes que serão montados. Para ver a lista de opções disponíveis, basta rodar o comando `docker run --help`.
|
|
|
|
|
|
### Como criar uma imagem Docker ?
|
|
|
|
|
|
Para criar uma imagem Docker, é necessário criar um arquivo **Dockerfile** na raiz do projeto com as instruções para criar a imagem. O **Dockerfile** é um arquivo de texto que contém uma série de instruções que são executadas em ordem para criar a imagem. As instruções mais comuns são:
|
|
|
|
|
|
- **FROM**: A imagem base que será utilizada para criar a sua própria imagem.
|
|
|
- **RUN**: Comandos que serão executados durante a criação da imagem.
|
|
|
- **COPY**: Copia arquivos da sua máquina (host) para o ambiente virtualizado (container).
|
|
|
- **WORKDIR**: Define o diretório de trabalho do container, parecido com o comando `cd`.
|
|
|
- **EXPOSE**: Porta que será exposta pelo container.
|
|
|
- **CMD**: Comando que será executado quando o container for iniciado.
|
|
|
|
|
|
### Exemplo de Dockerfile
|
|
|
|
|
|
```dockerfile
|
|
|
# Dockerfile
|
|
|
|
|
|
FROM node:14
|
|
|
|
|
|
WORKDIR /app
|
|
|
|
|
|
COPY package.json .
|
|
|
|
|
|
RUN npm install
|
|
|
|
|
|
COPY . .
|
|
|
|
|
|
CMD ["npm", "start"]
|
|
|
```
|
|
|
|
|
|
Neste exemplo, criamos um **Dockerfile** para uma aplicação Node.js. A imagem base utilizada é a `node:14`, o diretório de trabalho é definido como `/app`, o arquivo `package.json` é copiado para o diretório de trabalho, as dependências são instaladas com o comando `npm install`, todos os arquivos são copiados para o diretório de trabalho e o comando `npm start` é executado quando o container é iniciado.
|
|
|
|
|
|
### Como rodar uma imagem Docker com docker-compose ?
|
|
|
|
|
|
Para usar o docker-compose, basta criar um arquivo docker-compose.yml na raiz do projeto com as propriedades dos serviços que serão rodados. Depois, basta rodar o comando `docker-compose up` na raiz do projeto para rodar os serviços. Caso seja necessário, é possível passar a flag `-d` para rodar os serviços em segundo plano. Para parar os serviços, basta rodar o comando `docker-compose down`.
|
|
|
|
|
|
### Quais propriedades são utilizadas no docker-compose.yml ?
|
|
|
|
|
|
O arquivo docker-compose.yml é um arquivo YAML que contém as propriedades dos serviços que serão rodados pelo docker-compose. Lembre-se que arquivos YAML são whitespace sensitive, e portanto cada identação e espaçamento é importante. As propriedades mais comuns são:
|
|
|
|
|
|
- **version**: A versão do docker-compose que está sendo utilizada. A versão mais recente é a 3.8.
|
|
|
- **services**: Uma lista de serviços que serão rodados pelo docker-compose. Cada serviço é definido por um nome e suas propriedades.
|
|
|
- **image**: A imagem do Docker que será utilizada para rodar o serviço. A imagem é um arquivo que contém o sistema operacional e as bibliotecas necessárias para rodar a aplicação.
|
|
|
- **ports**: As portas que serão expostas pelo serviço. Isso permite que a aplicação seja acessada de fora do container.
|
|
|
- **volumes**: Os volumes que serão montados pelo serviço. Isso permite que a aplicação acesse arquivos fora do container.
|
|
|
- **environment**: As variáveis de ambiente que serão passadas para o serviço. Isso permite configurar a aplicação de forma dinâmica.
|
|
|
- **depends_on**: Os serviços que o serviço depende. Isso permite definir a ordem de inicialização dos serviços.
|
|
|
|
|
|
### Exemplo de docker-compose.yml
|
|
|
|
|
|
```yaml
|
|
|
# docker-compose.yml
|
|
|
|
|
|
version: '3.8'
|
|
|
services:
|
|
|
app:
|
|
|
image: node:14
|
|
|
ports:
|
|
|
- 3000:3000
|
|
|
volumes:
|
|
|
- .:/app
|
|
|
environment:
|
|
|
- NODE_ENV=development
|
|
|
depends_on:
|
|
|
- db
|
|
|
db:
|
|
|
image: postgres:13
|
|
|
ports:
|
|
|
- 5432:5432
|
|
|
environment:
|
|
|
- POSTGRES_USER=postgres
|
|
|
- POSTGRES_PASSWORD=postgres
|
|
|
```
|
|
|
|
|
|
Neste exemplo, temos dois serviços: `app` e `db`. O serviço `app` utiliza a imagem `node:14`, expõe a porta `3000`, monta o volume atual na pasta `/app`, define a variável de ambiente `NODE_ENV` como `development` e depende do serviço `db`. O serviço `db` utiliza a imagem `postgres:13`, expõe a porta `5432` e define as variáveis de ambiente `POSTGRES_USER` e `POSTGRES_PASSWORD` como `postgres`.
|
|
|
|
|
|
Outra forma de executar uma imagem docker é criando a sua própria imagem com um arquivo **Dockerfile**, e ao invés de utilizar a propriedade **image** no arquivo **docker-compose.yml**, utilizar a propriedade **build** e passar o caminho do diretório onde se encontra o **Dockerfile**.
|
|
|
|
|
|
```yaml
|
|
|
# docker-compose.yml
|
|
|
|
|
|
version: '3.8'
|
|
|
services:
|
|
|
app:
|
|
|
build: <path_to_Dockerfile>
|
|
|
ports:
|
|
|
- 3000:3000
|
|
|
volumes:
|
|
|
- .:/app
|
|
|
environment:
|
|
|
- NODE_ENV=development
|
|
|
```
|
|
|
|
|
|
## Bônus: Espelhando a pasta do host no container
|
|
|
|
|
|
Caso queira desenvolver em sua máquina e ver as alterações refletidas no container, é possível espelhar a pasta do host no container. Para espelhar a pasta do host no container, é necessário utilizar a propriedade **volumes** no arquivo **docker-compose.yml**. A propriedade **volumes** permite montar um volume no container, que pode ser um diretório ou um arquivo do host. Assim como fizemos no exemplo anterior, onde montamos o volume atual na pasta `/app`, podemos montar qualquer pasta do host no container.
|
|
|
|
|
|
Perceba a diferença entre fazermos o **COPY** de arquivos do host para o container e montar um volume no container. No primeiro caso, os arquivos são copiados para o container durante a criação da imagem, enquanto no segundo caso, a pasta é montada no container durante a execução, e mantém essa ligação mesmo que os arquivos sejam alterados no host. Permitindo que você faça alterações no código no host e veja essas alterações refletidas no container.
|
|
|
|
|
|
## Referências
|
|
|
|
|
|
- [Docker Documentation](https://docs.docker.com/)
|
|
|
- [Docker Compose Documentation](https://docs.docker.com/compose/)
|
|
|
- [Docker Hub](https://hub.docker.com/)
|
|
|
- [Dockerfile Reference](https://docs.docker.com/engine/reference/builder/)
|
|
|
- [Docker Compose File Reference](https://docs.docker.com/compose/compose-file/) |