Acredito que você nesta altura do campeonato já saiba o que é o docker mas se ainda não sabe, não se preocupe, você pode aprender tudo sobre ele no meu curso: Domine Docker do Zero ao Deploy! que está incluso no pacote de assinatura vitalício da Certbest, acesse: https://certbestlinux.com/
Usabilidade e para quem se destina?
O objetivo deste artigo não é tanto instalar ou usar o MacOS. O desempenho do sistema serve apenas para quem quer conhecer o sistema da apple ou para quem é desenvolvedor e quer testar um Aplicativo simples. Mas não dá para ser usado no dia a dia. O objetivo deste artigo é ensiná-lo a usar o docker compose.
E através deste tutorial com o MacOS aprender como tudo isto funciona.
Como o docker funciona?
Mas simplificando tudo, vamos fazer uma analogia para entender como ele funciona:

O navio cargueiro e o contêiner de transporte
Antes da invenção do contêiner marítimo padrão, carregar um navio era um caos. Sacos de café, barris de vinho, pianos e peças de ferro eram empilhados juntos. Se o vinho vazasse, estragava o café; se o piano fosse pesado demais, esmagava os barris. Além disso, cada porto tinha um jeito diferente de carregar, o que tornava tudo lento e sujeito a erros.
O Docker resolveu o mesmo problema no mundo do software.
1. O Problema: “Na minha máquina funciona”
Imagine que seu software é como uma carga delicada. Ele precisa de uma versão específica do Python (o “barril”), de uma biblioteca de segurança (o “saco de café”) e de certas configurações de rede. Quando você move esse software do seu notebook para um servidor na nuvem, as versões mudam, o sistema operacional é outro e… BOOM, o sistema para de funcionar.
2. A Solução: O Contêiner Docker
O Docker permite que você coloque o seu código e tudo o que ele precisa para rodar dentro de uma caixa lacrada (o Contêiner).
- A Imagem (O Projeto): É como a planta técnica do contêiner. Ela diz exatamente o que deve haver lá dentro.
- O Contêiner (A Instância): É a caixa física em si. Não importa se ela está em um navio (servidor Linux), em um caminhão (seu notebook) ou em um trem (nuvem). O que está lá dentro está isolado e vai funcionar da mesma maneira em qualquer lugar.
- O Docker Engine (O Navio/Guindaste): É o motor que carrega, descarrega e executa esses contêineres. Ele garante que um contêiner não interfira no outro.
3. O Docker Compose (O Manifesto de Carga)
Se o Docker é o contêiner individual, o Docker Compose é o plano de carga do navio. Ele diz: “Coloque o contêiner do macOS na porta 8006, conecte-o ao volume de armazenamento X e certifique-se de que ele tenha acesso ao hardware KVM”.
Por que isso é revolucionário para você?
- Isolamento: Você pode testar uma distribuição Linux dentro de um contêiner sem bagunçar os arquivos do seu sistema principal.
- Reprodutibilidade: Quando eu passar minha configuração:
docker-compose.yml, o macOS que você vai subir sera exatamente com as mesmas configurações que o meu, sem que você precise instalar manualmente qualquer dependência. - Leveza: Diferente de uma Máquina Virtual (VM) tradicional, que carrega um “navio” inteiro (um sistema operacional completo com kernel) para cada carga, o Docker compartilha o kernel do sistema hospedeiro, tornando tudo muito mais rápido e eficiente.
Basicamente, o Docker transformou a “arte” de configurar servidores em uma linha de montagem industrial, onde tudo é padronizado, seguro e fácil de transportar.
O docker compose
O Docker Compose é uma ferramenta (um binário que hoje faz parte do comando docker) usada para definir e rodar aplicações de múltiplos containers.
Imagine que você precise rodar uma aplicação que depende de um banco de dados, um servidor web e um sistema de cache. Em vez de digitar três comandos docker run gigantescos, com dezenas de flags de rede e volume, você descreve tudo em um único lugar.
A diferença fundamental:
- Docker CLI (
docker run): É imperativo. Você diz ao Docker exatamente o que fazer: “Crie este container, use esta porta, conecte nesta rede”. - Docker Compose: É declarativo. Você descreve o “estado desejado” da sua infraestrutura no arquivo YAML, e o Compose se vira para transformar o estado atual (nada rodando) no estado desejado (tudo configurado).
2. Como ele funciona com arquivos YAML?
O arquivo YAML (Yet Another Markup Language) é escolhido pela sua legibilidade. No contexto do Docker, ele funciona como um manual de instruções estruturado.
A Estrutura do Arquivo
Um arquivo Compose geralmente é dividido em três seções principais:
- Services (Serviços): Aqui você define os containers. No seu caso do macOS, o “serviço” é o container
macos. Se você tivesse um banco de dados junto, ele seria outro serviço. - Networks (Redes): Define como os containers conversam entre si. Por padrão, o Compose cria uma rede isolada para que todos os serviços do arquivo se enxerguem pelo nome.
- Volumes (Persistência): Define onde os dados serão salvos permanentemente no seu host (o diretório
~/docker/mac, por exemplo).
O Processo de Execução
Quando você digita docker compose up, acontece o seguinte:
- Parsing: O Docker lê o seu arquivo
.ymle verifica se a sintaxe está correta. - Criação de Recursos: Ele cria a rede e os volumes definidos antes de subir os containers.
- Pull/Build: Ele verifica se a imagem (ex:
dockurr/macos) existe localmente. Se não, ele baixa automaticamente. - Convergence: O Docker compara o que está rodando no seu Linux com o que está no arquivo. Se você mudar a memória de 8G para 16G no arquivo e der um
upnovamente, ele sabe que precisa recriar apenas aquele contêiner específico para aplicar a mudança.
Para quem já domina a linha de comando do Linux, o Docker Compose é como um “script de automação evoluído”. Se o Docker Engine cuida do container individual, o Compose cuida da orquestração e do estado do ambiente.
Aqui está o funcionamento detalhado:
1. O que é o Docker Compose?
O Docker Compose é uma ferramenta (um binário que hoje faz parte do comando docker) usada para definir e rodar aplicações de múltiplos containers.
Imagine que você precise rodar uma aplicação que depende de um banco de dados, um servidor web e um sistema de cache. Em vez de digitar três comandos docker run gigantescos, com dezenas de flags de rede e volume, você descreve tudo em um único lugar.
A diferença fundamental:
- Docker CLI (
docker run): É imperativo. Você diz ao Docker exatamente o que fazer: “Crie este container, use esta porta, conecte nesta rede”. - Docker Compose: É declarativo. Você descreve o “estado desejado” da sua infraestrutura no arquivo YAML, e o Compose se vira para transformar o estado atual (nada rodando) no estado desejado (tudo configurado).
2. Como ele funciona com arquivos YAML?
O arquivo YAML (Yet Another Markup Language) é escolhido pela sua legibilidade. No contexto do Docker, ele funciona como um manual de instruções estruturado.
A Estrutura do Arquivo
Um arquivo Compose geralmente é dividido em três seções principais:
- Services (Serviços): Aqui você define os containers. No seu caso do macOS, o “serviço” é o container
macos. Se você tivesse um banco de dados junto, ele seria outro serviço. - Networks (Redes): Define como os containers conversam entre si. Por padrão, o Compose cria uma rede isolada para que todos os serviços do arquivo se enxerguem pelo nome.
- Volumes (Persistência): Define onde os dados serão salvos permanentemente no seu host (o diretório
~/docker/mac, por exemplo).
O Processo de Execução
Quando você digita docker compose up, acontece o seguinte:
- Parsing: O Docker lê o seu arquivo
.ymle verifica se a sintaxe está correta. - Criação de Recursos: Ele cria a rede e os volumes definidos antes de subir os containers.
- Pull/Build: Ele verifica se a imagem (ex:
dockurr/macos) existe localmente. Se não, ele baixa automaticamente. - Convergence: O Docker compara o que está rodando no seu Linux com o que está no arquivo. Se você mudar a memória de 8G para 16G no arquivo e der um
upnovamente, ele sabe que precisa recriar apenas aquele container específico para aplicar a mudança.
3. Por que usar YAML em vez de Shell Scripts?
Como você trabalha com consultoria e ensino, a vantagem do YAML fica clara na manutenção:
- Idempotência: Você pode rodar o comando
upvárias vezes; se nada mudou no arquivo, o Docker não faz nada. Um script.shcomdocker rundaria erro de “container já existente”. - Versionamento: O arquivo YAML pode (e deve) ser enviado para um Git. Isso garante que qualquer pessoa da sua equipe (ou seus alunos) tenha exatamente o mesmo ambiente que você, com as mesmas portas e variáveis.
- Cleanup Centralizado: Com um simples
docker compose down, o Docker remove os containers, redes e configurações criadas, deixando o sistema limpo, sem resíduos de processos rodando em background.
Exemplo Prático de Fluxo
No nosso caso com o MacOS, vamos definir:
- O estado: “Quero um macOS Sonoma, com 8GB de RAM e teclado PT-BR”.
- Provisionou: O
docker compose up -dinterpreta esse desejo e monta toda a estrutura de virtualização QEMU/KVM por trás dos panos.
Se você decidir amanhã que o macOS precisa de 128GB de disco, basta editar o DISK_SIZE no YAML e rodar o comando novamente. O Compose entende que deve reconfigurar o serviço existente.
Instalando o docker no ubuntu 26.04 LTS
Minha distro de teste é o Ubuntu 26.04 LTS, para instalar o docker atual vamos usar o seu repositório, o procedimento é simples:
sudo apt install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER
reboot
docker run hello-world
Copie um comando por vez em seu terminal. Após reiniciar o docker vai estar funcionando.
Agora, crie um diretório para criarmos o arquivo de instalação:
services:
macos:
image: dockurr/macos:latest
container_name: macos
environment:
VERSION: "14"
LANGUAGE: "Portuguese" # Idioma em português
REGION: "pt-BR" # Região Brasil
KEYBOARD: "pt-BR" # Teclado padrão ABNT2
DISK_SIZE: "64G"
RAM_SIZE: "8G"
CPU_CORES: "4"
USERNAME: "admin"
PASSWORD: "p4ssw0rd"
volumes:
- ./macos:/storage
devices:
- /dev/kvm
- /dev/net/tun
cap_add:
- NET_ADMIN
ports:
- 8006:8006
- 5900:5900/tcp
- 5900:5900/udp
restart: unless-stopped
stop_grace_period: 2m
Atenção:
Seu computador precisa estar com o KVM funcionando e também com permissão para o usuário comum:
sudo usermod -aG kvm $USER
Salve como : mac.yml e execute com o docker:
docker compose -f mac.yml up -d
Você pode acompanhar o processo vendo os logs:
docker logs -f macos
No meu caso mostrou um erro de UEFI MISC DEVICE (ignore-o) e abra seu navegador no endereço:
Abra o utilitário de discos e formate o disco de 64 GBs depois prossiga com a instalação do MacOS.

Prossiga normalmente com a instalação:

Resultado final:

Entendo o arquivo docker compose
1. Definição do Serviço e Imagem
services:: É o início do manifesto. Indica que abaixo virão os “serviços” (containers) que compõem sua aplicação.macos:: É o nome interno do serviço para o Docker Compose.image: dockurr/macos:latest: O “molde” do container. Ele baixa a versão mais recente da imagem criada pelo projeto Dockur, que já vem com o QEMU (emulador) e scripts de automação preparados.container_name: macos: Define o nome fixo que aparecerá quando você der umdocker ps. Sem isso, o Docker geraria um nome aleatório.
2. Environment (Variáveis de Ambiente)
Essas são as instruções passadas para o script dentro do container na hora do boot:
VERSION: "14": Define que será instalado o macOS Sonoma.LANGUAGE,REGION,KEYBOARD: Automatizam o instalador para que o sistema já suba em português e reconheça o teclado brasileiro (ABNT2).DISK_SIZE,RAM_SIZE,CPU_CORES: Alocam os recursos de hardware. Aqui você está reservando 64GB de disco (esparso), 8GB de memória RAM e 4 núcleos de processamento.USERNAMEePASSWORD: Criam o usuário inicial do macOS automaticamente.
3. Volumes e Dispositivos (Acesso ao Hardware)
volumes: - ./macos:/storage: Cria uma ponte entre a pasta local./macose a pasta/storagedentro do container. É aqui que o seu disco virtual (data.img) e seus arquivos pessoais ficam salvos.devices::/dev/kvm: O mais importante. Permite que o container use a virtualização nativa do seu processador (Kernel-based Virtual Machine). Sem isso, o macOS seria tão lento que ficaria inutilizável./dev/net/tun: Permite a criação de túneis de rede, necessário para a ponte de rede do macOS.
4. Capacidades e Portas
cap_add: - NET_ADMIN: Dá permissões administrativas de rede ao container para que ele possa configurar a placa de rede virtual.ports::8006:8006: Abre a interface web. Você acessa o macOS pelo navegador através desta porta.5900:5900/tcp e udp: Portas padrão do VNC. Permitem que você use um cliente de Desktop Remoto (como o Remmina ou RealVNC) para controlar o Mac com melhor performance que no navegador.
5. Políticas de Operação
restart: unless-stopped: Garante que o macOS inicie automaticamente sempre que você ligar o computador/servidor, a menos que você o tenha desligado manualmente com um comando Docker.stop_grace_period: 2m: Quando você manda parar o container, o Docker normalmente “mata” o processo em 10 segundos. Como o macOS precisa fechar arquivos e desligar corretamente para não corromper o disco, essa linha dá 2 minutos para ele encerrar com calma antes do “force kill”.
Resumo do Fluxo
Ao rodar este arquivo, o Docker:
- Reserva memória e CPUs.
- Mapeia o teclado e idioma.
- Conecta o processo ao acelerador de hardware (KVM).
- Abre as portas de visualização (8006/5900).
- Garante que tudo o que você fizer seja salvo na pasta local
./macos.
Para concluir este artigo
Docker compose é sem dúvida uma forma rápida de realizar testes de aplicações e no final, caso não queira mais, basta remover tudo com poucos comandos.
Com docker ps você visualiza o processo ativo. Anote o conainer ID e pare o processo:
docker stop id_do_conteiner
Se desejar pode verificar a imagem:
docker images i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
dockurr/macos:latest b080b8069bb8 115MB 109MB
hello-world:latest f9078146db2e 11.5kB 9.49kB U
E remover com:
docker rmi dockurr/macos:latest
Agora, basta excluir o diretório criado e pronto. Nenhuma mudança foi realizada no seu sistema host, neste caso o Ubuntu 26.04.







