// pull image
docker run ubuntu
// download withoug execute it
docker pull nome_usuario/nome_image
// list all open containers
docker ps
// list id's containers
docker ps -q
// list all containers
docker ps -aq
//list all image
docker image ls || docker image
// remove all images
docker rmi $(docker images -q)
// remove one image
docker rmi name_image
// init container
docker start name_container
// stop all cotainners
docker stop $(docker ps -aq)
// run one container attached the terminal to it
docker run -it name_image
// stop one container
docker stop (name or id)
// remove container
docker rm (id or name) -f // (-f if it was running)
// remove all containers stoped
docker container prune
// run one container with port and name and dettached
docker run -d -p 80:8080 --name server nginx:latest
// add network in create container
docker network create --driver bridge local
// stop the current container and remove it after get out
docker-compose down --rmi all
// copy schema mysql
docker exec container_mysql_name /usr/bin/mysqldump -u root --password=root schema > backup.sql
// util image web containers
docker run --name postgres11 -e POSTGRES_PASSWORD=docker -p 5432:5432 -d postgres:11
// run one mongo container
docker run --name mongo -p 27017:27017 -d -t mongo
// run one detached container
docker run --detach --name=mysql8 -p 3306:3306 --env="MYSQL_ROOT_PASSWORD=docker" mysql:8.0.22
// remove all
rm -rf /var/lib/docker
Imagine o cenário, precisamos configurar uma image pessoal para subir um conainer em um determinado servidor, com o doker hub podemos facilmente ter images pessoais privadas(plano não gratuito no docker hub), assim podemos usa-las quando e onde quisermos, grandes datacenter também vão ter seus próprios registers, por exemplo digamos que temos uma conta na digital ocean, basta termos nosso register privado lá e conseguiremos ter nossas images privadas para subir em nosso servdor remoto.
Muitas vezes removemos os containers após o uso.
É muito comum usar o container e apagá-lo após o uso, dessa forma os dados desse container são perdidos e nesse ponto entram os volumes ou mount que permitem salvar dados fora de um container.
Volumes são usados para os dados não serem removidos ao paramos nosso container, trata-se de um mapeamento entre seu host (computador de trabalho) e container, na maioria dos projetos que trabalhamos em ambiente de dev costumamos fazer um apontamento entre nossa maquina e algum container.
docker run -d --name nginx -v ~/ti/testdocker/html:/usr/share/nginx/html -p 8080:80 nginx
No exemplo acima apontamos um volume de nossa maquina local por meio da tag -v para dentro da pasta do nginx, dessa forma se perdemos nossa imagem o conteúdo está salvo em nosso host.
A forma mais atual de se trabalhar é com volumes é utilizando mouts, um exemplo de diferença entre volumes e mouts é que volumes criam pastas em nosso host mesmo que essas não existam, mounts não.
docker run -d --name nginx --mount type=bind,source=/Users/andremartds/ti/testdocker/html,target=/usr/share/nginx/html -p 8080:80 nginx
docker run -d --name nginx --mount type=bind,source="$(pwd)",target=/usr/share/nginx/html -p 8080:80 nginx
Caso você utilize $(pwd) esse cara vai conseguir pegar o diretório absoluto de onde você está no momento.
Pode ser que precisemos ter um volume centralizado em nosso host e queremos apontar esses dados para um ou mais containers, nesse caso tudo que for criado em um container será apontado para os outros que compartilham desse type.
requer estar na mesma rede*
// commands
docker volume
// create volume
docker volume create myvolume
// list every volumes in your register
docker volume ls
// remove volumes
docker volume prune (hash volume)
// inspect volumes
docker volume inspect myvolume
Criando e utilizando um volume
// cria um volume
docker volume create myvolue
// rodando uma imagem e atrelando nosso novo volume com -v
docker run -d -p 8082:80 --name nginx24 -v myvolume:/app nginx
// ou
docker run -d -p 8080:80 --name nginx1 --mount type=volume,source=myvolume,target=/app nginx
//e
docker run -d -p 8081:80 --name nginx2 --mount type=volume,source=myvolume,target=/app nginx
// acessando o container para criar um arquivo
Para acessar um container ativo precisamos utilizar o docker exec
docker exec nginx ls //lista os diretorios da pasta root do container
docker exec nginx -it bash // acessa o container com nosso bash local
Agora que acessamos nosso container vamos alterar o arquivo index do nginx
cd /usr/share/nginx/html
apt update
apt install vim
vim index.html // altere seu arquivo html
// use i para inserir
// :q para sair
// :wq para sair e salvar
// esq para parar de inserir
Perceba o conceito images, elas são IMUTÁVEIS ou seja, caso nosso container seja removido ao reutilzarmos a imagem que temos em nossa máquina a mesma virá sem as alterações que acabamos de fazer
A partir de um Dockerfile (receita de uma imagem) conseguimos definir diversas configurações extras para nosso container, imagine que você precisa de volumes, redes portas e ainda precisa utilizar isso para subir posteriormente para um servidor e utilizar.
O Dockerfile é um facilitador pois nele podemos definir muitas características e comandos para nosso container.
crie em um diretório um arquivo com o nome Dockerfile
FROM nginx:latest
RUN apt update
RUN apt install vim -y
agora que criamos nossa primeira imagem vamos construi-la para ficar salva em nosso register local.
docker build -t andremartds/nginx-com-vim .
No comando acima nós construimos nossa imagem com as características que colocamos no nosso arquivo Dockerfile, ou seja adicionamos o vim ao nginx
docker run -it andremartds/nginx-vim-example bash
agora que criamos a imagem podemos executar a mesma.
vamos nos basear neste Dockerfile e descrever os comandos abaixo.
FROM nginx:latest
WORKDIR /app
RUN apt update
RUN apt install vim -y
COPY html /usr/share/nginx
Criando um diretório de trabalho dentro de um Dockerfile, interessante que ao logar no container já iniciaremos neste diretório /app
workdir /app
Copiando de uma pasta do nosso computador para dentro do container
COPY html /usr/share/nginx
// html em nosso computador
// /usr/share/nginx nosso caminho dentro da imagem para o nginx
para executar comandos no dokcer podemos utilizar o CMD
FROM ubuntu:latest
workdir /app
CMD ["echo", "hello world"]
no exemplo acima criamos uma nova imagem baseada no ubuntu, adicionamos o diretório de trabalho e posteriormente adicionamos o CMD
docker build -t andremartds/ubuntu-test .
da forma acima iremos criar a imagem, o ponto significa que estamos no diretório onde se encontra o Dockerfile
docker run --rm andremartds/ubuntu-test echo 'oi oi'
agora perceba que no exemplo acima estamos reescrevendo a saída do CMD, essa é a uma das funcionalidades do CMD.
docker run -it andremards/ubuntu-test bash
é da mesma forma, ao executarmos o comando acima ele faz uma substituição do que existe dentro da imagem para podemos executar e acessar diretamente um container
FROM ubuntu:latest
WORKDIR /app
ENTRYPOINT [ "echo", "Hello " ]
CMD [ "world" ]
O grande ponto da image acima é que nela temos o entrypoint e o cmd, pense que o cmd pode servir tanto para executar comandos mas também serve para enviar parametros para o entrypoint.
docker build -t andremartds/ubuntu123 .
docker run --rm andremartds/ubuntu123 // retorna Hello world
docker run --rm andremartds/utuntu123 oioi // retorna Hello oioi
Por muitas vezes vemos containers que acessam arquivos de shell, basicamente esses arquivos são executados a partir do nosso comando
ENTRYPOINT["docker-entrypoint.sh"]
então dentro de nossa image temos uma chamada para esse arquivo, ao final desse arquivo podemos ter o seguinte.
//cat docker-entrypoint.sh
exec "$@"
com essa entrada acima vamos poder executar CMD posteriormente em nossa dockerfile ou linha de comando
o primeiro passo é criar a nosso arquivo html para jogar dentro do nginx - index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Dedev é lindo</h1>
</body>
</html>
agora na mesma pasta vamos definir nosso Dockerfile
FROM nginx:latest
COPY html /usr/share/nginx/html
ENTRYPOINT [ "/docker-entrypoint.sh" ]
CMD [ "nginx", "-g", "daemon off;" ]
No exemplo acima baseamos nossa image na image do nginx, e por isso trazemos algumas características dela para dentro do nosso container, adicionamos o entrypoint e o CMD, outro ponto a se notar nesse arquivo é que estamos fazendo uma copia de html para dentro do html do nginx.
agora vamos subir nossa imagem
docker build -t -d andremartds/nginx-personalizado
docker login
// usuario e senha de seu hub.docker.com
docker push andremartds/nginx-personalizado
Pronto, como o register do docker é publico então a imagem está disponível para download na internert, da seguinte forma.
docker run andremartds/nginx-personalizado
Tipo de network
- Bridge O tipo de network mais comumn no docker é esse tipo, utiliza-se essa rede quando vamos fazer com que um container se comunica com outro
- Host Ele mescla a network do docker com a do host, ou seja tanto o host quanto o docker ficam na mesma rede
- Overlay para um container comunicar com outro em maquinas diferentes eles precisam estar nesse tipo de rede, também é utilizado pelo docker swarmer
- Maclan
- none sem rede, de forma isolada
docker network // lista os comandos do network
docker network ls // lista todas as redes
docker network prune // mata todas as networks que nao estão sendo utilizadas
// criando um rede
docker network create -d bridge my-bridge-network
// criando container atrelado a rede
docker run -d -it ubuntu1 --network minharede
docker run -d -it ubuntu2 --network minharede
docker run -d -it ubuntu3
// conectando um container a network
docker network connect minharede ubuntu3
docker inspect network minharede
// acesse seus containers e instale
apt-get update
apt-get install iputils-ping
agora basta acessar pingar para ver a conexão entre os containers
docker exec -it ubuntu1 bash
ping ubuntu2
// outro terminal
docker exec -it ubuntu2 bash
ping ubuntu1
com essa rede basicamente conseguimos atrelar a rede do docker ao nosso host, vamos ao exemplo.
docker run -d --it --name nginx --network host nginx
dessa forma tanto o container quanto o host terão o mesmo host
Fazendo com que o container acesse a nossa maquina atravéz de uma porta, é um pouco estranho isso. mas podemos precisar desse recurso.
digamos que temos um node rodando na porta 3333, por algum motivo precisamos acessar esse cara de dentro do nosso container, vamos aos passos para isso.
// rodando nosso node no host local, digamos que nosso projeto está na porta 3333
npm run dev
// app rodando na 3333
Nesse ponto vamos acessar nosso container que precisa acessar esse recurso
docker run -it ubuntu
# curl http://host.docker.internal:3333
Dessa forma conseguimos acessar o nosso host, ou seja. bastaria puxar uma rota e seguir a vida acessando por exemplo uma entrada a uma api
// example of Dockerfile FROM node:latest MAINTAINER andremartds/mynode COPY . /var/www // copia do . para /var/www WORKDIR /var/www // diretório de trabalho RUN npm install // comando para rodar o node e instalar ENTRYPOINT npm start // ponto de entrada EXPOSE 3000 // expomos a porta 3000
// ... other behaviors
para rodar esse container é muito simples, com o docker ativo no seu computador execute
docker build -f Dockerfile
esse comando vai criar uma imagem a partir do Dockerfile
Vamos logar na nossa conta e enviar o nosso container
docker login
docker push nome_usuario/nome_image
enviamos a imagem para o docker hub
Vamos compor um docker-compose.yml
version: '3'
services:
nginx:
build:
dockerfile: ./docker/nginx.dockerfile
context: .
image: douglasq/nginx
container_name: nginx
ports:
- "80:80"
networks:
- production-network
depends_on:
- "node1"
- "node2"
- "node3"
mongodb:
image: mongo
networks:
- production-network
node1:
build:
dockerfile: ./docker/alura-books.dockerfile
context: .
image: douglasq/alura-books
container_name: alura-books-1
ports:
- "3000"
networks:
- production-network
depends_on:
- "mongodb"
node2:
build:
dockerfile: ./docker/alura-books.dockerfile
context: .
image: douglasq/alura-books
container_name: alura-books-2
ports:
- "3000"
networks:
- production-network
depends_on:
- "mongodb"
node3:
build:
dockerfile: ./docker/alura-books.dockerfile
context: .
image: douglasq/alura-books
container_name: alura-books-3
ports:
- "3000"
networks:
- production-network
depends_on:
- "mongodb"
networks:
production-network:
driver: bridge
Agora vamos buildar esse yml
// docker compose
docker-compose build
// -d dettached
docker-compose up -d
// stop compose rellationships in this yml
docker-compose down
docker build de fato constrói o container
docker compose up sobe todos os containers relacionados ao build pré feito
docker-compose down para todos os container relacionados ao yml