Skip to content

Instantly share code, notes, and snippets.

@tdcosta100
Last active August 6, 2024 15:55
Show Gist options
  • Save tdcosta100/c5c206f8958e82e638fa0ea226351081 to your computer and use it in GitHub Desktop.
Save tdcosta100/c5c206f8958e82e638fa0ea226351081 to your computer and use it in GitHub Desktop.
Tutorial para utilizar interface gráfica no WSL2, substituindo XServer pelo Xvnc, permitindo ao WSL trabalhar como se fosse Linux nativo, incluindo tela de login

WSL2 com interface gráfica utilizando Xvnc

Note

Caso você queira utilizar o WSLg puro, você pode tentar o novo tutorial com o WSLg (Xwayland) ou o tutorial com o WSLg (Wayland).

Nesse tutorial, iremos configurar a interface gráfica no WSL2, e acessá-la utilizando o VNC. Nenhum software adicional fora do WSL é necessário (como o VcXsrv), exceto, claro um VNC Viewer (RealVNC, TightVNC, TigerVNC, UVNC, etc, todos devem funcionar perfeitamente).

Os componentes-chave que precisamos instalar são o metapackage do desktop que você desejar (GNOME, KDE, Xfce, Budgie, etc) e o tigervnc-standalone-server.

Para essa configuração irei utilizar Ubuntu (20.04, 22.04 e 24.04 funcionam), e irei instalar o GNOME Desktop. Uma vez que os componentes-chave não são diretamente relacionados ou dependentes do Ubuntu ou do GNOME, você pode utilizar sua distribuição favorita e interface gráfica. Dê uma olhada na seção Telas de exemplo para exemplos.

Então vamos lá. Primeiro, precisamos do WSL2 instalado e funcionando.

Warning

O WSLg pode não funcionar da maneira esperada, uma vez que os seus sockets Wayland serão desabilitados para todos, e nem todo aplicativo consegue funcionar corretamente dessa maneira.

Antes de colocar a mão na massa, vamos nos certificar de que tudo está atualizado.

sudo apt update
sudo apt upgrade

Você também precisa verificar se o arquivo /etc/wsl.conf tem as seguintes linhas:

[boot]
systemd=true

Caso não tenha, crie/edite este arquivo, adicione essas linhas e reinicie o WSL (por exemplo, usando wsl.exe --shutdown, e reabrindo o terminal da sua distribuição).

Agora sim, estamos prontos para começar.

Instalando os componentes

Instalando a interface gráfica

  1. Primeiro você seleciona o metapackage do seu ambiente desktop favorito. Aqui está uma lista dos metapackages mais comuns:

    DistribuiçãoAmbiente DesktopMetapackage
    UbuntuBudgieubuntu-budgie-desktop
    GNOMEubuntu-desktop
    KDEkubuntu-desktop
    Kylinubuntukylin-desktop
    LXDElubuntu-desktop
    MATEubuntu-mate-desktop
    Studioubuntustudio-desktop
    Unityubuntu-unity-desktop
    Xfcexubuntu-desktop
    Ubuntu/DebianCinnamontask-cinnamon-desktop
    GNOMEtask-gnome-desktop
    GNOME Flashbacktask-gnome-flashback-desktop
    KDE Plasmatask-kde-desktop
    LXDEtask-lxde-desktop
    LXQttask-lxqt-desktop
    MATEtask-mate-desktop
    Xfcetask-xfce-desktop
  2. Uma vez escolhido o metapackage, vamos instalá-lo. Por exemplo, se você escolheu o ubuntu-desktop, o comando será:

    sudo apt install \
    `[ ! -z "$(apt-cache search ^acpi-support$)" ] && echo "acpi-support-"` \
    tigervnc-standalone-server \
    ubuntu-desktop
    

    Isso irá instalar o ubuntu-desktop e o tigervnc-standalone-server, mas excluirá o acpi-support, caso seja incluído como dependência. Isto porque caso seja instalado, irá praticamente inutilizar a sua distribuição (detalhes em microsoft/WSL#10059), então o comando faz o apt não instalar esse pacote.

    A instalação irá demorar um pouco, então seja paciente.

  3. Caso esteja utilizando o Ubuntu, você deve querer instalar o snap-store. Mas se não precisa da loja de aplicativos, você pode pular esse passo:

    sudo snap install snap-store
    

Configurando o ambiente

Se você está utilizando o Debian, precisa configurar o locale (no Ubuntu isso não é necessário):

echo "LANG=en_US.UTF-8" | sudo tee -a /etc/default/locale

Criando e modificando serviços

  1. Agora que temos tudo instalado, precisamos ajustar o diretório /tmp/.X11-unix/, porque é montado como somente leitura por padrão. Criaremos uma nova unit do systemd:

    sudo systemctl edit --full --force wslg-fix.service
    
  2. Cole o código abaixo no editor:

    [Service]
    Type=oneshot
    ExecStart=-/usr/bin/umount /tmp/.X11-unix
    ExecStart=/usr/bin/rm -rf /tmp/.X11-unix
    ExecStart=/usr/bin/mkdir /tmp/.X11-unix
    ExecStart=/usr/bin/chmod 1777 /tmp/.X11-unix
    ExecStart=/usr/bin/ln -s /mnt/wslg/.X11-unix/X0 /tmp/.X11-unix/X0
    
    [Install]
    WantedBy=multi-user.target
    
  3. Saia do editor salvando as alterações do arquivo.

  4. Vamos habilitar o wslg-fix.service:

    sudo systemctl enable wslg-fix.service
    
  5. Também precisamos remover todas as referências ao Wayland, porque se não, alguns aplicativos (gnome-terminal, por exemplo) abrirão fora do desktop shell. Vamos editar o serviço [email protected]:

    sudo systemctl edit [email protected]
    
  6. Cole o código abaixo no editor:

    [Service]
    ExecStartPost=-/usr/bin/rm -f /run/user/%i/wayland-0 /run/user/%i/wayland-0.lock
    

Warning

Atente às instruções que aparecem no editor sobre o local correto do cursor no texto antes de colar. Se você colar o código no local errado, o código será descartado.

  1. Reinicie o WSL usando wsl.exe --shutdown, e então reabra o terminal da sua distribuição novamente.

Criando as senhas do VNC Server

Important

No Debian, o usuário do GDM é Debian-gdm, então você precisa substituir gdm por Debian-gdm nos comandos abaixo.

  1. Em algumas distribuições, o diretório /var/lib/gdm3/ tem um owner incorreto, então vamos corrigir isso antes de definir as senhas do VNC Server:

    sudo chown gdm:gdm /var/lib/gdm3/
    
  2. Nessa configuração, cada usuário tem uma senha do VNC diferente. Então você precisa configurar ao menos três senhas, uma para o usuário atual, uma para o root e uma para o GDM, que irá apresentar a tela de login. Se você não configurar a senha, não será capaz de acessar a tela de login, ou o desktop do usuário. Primeiro, vamos configurar a senha do VNC para o usuário atual:

    vncpasswd
    
  3. Agora, vamos configurar a senha do VNC do root (necessária se você utilizar o LightDM ao invés do GDM):

    sudo -H vncpasswd
    
  4. Finalmente, vamos configurar a senha do VNC para o GDM (pule esse passo se você não usa o GDM):

    sudo -H -u gdm vncpasswd
    

    Você pode repetir o processo para outros usuários existentes.

Substituindo o Xorg padrão pelo Xvnc

Por padrão, o display manager pode chamar várias instâncias do Xorg, uma para cada sessão de usuário, incluindo a tela de login, exibida pelo GDM. Então iremos substituir o script Xorg por uma nova versão que chama o Xvnc ao invés do Xorg clássico. Éssa é a verdadeira mágica que estamos tentando fazer.

  1. Primeiro, vamos fazer um backup do script Xorg original.

    sudo mv /usr/bin/Xorg /usr/bin/Xorg.original
    
  2. Agora, criamos um novo script Xorg.

    sudo nano /usr/bin/Xorg.Xvnc
    
  3. Cole o código abaixo no editor:

    #!/bin/bash
    for arg do
      shift
      case $arg in
        # Xvnc nao suporta o argumento vtxx, entao vamos converter para ttyxx
        vt*)
          set -- "$@" "${arg//vt/tty}"
          ;;
        # -keeptty nao e suportado pelo Xvnc
        -keeptty)
          ;;
        # -novtswitch nao e suportado pelo Xvnc
        -novtswitch)
          ;;
        # outros argumentos permanecem intactos
        *)
          set -- "$@" "$arg"
          ;;
      esac
    done
    
    # Encontrar um numero de display disponivel
    for displayNumber in $(seq 1 100)
    do
      [ ! -e /tmp/.X11-unix/X$displayNumber ] && break
    done
    
    # Aqui voce pode adequar ou adicionar as opcoes de acordo com as suas necessidades
    command=("/usr/bin/Xvnc" ":${displayNumber}" "-geometry" "1024x768" "-rfbport" "$((5900 + $displayNumber))" "-rfbauth" "${HOME:-/root}/.vnc/passwd" "$@")
    
    systemd-cat -t /usr/bin/Xorg echo "Starting Xvnc:" "${command[@]}"
    
    exec "${command[@]}"
    

    Note a resolução da tela virtual. Você pode modificá-la para outra que satisfaça suas necessidades (1366x768, 1920x1080, etc). Você também pode alterar a opção -rfbauth para apontar para um local fixo ao invés da home do usuário atual, para não precisar ter uma senha para cada usuário.

  4. Finalmente, definimos as permissões corretas para o arquivo e criamos um um link para ele:

    sudo chmod 0755 /usr/bin/Xorg.Xvnc
    sudo ln -sf Xorg.Xvnc /usr/bin/Xorg
    

Warning

Às vezes, atualizações do sistema substituem o link Xorg com a versão original. Basta repetir esse passo se isso ocorrer, e o Xvnc voltará a funcionar como substituição do Xorg.

Executando sua distribuição com interface gráfica habilitada

Agora você tem tudo pronto para começar. Primeiro finalize o WSL:

wsl.exe --shutdown

Então reabra o terminal da sua distribuição.

Fazer isso é como dar boot no Linux novamente, e o GDM irá inicializar automaticamente, e irá criar uma instância de Xorg para mostrar a interface de login. Mudamos esse processo para fazê-lo criar instâncias de Xvnc, então podemos acessá-las. A primeira instância abrirá a porta 5901, a segunda instância abrirá a porta 5902, e assim por diante.

Acessando a tela do VNC

Depois de um tempo (geralmente alguns segundos, mas pode demorar mais se você não tiver um SSD), você pode testar se está funcionando corretamente. Use seu VNC Viewer favorito para conectar no localhost porta 5901 (localhost:5901). Use a senha do VNC definida para o usuário gdm (ou Debian-gdm, se está utilizando o Debian). A tela de login deve aparecer.

Depois de fazer o login, a tela ficará em branco e eventualmente fechará automaticamente. Isso é porque uma nova instância do Xvnc foi criada para o desktop do usuário, abrindo a porta 5902. Conecte-se a essa porta agora. O desktop do usuário logado deve aparecer. Quando você deslogar, a tela da porta 5901 mostrará a interface de login novamente. Isso se aplica ao GDM (que é o caso se você instalou o Ubuntu Desktop). Você pode mudar esse comportamento alterando o arquivo de configuração dessa forma:

  1. sudo nano /etc/gdm3/custom.conf

  2. Descomente e edite as seguintes linhas:

     AutomaticLoginEnable=true
     AutomaticLogin=[seu username sem os colchetes]
    

Se você está utilizando o LightDM, a tela de desktop aparecerá na porta 5901, então não há necessidade de conectar na porta 5902.

Desligando

Uma coisa importante é: uma vez que você inicializa sua instância de WSL, você não pode simplesmente desligá-la do nada. Você deve realizar um desligamento padrão do Linux. Você pode utilizar uma das alternativas abaixo:

  • Opção de Desligar no menu da interface gráfica
  • sudo poweroff

Depois disso, você pode parar a sua instância de WSL com segurança, através do comando wsl --terminate ou wsl --shutdown. Não realizar o processo de desligamento poderá corromper sua instância de WSL, portanto tenha cuidado.

Dicas e truques

  • O VNC é um protocolo bastante adaptativo, e por padrão utiliza a maior taxa de compressão possível, para otimizar a utilização da rede. Mas no nosso caso, isso apenas desperdiça processamento, uma vez que você está se conectando ao próprio computador (largura de banda "infinita" e ping praticamente zero). Para não utilizar nenhum algoritmo de compressão e assim reduzir o delay, o ideal é forçar seu VNC Viewer a conectar-se utilizando a codificação RAW. O ganho de performance é perceptível, especialmente ao reproduzir vídeos (apesar de a performance não ser grande coisa nesse caso específico).

Solução de problemas

  1. Caso não funcione de primeira, tente checar os logs do journalctl:

    journalctl -b -t /usr/lib/gdm3/gdm-x-session -t /usr/bin/Xorg --no-pager
    

    Se você está utilizando o Debian, então o comando é:

    journalctl -b -t /usr/libexec/gdm-x-session -t /usr/bin/Xorg --no-pager
    

    Na saída gerada, você deve conseguir encontrar qual linha de comando foi gerada para o Xvnc, e quais mensagens de erro aparecem. E claro, mesmo que tudo funcione corretamente, ainda assim você pode checar os logs para ver o que está acontecendo, ou para fazer debug.

  2. Você deve verificar se o script customizado Xorg não foi substituído pela versão padrão dele. Se foi o caso, basta repetir os passos da seção Substituindo o Xorg padrão pelo Xvnc.

  3. Verifique se o Xorg é seu display server padrão, não Xephyr ou Wayland. Caso não seja, você precisa mudar o display server padrão para o Xorg.

  4. Se você está utilizando o LightDM, você também precisa verificar os logs em /var/log/lightdm (você vai precisar utilizar o sudo para ler os arquivos nesse diretório). A saída do Xvnc estará no arquivo /var/log/lightdm/x-0.log.

  5. Se você pode se conectar às portas 590XX, mas aparece um erro como Authentication failure: No password configured for VNC Auth, está faltando o arquivo $HOME/.vnc/passwd está faltando para aquele usuário em particular (na porta 5901, o usuário é gdm). Tente repetir os passos descritos na seção Criando as senhas do VNC Server e tente se conectar novamente.

  6. Caso ainda não funcione, você pode tentar reiniciar o WSL com wsl.exe --shutdown (não se esqueça de salvar tudo o que não foi salvo antes, porque o WSL será desligado completamente), e então reabra o terminal da sua distribuição e repita os passos da seção Acessando a tela do VNC.

Telas de exemplo

GDM

GDM

LightDM

LightDM

GNOME

GNOME

KDE

KDE

Xfce

Xfce

Budgie Desktop

Budgie Desktop

Pessoas que contribuíram

Meu muito obrigado às pessoas abaixo, cujo feedback fez esse tutorial atingir o nível atual de qualidade e completitude (e ficará cada vez mais completo conforme mais feedback for sendo dado).

@tdcosta100
Copy link
Author

Olá, @1993nxv. Muita coisa mudou desde que esse tutorial foi escrito. Agora existe suporte nativo ao systemd, e com isso as coisas ficaram um pouco diferentes. Eu vou reescrever o tutorial para abraçar essas mudanças. Enquanto isso, me conte qual é a distro que você está usando? Pergunto porque o Ubuntu 22.04 infelizmente tem coisas que não funcionam, aí a opção será usar o Ubuntu 20.04 mesmo. Me avise que aí consigo continuar te ajudando.

@cjannuzzi
Copy link

@tdcosta100 gostei da ideia de reescrever o tutorial atualizado. Já que o 22.04 ta bugado pode ser o 20.04 caso esteja rodando liso. De qualquer forma, agradeço desde já o empenho.

@tdcosta100
Copy link
Author

Olá, @cjannuzzi. Ainda não atualizei a versão em português, mas você já pode conferir a versão atualizada em inglês aqui.

@dpaes
Copy link

dpaes commented Jun 26, 2024

sudo apt install dotnet-runtime-5.0
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
dotnet-runtime-deps-5.0 : Depends: libssl1.0.0 but it is not installable or
libssl1.0.2 but it is not installable or
libssl1.1 but it is not installable
E: Unable to correct problems, you have held broken packages.

O que eu faço agora?

@tdcosta100
Copy link
Author

Olá, @dpaes. Muita coisa mudou desde que eu escrevi esse tutorial. Eu preciso reescrever ele, infelizmente minha vida está meio corrida então ainda não consegui. A versão 22.04 do Ubuntu está horrível pra funcionar dessa forma que o tutorial descreve. Mas as versões 24.04 e 20.04 funcionam melhor. O 24.04 inclusive eu consegui fazer funcionar mesmo com o WSLg ativado.

Enquanto não atualizo, resete sua distro WSL ou faça os tutoriais seguindo a versão em inglês.

@dpaes
Copy link

dpaes commented Jun 28, 2024

entendi, obrigado @tdcosta100, mas o erro ocorreu usando o Ubuntu 20.04 mesmo só pra informar.

@tdcosta100
Copy link
Author

Opa, obrigado pela informação. Então, como falei, agora muita coisa mudou, e esse tutorial está desatualizado, o systemd-genie não é mais necessário, então você não precisa mais instalar o dotnet-runtime-5.0. Com isso, esse erro não vai acontecer se você seguir o tutorial em inglês. No momento estou fazendo alguns testes com o WSLg, e tenho tido resultados bastante interessantes. Quando finalizar, reescrevo o tutorial em português e atualizo o tutorial em inglês.

@tdcosta100
Copy link
Author

Pessoal, finalmente atualizei o tutorial em português. Agora não é mais necessário desativar o WSLg, e agora funciona no Ubuntu 22.04 e também no Ubuntu 24.04.

@tdcosta100
Copy link
Author

E pra quem quiser utilizar somente o WSLg, também tem um tutorial novo para o WSLg.

@jamazonaz
Copy link

Boa tarde, tutorial muito bom, segui e executei os passos necessários, não ouve nenhum erro e estou utilizando a interface gráfica.
Valeu!!!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment