WSL 2, Arch, Docker e um pouco mais do meu ambiente de desenvolvimento

Gustavo Bellini Bigardi
11 min readFeb 21, 2022

Salve pessoal, tudo certo?

Recentemente, comecei a utilizar mais o WSL para ambiente de desenvolvimento, principalmente por contato com tecnologias diferentes das que trabalho no dia-a-dia, como Go ou PHP.

Outro ponto que precisei fazer recentemente, como o Docker Desktop passou a ser pago para empresas com mais de 250 funcionários ou com faturamento superior a $10 milhões, para evitar custos extras para o que preciso no dia-a-dia, configurei o mesmo para rodar inteiramente no WSL, como é feito em qualquer instalação Linux padrão.

Depois de passar alguns perrengues configurando tudo, resolvi escrever este artigo mostrando como construí meu ambiente de desenvolvimento no WSL 2. Inclusive depois de um tempo utilizando Ubuntu no WSL, passei a utilizar o Arch Linux, seguindo como base um excelente vídeo produzido pelo Fabio Akita, que recomendo fortemente que assistam (estou deixando o link abaixo):

Vou pular a parte de instalação do WSL até a configuração do ZSH, pois é basicamente o que está no vídeo acima, sendo que eu faço um pouco diferente a partir da parte do ZSH, mas como o próprio Akita fala no vídeo, teste o que estou publicando aqui, o que ele publicou no vídeo, opções diferentes, veja qual fica melhor para você, ok? Dito isso, vamos lá.

Limitando recursos do WSL

Quem já utilizou o WSL anteriormente, sabe que se formos consumindo recursos como memória RAM, ele irá alocar o quanto achar que precisa, podendo deixar o Windows com falta de recursos caso você inicie muitas aplicações, containers, etc.

Um ponto essencial após instalar o WSL e subir uma distribuição nele é configurar o limite de uso de memória. Para isto, crie, caso ainda não existe, o arquivo wsl.conf dentro do diretório do perfil de seu usuário no windows, normalmente em C:\Users\[Usuario]. No Powershell, podemos abrir o arquivo com o comando a seguir:

notepad "$env:USERPROFILE/.wslconfig"

Vamos adicionar o seguinte conteúdo ao arquivo, que já vou explicar a seguir:

[wsl2]
memory=3GB # Limits VM memory in WSL 2 up to 3GB
processors=4 # Makes the WSL 2 VM use two virtual processors

Basicamente estas duas linhas definem:

  • Memory: limite de memória que poderá ser utilizada pela máquina virtual do WSL. Recomendo sempre deixar uma quantidade mínima de 3–4GB para o SO principal, então se você tiver 8GB de RAM, recomendo um limite de 3–4gb de uso para o WSL. Caso tenha 16GB, um limite de 8GB será mais que o suficiente.
  • Processors: limite de quantos núcleos virtuais do processador o WSL poderá utilizar. Caso tenha um processador como um Intel i5 9th geração ou superior, recomendo a limitar para 4 núcleos no máximo. Caso tenha um i7 de 9th geração ou superior, limites como até 8 núcleos podem ser utilizados sem problemas.

Estes valores para as configurações que mencionei são valores que testei e funcionam para mim. Novamente, brinque e teste com as configurações para encontrar valores que atendam melhor suas necessidades de uso.

Após salvar o arquivo, no Prompt de Comando ou Powershell, execute o comando a seguir:

wsl --shutdown Arch

Onde você deve trocar o Arch pelo nome da sua instância de WSL, caso seja diferente. Após isto, basta abrir o WSL ou Windows Terminal no perfil do WSL para ele ser iniciado novamente com as novas configurações.

Existem outras configurações além dos limites de memória e uso de núcleos virtuais do processador, que podem ser encontradas no link a seguir, mas as essenciais a serem definidas são uso de memória e núcleos.

Configurando o ZSH e Oh-My-Zsh

Eu particularmente utilizo o Oh-My-Zsh pela facilidade de ativar vários plugins úteis no meu dia-a-dia, como auto-complete e suporte ao git, docker, npm, .net e outros.

Logo após instalar o ZSH e definir ele como shell padrão, conforme o vídeo do Akita, temos o terminal aproximadamente neste estado:

Terminal com o Arch WSL em execução com o shell ZSH ativo.

Chegando a este ponto, vamos acessar o site do Oh-My-Zsh, navegar até a seção de instalação (https://ohmyz.sh/#install) e copiar e colar o comando para o script de instalação.

sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Um lembrete: O git já precisa estar instalado. Caso não tenha feito esse passo do vídeo, basta executar o comando a seguir:

sudo pacman -S git

Ao final da instalação, sua tela deve estar semelhante a esta (note que eu já configurei o tema Moonlight II e as fontes que estão em passos seguintes do vídeo. Recomendo assistir ele inteiro antes de seguir meus passos aqui do artigo, ok?

Oh-My-Zsh instalado.

Vamos agora abrir o arquivo ~/.zshrc com o vim, VS Code ou editor de sua preferência. Caso você tenha a extensão Remote WSL instalada no VS Code no Windows, pode ser que você tenha um erro ao tentar abrir o arquivo com ele, pois o wget não foi instalado por padrão no Arch. Neste caso, execute o comando a seguir para corrigir isso:

sudo pacman -S wget

Com o arquivo .zshrc aberto, vamos encontrar a linha a seguir nele:

plugins=(git)

Nesta linha podemos ativar todos os plugins disponíveis já com o Oh-My-Zsh e ativar outros novos, desde que estejam no diretório plugins da instalação do Oh-My-Zsh (normalmente $ZSH_CUSTOM/plugins/). Eu basicamente utilizo os plugins a seguir, lembrando que devem ser separados por espaço.

plugins=(git docker docker-compose kubectl heroku dotnet npm node laravel)

Lembrando mais uma vez que são os plugins de acordo com as tecnologias que trabalho no dia-a-dia, sinta-se a vontade de verificar quais plugins estão disponíveis e usar os que forem mais adequados para você. Explicando brevemente os plugins que ativei, eles fornecem um autocomplete e integração com as seguintes ferramentas:

  • CLI do Git, com auto-complete de branches, comandos e alguns alias para comandos do git, como gpsup, que basicamente executa um git push -u origin [branch atual] para o servidor, facilitando ao subir novas branches ou mesmo existentes;
  • CLI do docker e docker-compose, facilitando o auto-complete com imagens, containers, volumes e outros recursos existentes;
  • CLI do kubernetes, com auto-complete para vários comandos dele;
  • CLI do Heroku, facilitando a operação da plataforma, que utilizo para projetos pessoais, incluindo auto-complete para nomes de recursos e comandos de addons;
  • CLI do .NET Core, NPM e NodeJS, para auto-complete de comandos e arquivos, compilação, execução de aplicações e outros recursos;
  • CLI do Laravel, para auto-complete de comandos do laravel e scritp do artisan, que utilizo em pequenos projetos pessoais.

Feita a configuração, vamos salvar o arquivo, fechar e abrir novamente o terminal para aplicar as configurações. Caso queira alterar o tema padrão do Oh-My-Zsh, basta localizar alterar a linha a seguir no arquivo .zshrc para um tema já existente no diretório $ZSH_CUSTOM/themes/. Basta informar o nome do tema disponível no diretório.

ZSH_THEME="robbyrussell"

Caso queira ver um preview dos temas, basta acessar https://github.com/ohmyzsh/ohmyzsh/wiki/Themes e verificar novos temas inclusive neste site.

Recomendo ainda seguir as outras dicas do Akita no vídeo, como instalar o plugin zsh-autosuggestions, que funciona normalmente com o Oh-My-Zsh, além da instalação do LVIM, que estou começando a tentar me adaptar ao uso depois de anos com editores no Windows e usando mouse muitas tarefas.

Docker sem o Docker Desktop

Acho que todos já devem saber que o Docker Desktop passou a ser pago no macOS e Windows para empresas que estejam fora dos critérios a seguir:

Ele continua gratuito para pequenas empresas (com menos de 250 funcionários e um faturamento anual inferior a $10M), uso pessoal, educacional e projetos open source não comerciais;

https://www.docker.com/blog/updating-product-subscriptions/

O docker para linux, sem o ferramental visual e algumas facilidades do Docker Desktop ainda continua gratuito, mesmo para empresas que estejam fora dos critérios do link acima. Então podemos utilizar o docker internamente no WSL, mas para isto temos algumas configurações adicionais para realizar, devido a particularidades do WSL.

Primeiramente, tenha certeza que a versão em execução do WSL confirado em seu computador é a 2. Caso tenha configurado o Arch com o WSL 1, que pode ser confirmado com o comando a seguir, conferindo a versão a frente da distro Arch:

wsl --list --verbose

Siga as instruções da documentação da Microsoft para upgrade ao WSL 2:

Neste momento, assumindo que você seguiu as instruções do Akita para configurar seu Arch Linux até o ZSH, você já está utilizando uma conta própria no WSL e com o sudo configurado. Vamos então instalar o Docker utilizando o pacman, com o comando a seguir (simples assim):

sudo pacman -S docker docker-compose

Terminada a instalação, vamos configurar o docker. O primeiro passo é adicionar seu usuário no grupo docker, com o comando a seguir:

sudo usermod -aG docker $USER

Para confirmar se funcionou, execute o comando a seguir e você deverá ver o grupo docker na lista:

groups

Vamos agora configurar o dockerd, que é o serviço do Docker. No WSL, não temos o systemd, o módulo que orquestra os serviços no Linux, disponível para uso. Existem alternativas para configuração, mas para uso do docker, podemos seguir com uma abordagem mais simples utilizando um script de inicialização.

Primeiramente vamos criar um diretório para armazenamento dos logs e do arquivo docker.sock. Vou utilizar o diretório /mnt/wsl/shared-docker (que será criado), mas você pode utilizar outro diretório se preferir.

DOCKER_DIR=/mnt/wsl/shared-docker
mkdir -pm o=,ug=rwx "$DOCKER_DIR"
sudo chgrp docker "$DOCKER_DIR"

Basicamente o comando acima cria o diretório e altera o diretório para pertencer ao grupo docker.

O próximo passo é criar o arquivo de configuração para o daemon do Docker saber onde armazenar o arquivo docker.sock. Vamos criar o arquivo daemon.json no diretório /etc/docker/. Caso o diretório ou arquivo não existam, basta criá-los com o conteúdo a seguir:

{
"hosts": ["unix:///mnt/wsl/shared-docker/docker.sock"]
}

Feito isso, podemos testar se está tudo funcionando com o comando a seguir:

sudo dockerd

Pode ser que você encontre o erro a seguir:

Erro por falta das bibliotecas de compilação do C ao iniciar o dockerd.

Caso tenha encontrado esse mesmo problema, basta instalar o pacote que no Ubuntu e outras distribuições Debian é conhecido dev-essentials, mas no Arch é o pacote base-devel, como mostrado pelo Akita no vídeo. Após instalar o pacote, execute novamente o dockerd com o comando que mostrei anteriormente. Você deve chegar nesta resultado (podendo ter algumas variações no conteúdo do log, mas indicando que o Docker foi iniciado):

Docker executando corretamente após a instalação do pacote base-devel

Com isso, abra uma nova aba e execute o comando a seguir:

docker -H unix:///mnt/wsl/shared-docker/docker.sock run --rm hello-world

Caso tenha um resultado semelhante a esse, parabéns, a instalação do docker funcionou!

Execução com sucesso da imagem hello-world do Docker.

Feito tudo isso, feche essa aba e interrompa a execução do dockerd na aba anterior teclando Ctrl C.

Vamos agora configurar o dockerd para ser inicializado assim que uma instância do WSL for iniciada, já que não temos o systemd para cuidar disso. Abra o arquivo ~/.zshrc com o editor de sua preferência e adicione essas linhas ao final do arquivo:

DOCKER_DISTRO="Arch"
DOCKER_DIR=/mnt/wsl/shared-docker
DOCKER_SOCK="$DOCKER_DIR/docker.sock"
export DOCKER_HOST="unix://$DOCKER_SOCK"
if [ ! -S "$DOCKER_SOCK" ]; then
mkdir -pm o=,ug=rwx "$DOCKER_DIR"
chgrp docker "$DOCKER_DIR"
/mnt/c/Windows/System32/wsl.exe -d $DOCKER_DISTRO sh -c "nohup sudo -b dockerd < /dev/null > $DOCKER_DIR/dockerd.log 2>&1"
fi

Feche e abra o WSL / Windows Terminal novamente. Você notará que ele irá pedir de imediato sua senha para execução de um processo com o sudo. Informe a senha e após 2–3 segundos, você conseguirá executar comandos do Docker normalmente.

Para remover essa questão de digitar a senha para o sudo toda vez que abrir uma instância do WSL, vamos configurar o sudo para o grupo docker. Para isto, vamos editar o arquivo de sudoers com o comando:

sudo visudo

Adicionando esta linha:

%docker ALL=(ALL)  NOPASSWD: /usr/bin/dockerd

Caso você tenha uma mensagem de erro ao executar o comando visudo de que o editor padrão não existe, execute conforme o comando a seguir:

sudo EDITOR=vim visudo

Bastando trocar o code pelo comando do seu editor de preferência. No meu caso, estou utilizando o vim. No final, seu arquivo sudoers deve ficar como este:

Arquivo sudoers com permissão para sudo no dockerd sem senha.

Salve o arquivo teclando :wq, feche o Windows Terminal e abra novamente. Agora a senha de sudo não será solicitada e o docker estará disponível para uso. Ele sempre será iniciado com a primeira instância do WSL aberta após iniciar o Windows.

Comandos do docker funcionando normalmente após configuração do dockerd no arquivo .zshrc.

Acessando o docker pelo Windows

No Windows, já temos acesso a portas dos containers em execução, como um postgres ou redis, diretamente pelo endereço localhost.

Caso você tenha scripts em powershell que precise executar no lado do Windows para operar o Docker, temos várias alternativas, como fazer download dos binários do CLI do docker, expor o dockerd via TCP e configurar para conexão.

Mas temos uma abordagem mais simples, onde podemos criar um alias no Windows para executar os comandos do docker dentro do WSL.

Caso você utilize Powershell, basta editar o arquivo de perfil do Powershell e adicionar uma função a ele. Para encontrar o arquivo de perfil, execute o comando a seguir no Powershell:

echo $PROFILE

Você deverá ter um resultado semelhante a:

C:\Users\[SEU_USUARIO]\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

Basta abrir este arquivo com um editor de sua preferência e adicionar o conteúdo a seguir ao final dele:

$DOCKER_DISTRO = "Arch"
function docker {
wsl -d $DOCKER_DISTRO docker -H unix:///mnt/wsl/shared-docker/docker.sock @Args
}

Dependendo das configurações de segurança, você pode ter o erro a seguir ao reiniciar o Terminal com o Powershell:

Erro de permissão nos scripts de profile do PowerShell.

Para corrigir isto, vamos teclar Windows + Q, procurar pelo Powershell, clicar com o botão direito e executar como administrador:

Executando o Powershell como administrador.

Em seguida, vamos executar o comando a seguir e confirmar com A para todos.

Set-ExecutionPolicy RemoteSigned
Alterando a política de execução do Powershell para Remote Signed.

Feito isso, agora conseguimos executar nossa função docker que será executada no WSL, mas pelo Powershell no Windows.

Comando docker executado pelo Powershell no WSL através de script no arquivo de perfil.

Caso você utilize o Prompt de Comando padrão do Windows, crie um diretório Tools ou algo semelhante no drive C:, e dentro dele, crie um arquivo chamado docker.cmd ou docker.bat e adicione o conteúdo a seguir:

@echo off
set DOCKER_DISTRO=fedora
wsl -d %DOCKER_DISTRO% docker -H unix:///mnt/wsl/shared-docker/docker.sock %*

Após isto, adicione o diretório Tools, ou nome que você tenha utilizado, ao PATH do seu usuário no Windows:

Acessando a tela de variáveis de ambiente da conta.
Adicionando o diretório com o arquivo .cmd ao path do sistema.

Após isso, basta abrir o Prompt de Comando novamente e testar o docker, executando um “docker ps”, por exemplo.

Com isso temos o WSL 2 configurado com uma distribuição Arch linux muito mais leve que a padrão Ubuntu disponível na loja de aplicaltivos e o Docker sendo executado diretamente no linux, sem a necessidade de instalação da versão paga do Docker Desktop.

Caso tenham dúvidas, deixem nos comentários.

Fico por aqui e até a próxima pessoal!

--

--