About • Windows 11 • Chocolatey • Ubuntu • Todo
This repository contains my personal dotfiles used to set up a new development environment on Windows using WSL2 with Ubuntu. The focus of the setup is on two main tools: Visual Studio Code and IntelliJ IDEA, which are my preferred development environments for programming tasks. Additionally, for other tasks, I use Windows Terminal.
To set up Windows 11 after fresh install in automatic mode, let's download the Sophia Script.
Download and expand the latest Powershell module of the script:
iwr script.sophia.team -useb | iex
Command below are meant to be executed in Administrator mode.
Set execution policy, get into the module directory, download our custom script preset and launch it:
# Set-ExecutionPolicy Bypass -Scope Process -Force; Set-Location -Path ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path + '\Sophi*'); (New-Object System.Net.WebClient).DownloadString('https://gist.githubusercontent.com/aubique/871ad87ef7a801d17942ca3974cd9909/raw/baf76313282abfa07da2e9690566d2df9e30c029/Sophie.ps1') | Out-File .\Sophie.ps1; .\Sophie.ps1
Script will set up environment, customize appearance, remove telemetry and UWPApp bloatware. For WSL2 it installs Virtual Machine Platform, WSL Kernel and GUI App Support (WSLg). After you've completed running script functions, restart the PC and proceed with Linux distribution installation:
wsl --install -d Ubuntu
Install WSL2 manually
Enable WSL and VirtualMachinePlatform features in Powershell console:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
Reboot your PC. Download and install the Linux kernel update package:
Install the update via Powershell:
$wslUpdateInstallerUrl = "https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi"
$downloadFolderPath = (New-Object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path
$wslUpdateInstallerFilePath = "$downloadFolderPath/wsl_update_x64.msi"
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($wslUpdateInstallerUrl, $wslUpdateInstallerFilePath)
Start-Process -Filepath "$wslUpdateInstallerFilePath"
Set WSL default version to 2
wsl --set-default-version 2
As soon as Ubuntu distribution is installed you can download the dotfiles.
To avoid conflict with the existing files you can clone it the temporary folder.
Then copy with rsync
your dotfiles to $HOME directory.
git clone --separate-git-dir=$HOME/.dotfiles https://github.com/aubique/dotfiles-wsl.git tempfiles
rsync -vah --exclude '.git' tempfiles/ $HOME/
sudo rsync -vah $HOME/pub/etc/ /etc/
Once we're done with synchronizing our config files, we delete temporary folder, update configs, sub-modules and aliases.
for s in source "/etc/profile" "$HOME/.profile"; do source $s; done
dotfiles config status.showUntrackedFiles no
rm -r tempfiles
Get back to $HOME and synchronize the sub-modules:
cd && dotfiles submodule update --init
Install Vim plugins
This repo contains a Vundle sub-module repository. That's an extension manager that helps to manage environment with plugins properly.
In case you didn't get managed to download Vundle plugin during the set above, clone it directly from GitHub:
git clone https://github.com/VundleVim/Vundle.vim.git ~/.local/share/vim/bundle/Vundle.vim
Afterwards, you have to open Vim and run :PluginInstall
that downloads automatically the plugins listed in your $VIMDOTDIR/vimrc
.
If you've got Warning: Cannot find word list
error message,
create spell folder and download the files:
mkdir -pv ~/.config/vim/spell
vim 1.md +'set spell'
There is no point to keep all the user files on drive C:\
or the same partition that has the Windows directory.
You can't move all user files but you can certainly relocate Documents,
Pictures, Videos, Downloads, Music to a different partition (drive).
While you allocate a distinct partition with diskmgmt.msc
,
you may find more intuitive to adopt Linux Filesystem Hierarchy Standard (FHS) on it.
Then synchronize the Windows user shell folders with WSL home user folders.
You can change user folder programmatically executing the script with interactive prompt:
bash $RUNSCRIPTS_PATH/relocate_user_shell_folders.sh
The bash script is provided with
ps1
scripts, so make sure that Powershell is initialized properly.
The script automates such tasks:
- Move User Shell folder location to another drive or directory
- Link the $HOME user folders for WSL to the existing Windows user shell folders
- Update Windows system PATH environment variable with the links on new partition
Chocolatey is software management automation for Windows that wraps installers, executables, zips and scripts into compiled packages.
First, ensure that you are using an administrative shell.
To install Chocolatey
with powershell.exe
paste the copied text into your shell and press Enter:
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Now you can manage Windows applications and packages
using Chocolatey in administrative shell, check out a list of installed packages with choco list --local
.
Install a pack of applications listed in pkglist_choco.txt
:
Get-Content \\wsl$\Ubuntu\home\*\pub\pkglist_choco.txt | Select-String -NotMatch '^#.*' | ForEach {iex "choco install -y $_"}
After having installed Chocolatey and packages, you may want to clean up the context menu.
Remove VLC from context menu.
New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT
Remove-Item HKCR:\Directory\shell\AddToPlaylistVLC\ -Recurse
Remove-Item HKCR:\Directory\shell\PlayWithVLC\ -Recurse
Hide 7-Zip cascaded context menu.
With regedit.exe
you can find HKEY_CLASSES_ROOT\CLSID{23170F69-40C1-278A-1000-000100020000}
that's linked to the 7-Zip DLL file. All 7-Zip context menu options are defined in this DLL file,
they're invoked every time Windows needs to show the menu and thus not static.
You can disable these options with 7-Zip GUI (as Admin) via menu Tools -- Options -- 7-Zip -- Integrate 7-Zip to shell context menu
Bypass Windows requirements check in Ventoy
Ventoy is a good solution for installing Windows 11 on incompatible devices.
That said we have to explicitly set in JSON config the parameter VTOY_WIN11_BYPASS_CHECK
,
that creates certain Registry keys to bypass RAM, TMP, Secure Boot, CPU and Storage checks on the machine.
Run this in WSL2 to add the configuration JSON file to the ventoy
subfolder installed with Chocolatey:
powershell.exe "choco list -lo" | grep ventoy && \
cp -fT ~/pub/etc/ventoy.json "$(readlink -e /mnt/c/Users/*/AppData/Local/ventoy/ventoy)/ventoy.json"
Personalize Start menu
Turn Off Show recently opened items in Start, Jump Lists, and File Explorer" for Current User:
Set-ItemProperty -path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -name "Start_TrackDocs" -value "0"
Disable Recently added Apps List on the Start Menu for the User:
Set-ItemProperty -path "HKCU:\Software\Policies\Microsoft\Windows\Explorer" -name "HideRecentlyAddedApps" -value "1"
Otherwise, you set it up in Settings -> Personalization -> Start
For Windows 10 you can use another Powershell debloater from GitHub.
In order to open the administrative shell in Windows Terminal you may want to use
Gsudo, sudo
equivalent for Windows.
It allows to run commands with elevated permissions,
or to elevate the current shell, in the current console window or a new one.
In case you it's not installed with other packages, you can run
choco install gsudo
Now you can elevate permissions powershell.exe gsudo powershell.exe -nologo
.
If you set it up in settings.json
you can launch it on Windows Terminal.
To do that, you can paste the content of profiles.
- Windows 11:
$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json
- WSL 2:
/mnt/c/Users/*/AppData/Local/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState/settings.json
settings.json
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"launchMode": "maximized",
"profiles": {
"defaults": {
"closeOnExit": "graceful",
"cursorColor": "#FFFFFF",
"cursorShape": "filledBox",
"font": {
"face": "Cascadia Code",
"size": 12
},
"hidden": false,
"snapOnInput": true
},
"list": [
{
"colorScheme": "Campbell Powershell",
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "PowerShell",
"startingDirectory": null
},
{
"colorScheme": "Ubuntu-ColorScheme",
"guid": "{2c4de342-38b7-51cf-b940-2309a097f518}",
"name": "Ubuntu WSL \u25a4",
"source": "CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc"
},
{
"commandline": "wsl genie -c ~/.config/scripts/genie-tmux.sh",
"font": {
"face": "Lucida Console"
},
"guid": "{2862b68e-b019-4846-bbdd-5f10c363cb1a}",
"icon": "https://assets.ubuntu.com/v1/49a1a858-favicon-32x32.png",
"name": "Ubuntu WSL \ud83d\udccc",
"suppressApplicationTitle": true,
"useAcrylic": true
},
{
"commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
"guid": "{a266a539-53e6-4b70-abf9-dfd2f76a2b97}",
"hidden": true,
"icon": "ms-appx:///Images/Square44x44Logo.targetsize-32.png",
"name": "PowerShell \u26a1",
"padding": "0, 0, 0, 0",
"suppressApplicationTitle": true
}
]
},
"schemes": [
{
"background": "#0C0C0C",
"black": "#0C0C0C",
"blue": "#0037DA",
"brightBlack": "#767676",
"brightBlue": "#3B78FF",
"brightCyan": "#61D6D6",
"brightGreen": "#16C60C",
"brightPurple": "#B4009E",
"brightRed": "#E74856",
"brightWhite": "#F2F2F2",
"brightYellow": "#F9F1A5",
"cursorColor": "#FFFFFF",
"cyan": "#3A96DD",
"foreground": "#CCCCCC",
"green": "#13A10E",
"name": "Campbell",
"purple": "#881798",
"red": "#C50F1F",
"selectionBackground": "#FFFFFF",
"white": "#CCCCCC",
"yellow": "#C19C00"
},
The WSL environment we're about to setup has an environment variable -
${WIN_TERM}
that stores in .bashrc
a path to the Windows Terminal settings.json
.
Follow the steps above to get Ubuntu and dotfiles installed.
WSL2 startup
genie-tmux.sh
script uses Genie systemd and Tmux multiplexer, mostly described in the Genie installation step.
Check out docs.microsoft.com to figure out the profile settings in Windows Terminal.
You can set a rule in wf.msc
by subnet and interface dedicated to WSL2:
New-NetFirewallRule -DisplayName "from WSL2" -Direction Inbound -Action Allow -LocalAddress "172.16.0.0/12" -InterfaceAlias "vEthernet (WSL)"
You can also allow SSH connections on 32022 and open other ports to access VMWare virtual machines.
New-NetFirewallRule -DisplayName "SSH/RDP > WSL2" -Direction Inbound -Action Allow -Protocol TCP -LocalAddress 192.168.1.0/24,172.16.0.0/12 -LocalPort 32022,3389
New-NetFirewallRule -DisplayName "SSH/HTTP(S) > VMWare" -Direction Inbound -Action Allow -Protocol TCP -LocalAddress 192.168.1.0/24,172.16.0.0/12,172.28.144.0/24 -LocalPort 32020,32021,32023-32025,32080,32443,64190
To set up SSH Server on WSL2, check out the step describing it below.
To synchronize IDE settings between different machines you can use 2 ways:
- Settings Sync built-in feature or plugin
- Git repository for settings
You can use the built-in feature called Settings Sync that allows you to synchronize your Visual Studio Code settings across different devices using your GitHub or Microsoft account.
More info in VSCode Docs
If you have JetBrains Account with license activated, the no-brainer would be to link the settings to your account and use IDE Settings Sync plugin, since no additional configuration is required.
Check out JetBrains Docs for more info about sharing IDE settings.
Install Ubuntu packages and proceed with setup of the WSL2 environment.
Now we can install common dependencies and packages to setup our environment:
sudo apt update && grep -vE '^#' ~/pub/pkglist_apt.txt | xargs sudo apt install -y
To run sshd
on WSL2 machine, you should generate and upload the SSH key to your WSL2 environment.
It's well described in the "How To Generate and Upload SSH keys" gist.
For the first connection you can enable SSH password authentication via port 32022:
sudo ssh-keygen -A
sudo sed -E -e 's/^[# ]*(Port )[0-9]+$/\132022/g' -e 's/^[# ]*(PasswordAuthentication )no/\1yes/g' -i /etc/ssh/sshd_config
Execute the alias sshd_up
to run SSH server.
Configure Git:
git config --global push.default current
git config --global core.pager /usr/bin/less
Set username and email:
git config --global user.email "{{EMAIL}}"
git config --global user.name "{{USERNAME}}"
In order to manage your git repositories via SSH you should generate a new key on your new machine.
Generate a new SSH key:
ssh-keygen -t rsa -b 4096 -C "$(lsb_release -cs):$(date -I)" -f ~/.ssh/id_rsa_serv-user
Once generated you can force the key files to be kept permanently in your ~/.ssh/config
file.
To set the key specific to one host, you can do the following in config:
Host gitlab
User git
HostName gitlab.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_gl-user
Copy the public key to the clipboard:
xclip -sel c < ~/.ssh/id_rsa_gl-user.pub
Add the generated pubic SSH keys to your profile:
- Add your key to GitHub
- Add your key to GitLab
For title you can pick a name of the key, such as
${hostname.exe}-WSL2 (gl-au.pub): 2023-03-03
If you have GPG secret keys for signing commits or password manager, restore them.
On old system, create a backup of a GPG key:
gpg --list-secret-keys
gpg --export-secret-keys {{KEY_ID}} > /tmp/private.key
On new system, import the key:
gpg --import /tmp/private.key
Delete the /tmp/private.key
on both side and install password manager you prefer.
You can check permissions for gnupg with
gpg --card-status
If you have "Permission Denied" problem then you can type:
mkdir -pv ~/.config/gnupg
find $GNUPGHOME -type d -exec sudo chown $USER:$USER {} \; -exec chmod 700 {} \;
find $GNUPGHOME -type f -exec sudo chown $USER:$USER {} \; -exec chmod 600 {} \;
Allow starting services like Docker with a systemd "bottle", arkane-systems/genie.
Set up Microsoft repository (Genie depends on .NET)
curl -sL -o /tmp/packages-microsoft-prod.deb "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb"
sudo dpkg -i /tmp/packages-microsoft-prod.deb
rm -f /tmp/packages-microsoft-prod.deb
Set up Arkane-Systems GPG key:
sudo curl -sL -o /usr/share/keyrings/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg
Add its repository to the sources.list:
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/wsl-transdebian.gpg] \
https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main" \
| sudo tee /etc/apt/sources.list.d/wsl-transdebian.list > /dev/null
sudo apt update && sudo apt install -y systemd-genie
Copy the custom config to the system one:
sudo cp -f ~/pub/etc/genie.ini /etc/genie.ini
Disable unwanted systemd
services
Services without #
are supposed to be disabled, the ones with #
are for complete masking:
grep -vE '^#' ~/pub/systemd_disabled.txt | xargs sudo systemctl disable
sed -En 's/#([a-z0-9\.-])/\1/p' pub/systemd_disabled.txt | xargs sudo systemctl mask
First, download a repository key into individual file in a directory dedicated for them.
On Ubuntu the standard convention is
/usr/share/keyrings
but any directory works (aside from/etc/apt/trusted.gpg
which is the system keystore)
For the key provided in ascii-armor, like Docker's is, you'll need to dearmor the key to create a binary version, e.g.:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Then update your source file to refer to the Docker's key.
E.g., in /etc/apt/sources.list.d/
have a file named docker.list
with the contents:
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
This ensure that only files downloaded from official Docker repository can be signed by the that gpg key. Having the key in the system keystore allows any package in any repository to be signed by the docker key. Should that key ever compromised, it could be used to sign anything, coming from anywhere, like a hacked version of your kernel.
Optional step. For further security, create a preferences file.
E.g. in /etc/apt/preferences.d/
have a file named docker
with the command:
sudo tee /etc/apt/preferences.d/docker <<EOF
Package: *
Pin: origin "download.docker.com"
Pin-Priority: 100
EOF
Setting the
Pin-Priority
to a value less than other repositories, which are 500 by default, prevents packages in the Docker repository from overriding packages with the same name from default repositories. This way you don't get the standard system package (e.g. new version of openssl) from Docker repository unless you specifically request it.
Update the apt
package index, install the latest version of Docker Engine
and containerd and add user to docker
group:
sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io
sudo usermod -aG docker $USER
Now you can start Docker daemon via Systemd.
sudo curl -sL -o /usr/local/bin/docker-compose \
$(curl -s https://api.github.com/repos/docker/compose/releases/latest \
| grep -i "browser_download_url.*$(uname -s)-$(uname -m)" | grep -v sha \
| cut -d: -f2,3 | tr -d \")
Make docker-compose
executable:
sudo chmod +x /usr/local/bin/docker-compose
Volta is a fast and reliable JavaScript tool manager.
Install Volta while skipping volta setup
:
mkdir -p $VOLTA_HOME
curl https://get.volta.sh | bash -s -- --skip-setup
Install package managers and ng-cli
:
volta install node npm @angular/cli
SDKman is a tool for managing parallel versions of multiple Software Development Kits for the JVM such as Java, Gradle, Maven, Spring Boot and others.
Install SDKman without modifying shell config:
curl -sSL "https://get.sdkman.io?rcupdate=false" | bash
To initialize SDKMAN module scripts open a new terminal. Otherwise, run the following in the existing one:
source $SDKMAN_DIR/bin/sdkman-init.sh
Install AdoptOpenJDK 11:
sdk install java 11.0.11.hs-adpt
- Upgrade the Windows Tweaks part with refined integration scripts for Windows 11
- Migration from IntelliJ IDEA to VSCode
- Decouple
relocate_user_shell_folders.sh
from gist dependencies whose links are regularly updated
- https://github.com/microsoft/wslg
- https://github.com/arkane-systems/genie/wiki
- https://github.com/abergs/ubuntuonwindows
- https://docs.docker.com/engine/install/ubuntu
- https://github.com/jonaspetersorensen/dotfiles-wsl
- https://stackoverflow.com/questions/37776684/which-intellij-config-files-should-i-save-in-my-dotfiles
- https://askubuntu.com/questions/759880/where-is-the-ubuntu-file-system-root-directory-in-windows-subsystem-for-linux-an
- https://stefanos.cloud/kb/how-to-clear-the-powershell-command-history
- https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-tools?view=sql-server-ver15#ubuntu