This helps me to setup my Ubuntu workstations and maybe it’s useful for you as well! I am currently using Kubuntu 20.04, but most of the stuff should also work with older/newer releases.

I used to use a config management system to do all of this, but I got tired of all the work and am now just writing the important things down into this article. Works for me.



Some packages need to be installed first to make sure all the other commands work.

  • apt-transport-https
  • software-properties-common
sudo apt-get install apt-transport-https software-properties-common 

Package Manager Setup

I configure Ruby and Node package managers to install “global” packages into my home directory so I don’t have to use “sudo” to install them. For Python packages I use pipx which installs Python applications into isolated environments.


Create $HOME/.gemrc with the following content to ensure installation in the user directory and to avoid generating the documentation.

install: --user-install --no-document
update: --user-install --no-document


Create $HOME/.npmrc with the following content to make sure npm modules will be installed in the user directory.



  • Requires Python >= 3.6
  • Install packages:
    • python3-pip
    • python3-venv (for ensurepath library)
    • python3-dev (for applications that install native extensions)
  • Add ~/.local/bin to PATH
python3 -m pip install --user pipx



I am using some PPA repositories for packages which are not included in Ubuntu or where newer versions are available. Install before installing the Core packages!

sudo add-apt-repository ppa:git-core/ppa
sudo add-apt-repository ppa:peek-developers/stable
sudo add-apt-repository ppa:phoerious/keepassxc
sudo add-apt-repository ppa:nextcloud-devs/client


Some repositories need manual steps to set them up.

  • 1password - 1password
  • adoptopenjdk - Prebuilt OpenJDK Binaries for Free
  • docker - Official Docker packages
  • gpxsee - GPXsee packages
  • hashicorp - Hashicorp Software Packages
  • heroku - Heroku provides a CLI application
  • insomnia - Insomnia HTTP client
  • nodesource - the latest Node.js stable versions - make sure to check the version!
  • packagecloud - My personal package repo
  • signal
  • spotify
  • virtualbox
  • zerotier
# 1password
sudo apt-key adv --keyserver --recv-keys 3FEF9748469ADBE15DA7CA80AC2D62742012EA22
sudo sh -c 'echo "deb [arch=amd64] edge main" > /etc/apt/sources.list.d/1password.list'

# adoptopenjdk
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb focal main" > /etc/apt/sources.list.d/adoptopenjdk.list'

# docker
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] focal stable" > /etc/apt/sources.list.d/docker.list'

# gpxsee
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] /" > /etc/apt/sources.list.d/gpxsee.list'

# hashicorp
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] focal main" > /etc/apt/sources.list.d/hashicorp.list'

# heroku
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb ./" > /etc/apt/sources.list.d/heroku.list'

# insomnia
sudo sh -c 'echo "deb [trusted=yes arch=amd64] default all" > /etc/apt/sources.list.d/insomnia.list'

# nodesource
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb focal main" > /etc/apt/sources.list.d/nodesource.list'

# packagecloud
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb focal main" > /etc/apt/sources.list.d/packagecloud.list'

# signal
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] xenial main" > /etc/apt/sources.list.d/signal.list'

# spotify
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb stable non-free" > /etc/apt/sources.list.d/spotify.list'

# virtualbox
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] focal contrib" > /etc/apt/sources.list.d/virtualbox.list'

# zerotier
curl -fsLS "" | sudo apt-key add -
sudo sh -c 'echo "deb bionic main" > /etc/apt/sources.list.d/zerotier.list'

sudo apt-get update


  • apt-file
  • build-essential
  • curl
  • dstat
  • flameshot
  • fonts-dejavu-core
  • git-crypt
  • gnome-disk-utility
  • htop
  • iotop
  • ipcalc
  • jq
  • libavcodec-extra
  • linux-generic-hwe-20.04-edge
  • linux-tools-generic-hwe-20.04-edge
  • lftp
  • msmtp-mta
  • multitail
  • mutt
  • ncdu
  • ngrep
  • nmap
  • offlineimap
  • passwdqc
  • qiv
  • rpm
  • ruby
  • ruby-dev
  • shellcheck
  • sqlite3
  • tilix
  • tmux
  • tree
  • ttf-mscorefonts-installer
  • vim
  • virtualbox
  • w3m
  • xclip
sudo apt-get install apt-file build-essential curl dstat flameshot fonts-dejavu-core git-crypt gnome-disk-utility htop iotop ipcalc jq libavcodec-extra linux-generic-hwe-20.04-edge linux-tools-generic-hwe-20.04-edge lftp msmtp-mta multitail mutt ncdu ngrep nmap offlineimap passwdqc qiv rpm ruby ruby-dev shellcheck sqlite3 tilix tmux tree ttf-mscorefonts-installer vim virtualbox w3m xclip 


These are provided by the PPA repositories mentioned above.

  • git
  • keepassxc
  • nextcloud-client-dolphin
  • peek
sudo apt-get install git keepassxc nextcloud-client-dolphin peek 


These are provided by the custom repositories mentioned above.

sudo apt-get install 1password adoptopenjdk-8-hotspot adoptopenjdk-11-hotspot adoptopenjdk-12-hotspot desk devd docker-ce git-radar glow godeb gpxsee gron heroku hub hugo insomnia jid jl mkcert nodejs portecle restic s5cmd signal-desktop spotify-client terraform udict vagrant yj zerotier-one 


These are installed via rubygems.

  • gist
gem install --no-document gist 

Python Pipx

These are installed via pipx.
  • httpie
  • pygments

pipx install httpie

pipx install pygments


sudo apt-get purge nano


Some packages are not available in package repositories.



The Vagrant debian package can be downloaded from the downloads page. Take the latest version.

JetBrains Toolbox App

The Toolbox app helps with installing JetBrains products.

It also offers a Chrome extension that makes it possible to open GitHub projects in IntelliJ without having to clone it manually.


Clone and build binary via go build.


A electron based desktop application for Todoist:


There are frequent releases and the binary can update itself, just download the latest version from the homepage.

mkdir -p ~/local/bin
curl -fsSL -o ~/local/bin/youtube-dl
chmod +x ~/local/bin/youtube-dl






git config --global checkout
git config --global alias.diffy "diff -- ':(exclude)**/yarn.lock'"
git config --global alias.fpush "push --force-with-lease"
git config --global alias.pp "pull --prune"
git config --global alias.rh "reset HEAD"
git config --global color.ui true
git config --global core.quotepath false
git config --global diff.compactionHeuristic true
git config --global diff.indentHeuristic true
git config --global diff.noprefix true
git config --global diff.relative true
git config --global diff.renames true
git config --global diff.submodule log
git config --global init.defaultBranch main
git config --global log.abbrevCommit true
git config --global pull.ff only:
git config --global push.default simple
git config --global status.submodulesummary 1


Create a ~/.gitradarrc with the following content:

cat << __EOF > ~/.gitradarrc
GIT_RADAR_FORMAT=" git:(\\x01\\033[0m\\x02%{remote: }%{branch}%{ :local})\\x01\\033[0m\\x02%{ :stash}%{ :changes} $ "

Google Chrome


  • You and Google
    • Allow Chrome sign-in: disable
    • Autocomplete searches and URLs: disable
    • Show suggestions for similar pages: disable
  • Autofill
    • Passwords
      • Offer to save passwords: disable
      • Auto Sign-in: disable
    • Payment methods
      • Save and fill payment methods: disable
    • Addresses and more
      • Save and fill addresses: disable
  • Privacy and security
    • More
      • Safe Browsing: disable
      • Send a “Do Not Track” request with your browsing traffic: enable
      • Allow sites to check if you have payment methods saved: disable
      • Preload pages for faster browsing and searching: disable
  • Appearance
    • Show home button: enable
    • Show bookmarks bar: enable
  • On startup
    • Continue where you left off: enable
  • Advanced
    • Languages
      • Add “German” language
      • Offer to translate pages that aren’t in a language you read: disable
      • Spell check
        • Basic spell check: enable
      • Use spell check Forward
        • English: enable
        • German: enable
    • Printing
      • Google Cloud Print
        • Show notifications when new printers are detected on the network: disable


  • chrome://flags/#tab-hover-cards To disable the annoying tab hover cards


  • 1Password X
  • Awesome Screenshot Minus
  • Octotree
  • Gitako - GitHub file tree (alternative to Octotree)
  • Plasma Integration
  • React Developer Tools
  • Todoist for Chrome
  • uBlock Origin
    • Enable “prebake” 3rd party list
  • f*ck overlays
Chrome Apps
  • Google Docs Offline: remove
  • Docs: remove
  • Sheets: remove
  • Slides: remove


  • Settings > Configure Kate > Editor Component > Appearance > General
    • Whitespace Highlighting
      • Whitespaces: Trailing
  • Settings > Configure Kate > Editor Component > Editing > General
    • Input Mode: Vi
  • Settings > Configure Kate > Editor Component > Editing > Vi Input Mode
    • Let Vi commands override Kate shortcuts: enable
  • Settings > Configure Kate > Editor Component > Open/Save > General
    • Automatic Cleanups on Save
      • Remove trailing spaces: In Entire Document

Nextcloud Desktop

  • Make sure to enable all folders (big ones will be disabled by default)


  • Global
    • Behavior
      • Focus a terminal when the mouse moves over it: enable
      • Autohide the mouse pointer when typing: enable
    • Clipboard
      • Warn when attempting unsafe paste: disable
  • Appearance
    • Window style: Disable CSD, hide toolbar
    • Terminal title style: none
  • Quake
    • Size
      • Height percent: 40
      • Width percent: 80
      • Alignment: Center
    • Options
      • Show terminal on all workspaces: enable
  • Shortcuts
    • Session
      • Add terminal down: Shift+Ctrl+o
      • Add terminal right: Shift+Ctrl+e
    • Window
      • Switch to next session: disabled
      • Switch to previous session: disabled
  • Profiles
    • Default
      • General
        • Custom font: Monospace Regular 12
        • Terminal bell: None
      • Command
        • Run command as login shell: enable
      • Color
        • Color scheme: Orchis
        • Color palette:
        • Transparency: a little
      • Scrolling
        • Show scrollbar: disable
        • Limit scrollback to: 32768
    • Default Quake (clone of Default)
      • General
        • Custom font: Monospace regular 11

KDE System


  • Move panel to the top of the screen
  • Add widgets
    • Weather report (left of the clock/date widget)
    • System Load Viewer (right of the desktop pager)

System Tray

  • Entries
    • System Services
      • Clipboard: disabled

Digital Clock

  • Appearance
    • Show date: enable
    • Date format: Custom (yyyy-MM-dd | dddd)
  • Calendar
    • Show week numbers: enable
    • Astronomical events: enable
  • Time Zones
    • Add time zones: (will show on hovering the time with the mouse)
      • Berlin
      • Chicago (central time)
      • Denver (mountain time)
      • Los Angeles (pacific time)
  • Astronomical Events
    • Lunar phases: enable
    • Astronomical seasons: enable

System Settings

  • Appearance > Global Theme

  • Appearance > Plasma Style

    • Breeze Dark
  • Appearance > Application Style

    • Application Style
      • Breeze
    • Window Decorations > Theme
      • Get New Window Decorations
        • Install: “McMojave Aurorae”
      • Select: McMojave
      • Configure:
        • Button size: normal
      • Use theme’s default border size: “No Borders”
    • Window Decorations > Titlebar Buttons
      • Move “Close” button to the very left
      • Move “Minimize” button right of the “Close” button
      • Move “Maximize” button right of the “Minimize” button
      • Move “Menu” to the very right
      • Add “Application menu” right of the “Maximize” button
      • Remove “Context help” button
      • Remove “On all desktops” button
  • Appearance > Cursors

    • Size: “Resolution dependent” (switch to “24” if cursor is too big in some areas)
  • Workspace > Workspace Behavior > General Behavior

    • Click behavior: Double-click to open files and folders
  • Workspace > Workspace Behavior > Screen Edges

    • Upper left: No Action
    • Bottom left: Present Windows - All Desktops
  • Workspace > Workspace Behavior > Screen Locking

    • Activation
      • Lock screen
        • Automatically after: 30 minutes
        • After waking up from sleep
      • Allow unlocking without password for: 5 seconds
  • Workspace > Workspace Behavior > Virtual Desktops

    • Create 4 desktop
    • Options
      • Navigation wraps around: enable
      • Show animation when switching: disable
  • Workspace > Window Management > Window Behavior

    • Focus
      • Focus stealing prevention: None
        • This fixes focus issues with GTK+ applications, e.g. tilix not having focus after launch
  • Workspace > Window Management > Task Switcher

    • Main
      • Visualization: Thumbnail Grid
      • Shortcuts
        • Current application
          • Forward: Ctrl+Tab
  • Workspace > Shortcuts > Global Shortcuts

    • KWin
      • Maximize Window: Meta+Ctrl+m
      • Switch to Desktop 1: Alt+1
      • Switch to Desktop 2: Alt+2
      • Switch to Desktop 3: Alt+3
      • Switch to Desktop 4: Alt+4
  • Workspace > Shortcuts > Standard Shortcuts

    • Beginning of Line (Alternate): Ctrl+a
    • End of Line (Alternate): Ctrl+e
  • Workspace > Shortcuts > Custom Shortcuts

    • Edit: Add new global command/url shortcut
      • Name: Start Terminal
      • Trigger: Ctrl+Alt+Enter
      • Action: tilix
    • Edit: Add new global command/url shortcut
      • Name: Start Quake Terminal
      • Trigger: F3
      • Action: tilix --quake --profile="Default Quake"
    • Edit: Add new global command/url shortcut
      • Name: Capture Rectangular Region into Clipboard
      • Trigger: Ctrl+Shift+Print
      • Action: spectacle -bcr or flameshot gui
  • Workspace > Search > File Search

    • Do not search in these locations:
      • ~/Mail
      • /media/<username>
  • Workspace > Search > KRunner

    • Available Plugins
      • Activities: disable
      • Bookmarks: disable
      • Browser Tabs: disable
      • Desktop Sessions: disable
      • Software Center: disable
      • Web Shortcuts: disable
      • Windowed widgets: disable
  • Personalization > Account Details

    • KDE Wallet
      • Wallet Preferences
        • Close when unused for: 10 min
        • Close when screensaver starts: enable
        • Show Manager in System Tray: enable
      • Access Control
        • Prompt when an application accesses a wallet: enable
  • Personalization > Other Notifications

    • Show notifications for:
      • Incomplete language support: disable
  • Personalization > Applications > Default Applications

    • Terminal Emulator: tilix
  • Personalization > Applications > Diagnostics

    • Send error reports to Canonical: disable
  • Hardware > Input Devices > Keyboard

    • Hardware
      • Keyboard Repeat
        • Turn on: enable
        • Delay: 250ms
        • Rate: 25,00 repeats/s
        • Troubleshooting:
          • This doesn’t seem to work on 20.04, use xset instead: xset r rate 250 25
  • Hardware > Display and Monitor > Night Color

    • Activate Night Color: enable
    • Night Color Temperature: 3500 K
    • Activation time: Sunset to sunrise at current location
  • Hardware > Power Management > Energy Saving

    • On AC Power
      • Button events handling
        • When laptop lid closed: Lock screen


Change Default Terminal Application

sudo update-alternatives --config x-terminal-emulator


In its default configuration, Docker only allows the creation of 31 networks. This can be problematic when using lots of different docker-compose environments which create one or more networks each.

To increase the number of available networks, use the following default-address-pools setting in /etc/docker/daemon.json:

  "default-address-pools": [
      "scope": "local",
      "base": "",
      "size": 24


Enable ufw firewall and disable logging to avoid spamming the dmesg buffer.

sudo ufw enable
sudo ufw logging off

Inotify Watches Limit

This is needed for IntelliJ to keep track of all files efficiently.

cat <<__EOF > /etc/sysctl.d/intellij.conf
# Raise limit to make sure IntelliJ can monitor files efficiently
fs.inotify.max_user_watches = 524288

sudo sysctl -p --system

JDK Settings

Put the following into /etc/profile.d/ to configure the default JDK.

# Choose the default JDK:

export J2REDIR=$JDK_DIR/jre
export PATH=$PATH:$JDK_DIR/bin:$JDK_DIR/db/bin:$JDK_DIR/jre/bin


Replace all de_DE.UTF-8 in /etc/default/locale with en_US.UTF-8 and run update-locale.


Install the following file to /etc/sudoers.d/<username>:



cat <<__EOF > /etc/sysctl.d/99-swappiness.conf
# Only use swap when really needed
vm.swappiness = 1

sudo sysctl -p --system


Autostart Scripts

Keyboard Repeat Rate & Delay

Setting the values in the system settings doesn’t seem to work on 20.04. Use the following script to automatically set the rate at login.

cat <<__EOF > .config/autostart-scripts/


xset r rate \$delay \$repeats_s

Unlock SSH Key on Login


mkdir -p .config/plasma-workspace/env .config/autostart-scripts

cat <<__EOF > .config/plasma-workspace/env/

# Set askpass programs to use
export SSH_ASKPASS="/usr/bin/ksshaskpass"
export GIT_ASKPASS="/usr/bin/ksshaskpass"

cat <<__EOF > .config/autostart-scripts/

# Automatically unlock default ssh keys on login
ssh-add -q < /dev/null

# Unlock custom keys
#ssh-add -q ~/.ssh/id_rsa ~/.ssh/another_key < /dev/null

chmod +x .config/plasma-workspace/env/ .config/autostart-scripts/

Emacs key bindings

gsettings set org.gnome.desktop.interface gtk-key-theme "Emacs"

File Indexing

File indexing could be slow with big files. The following commands might help:

balooctl indexSize
balooctl disable
balooctl suspend

Ignore settings are in ~/.config/baloofilerc

Also see:

Shell Profile

cat <<__EOF >> $HOME/.profile
umask 022

user_bin+=" \$HOME/.gem/ruby/2.7.0/bin"
user_bin+=" \$HOME/.local/node_modules/bin"
user_bin+=" \$HOME/Nextcloud/bin"
user_bin+=" \$HOME/Local/bin"
user_bin+=" \$HOME/bin"

for path in $user_bin; do
	if [ -d "\$path" ] ; then

# Include custom bash completion config
if [ -d \$HOME/.bash_completion.d ]; then
	for file in \$HOME/.bash_completion.d/*; do
		. $file

# Make sure to use natural sort for ls(1).
alias ls="ls --color=auto -v"

alias be="bundle2.7 exec"
alias bundle="bundle2.7"
alias glow="glow -p -w \\$COLUMNS"
alias xxclip="xclip -selection clipboard"


Click Handler

After editing the Zoom.desktop file it needs to be re-registered with the system.

xdg-mime default Zoom.desktop x-scheme-handler/zoommtg


Display Scaling

In $HOME/config/zoomus.conf set autoScale=false to avoid a huge Zoom UI when desktop is scaled. The scaleFactor can be changed from 1 to 2 if the Zoom UI is too small.


AER severity=Corrected Errors

Temporary fix for AER’s excessive severity=Corrected logging for Intel Wireless (Avell G1513 Fire V3):

Jabra Evolve Headset Breaks Mouse Buttons

Create /etc/X11/xorg.conf.d/fix-jabra.conf with the following content:

Section "InputClass"
  Identifier "Jabra Link 370"
  MatchUSBID "0b0e:245d"
  Option "Ignore" "true"

Make SSH Key Work

gnome-keyring requires the id_rsa file to have theProc-Type and DEK-Info in it. Otherwise the ssh agent does not work. A key missing this information can be converted by executing ssh-keygen -t to change the passphrase.

If the gnome-keyring stuff should be disabled:

NetworkManager VPN DNS Issue

When connecting to a VPN, NetworkManager does not take the pushed DNS settings into account and continues to use the local dnsmasq server. This leads to non-working DNS.

Comment the dns=dnsmasq line in /etc/NetworkManager/NetworkManager.conf file to fix it.

UEFI Restore Menu Item

If the “ubuntu” menu item is gone from the UEFI boot manager, it can be restored with the following command.

sudo grub-install --bootloader-id ubuntu /dev/sda

This might happen after enabling/disabling the Secure Boot option.

See also:

rEFInd Boot Manager

Useful to find EFI boot partition if the “ubuntu” entry is gone from the UEFI boot manager.


Thinkpad BIOS Update


Download the bootable ISO image from the Lenovo site.

Extract the BIOS image from the ISO file and put it onto a USB thumb drive. (sdb in this case)

sudo apt-get install genisoimage
geteltorito -o gjuj23us.img gjuj23us.iso
sudo dd if=gjuj23us.img of=/dev/sdb bs=512K

After that, the USB drive can be booted.

Using Firmware Update Daemon

The fwupd tool can automatically update the BIOS on supported machines.


Switch to KDE Neon

An Ubuntu or Kubuntu installation can be swtiched to KDE Neon with the following steps. (this is not officially supported, though)

wget -qO - '' | sudo apt-key add -
sudo apt-add-repository
sudo apt-get update
sudo apt-get install neon-desktop

Check if there are any held back packages after the steps above. If so, repeat the following steps until everything has been updated and installed.

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade