Home / Tutoriais / Instalando o MacOS pelo Docker no Linux

Instalando o MacOS pelo Docker no Linux

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ê?

  1. Isolamento: Você pode testar uma distribuição Linux dentro de um contêiner sem bagunçar os arquivos do seu sistema principal.
  2. 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.
  3. 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:

  1. 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.
  2. 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.
  3. 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:

  1. Parsing: O Docker lê o seu arquivo .yml e verifica se a sintaxe está correta.
  2. Criação de Recursos: Ele cria a rede e os volumes definidos antes de subir os containers.
  3. Pull/Build: Ele verifica se a imagem (ex: dockurr/macos) existe localmente. Se não, ele baixa automaticamente.
  4. 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 up novamente, 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:

  1. 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.
  2. 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.
  3. 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:

  1. Parsing: O Docker lê o seu arquivo .yml e verifica se a sintaxe está correta.
  2. Criação de Recursos: Ele cria a rede e os volumes definidos antes de subir os containers.
  3. Pull/Build: Ele verifica se a imagem (ex: dockurr/macos) existe localmente. Se não, ele baixa automaticamente.
  4. 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 up novamente, 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 up várias vezes; se nada mudou no arquivo, o Docker não faz nada. Um script .sh com docker run daria 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:

  1. O estado: “Quero um macOS Sonoma, com 8GB de RAM e teclado PT-BR”.
  2. Provisionou: O docker compose up -d interpreta 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:

http://localhost:8006/

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:

Instalando macos pelo docker no linux.

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 um docker 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.
  • USERNAME e PASSWORD: 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 ./macos e a pasta /storage dentro 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:

  1. Reserva memória e CPUs.
  2. Mapeia o teclado e idioma.
  3. Conecta o processo ao acelerador de hardware (KVM).
  4. Abre as portas de visualização (8006/5900).
  5. 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.

Marcado: