Skip to content

Instantly share code, notes, and snippets.

@yipo
Last active February 12, 2026 19:59
Show Gist options
  • Select an option

  • Save yipo/af074b5ed29524aa4a45d438cde185d3 to your computer and use it in GitHub Desktop.

Select an option

Save yipo/af074b5ed29524aa4a45d438cde185d3 to your computer and use it in GitHub Desktop.
My Ubuntu desktop setup

Ubuntu Desktop Setup

These are my scripts for setting up a handy Ubuntu desktop. They also include solutions to problems people may hit when migrating from Windows to Ubuntu, based on my own experience. With Make, you can select the features you want by choosing targets.

Usage

  • Install the prerequisite:
    sudo apt update
    sudo apt install -y make
  • Run one or more targets:
    make [<target> ...]
    With no targets, the default setup is applied.
  • Reboot.

Key Features

  • gnome-extension/dash-to-panel: A Windows-like taskbar to feel familiar.
  • google-chrome: Install Google Chrome via Flatpak (not available in the Snap Store).
  • google-chrome.dual-profile: Google Chrome with distinct taskbar icons for Home/Work profiles.
  • qemu-kvm: Operate virtual machines.
  • remmina: An SSH and RDP client for Linux.
  • remote-desktop: Allows this machine to be managed over LAN via RDP.
  • samba: Share files over LAN and access hosts via hostname.local.
    • To share a folder, with nautilus-share installed, right-click it and choose "Sharing Options".
  • sublime-text: The text editor.
  • taiwan-locale
    • Install the required input method and recommended GNOME extension.
    • For developers, keep Ubuntu in English while using regional formats.
  • vs-code: Visual Studio Code for development, with Git and Docker integration.
  • xbox-controller-connection: Xbox controllers may appear paired but still not work. In most cases, re-pairing a few times fixes it without extra setup. If not, try this target and test with the included joystick-tester.

Some steps may still require manual operation.

Tested On

  • Ubuntu 25.10

Known issue: In GNOME, the Flatpak version of Google Chrome does not group dock icons by profile. Windows are grouped under a single icon because GNOME groups by App ID and ignores WM_CLASS for Flatpak apps.

config := .var/app/com.google.Chrome/config
desktop_entry := .local/share/applications
template := $(dir $(lastword $(MAKEFILE_LIST)))google-chrome.template.desktop
.PHONY: all config-alias
all: config-alias
all: $(desktop_entry)/google-chrome.home.desktop
all: $(desktop_entry)/google-chrome.work.desktop
$(config) $(desktop_entry):
mkdir -p $@
$(config)/google-chrome.home: $(config)
cd $< && (if test -d google-chrome -a ! -h google-chrome; then mv -T google-chrome google-chrome.home; fi)
config-alias: $(config) $(config)/google-chrome.home
cd $< && (test -h google-chrome || ln -s google-chrome.home google-chrome)
$(desktop_entry)/google-chrome.home.desktop: $(template) $(desktop_entry)
CONFIG=$(config) CLASS=google-chrome.home NAME=Home envsubst < $< > $@
chmod +x $@
$(desktop_entry)/google-chrome.work.desktop: $(template) $(desktop_entry)
CONFIG=$(config) CLASS=google-chrome.work NAME=Work envsubst < $< > $@
chmod +x $@
# Known issue: In GNOME, the Flatpak version of Google Chrome does not group
# dock icons by profile. Windows are grouped under a single icon because GNOME
# groups by App ID and ignores `WM_CLASS` for Flatpak apps.
[Desktop Entry]
Type=Application
Name=Google Chrome (${NAME})
Icon=com.google.Chrome
Exec=flatpak run com.google.Chrome --class=${CLASS} --user-data-dir=${CONFIG}/${CLASS} %U
Terminal=false
StartupNotify=true
StartupWMClass=${CLASS}
#!/bin/sh
set -e
if test $# -ne 1; then
echo "Usage: $0 <extension-uuid>" >&2
exit 1
fi
# Reference: https://github.com/mjakeman/extension-manager/blob/v0.6.5/src/local/org.gnome.Shell.Extensions.xml
gdbus call --session \
--dest org.gnome.Shell.Extensions \
--object-path /org/gnome/Shell/Extensions \
--method org.gnome.Shell.Extensions.InstallRemoteExtension \
"$1" || echo The error above is ignored because the D-Bus call fails if the confirmation dialog is not answered quickly enough.
.PHONY: default ufw-enable remote-desktop xbox-controller-connection
.PHONY: apt-update docker flatpak git joystick-tester qemu-kvm samba snapd taiwan-locale
.PHONY: remmina sublime-text vs-code google-chrome google-chrome.dual-profile
.PHONY: gnome-extension/dash-to-panel gnome-extension/kimpanel
default: samba taiwan-locale remmina sublime-text vs-code google-chrome gnome-extension/dash-to-panel
# System
ufw-enable:
sudo ufw --force enable
remote-desktop: ufw-enable
@yelp help:gnome-help/remote-login &
@echo --- 'Please follow the guide to enable Remote Desktop. Then, close the "Settings" window to continue.'
gnome-control-center system remote-desktop
sudo ufw allow from 192.168.0.0/16 to any port 3389 proto tcp comment 'remote desktop'
sudo ufw allow from fd00::/8 to any port 3389 proto tcp comment 'remote desktop'
xbox-controller-connection: joystick-tester
# usually not required: echo 1 | sudo tee /sys/module/bluetooth/parameters/disable_ertm
sudo service bluetooth restart
service bluetooth status | head
jstest-gtk &
@echo --- Try to forget your Xbox controller, pair it again, and test it with the joystick tester.
# APT packages
apt-update:
sudo apt update
sudo apt -y upgrade
docker: apt-update
sudo apt install -y docker.io docker-compose-v2
sudo adduser $(USER) docker
flatpak: apt-update
sudo apt install -y gnome-software-plugin-flatpak
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
git: apt-update
sudo apt install -y git
joystick-tester: apt-update
sudo apt install -y jstest-gtk
qemu-kvm: apt-update
sudo apt install -y virt-manager
kvm-ok
qemu-system-x86_64 -version
libvirtd -V
samba: apt-update ufw-enable
sudo apt install -y samba nautilus-share wsdd-server
@echo --- Since Samba doesn\'t use the system account password, please set up a Samba password for your account.
sudo smbpasswd -a $(USER)
sudo adduser $(USER) sambashare
sudo ufw allow from 192.168.0.0/16 to any app samba
sudo ufw allow from fd00::/8 to any app samba
sudo ufw allow from 192.168.0.0/16 to any app wsdd
sudo ufw allow from fd00::/8 to any app wsdd
snapd: apt-update
sudo apt install -y snapd
taiwan-locale: apt-update gnome-extension/kimpanel
sudo apt install -y fcitx5-table-boshiamy language-pack-zh-hant
@echo --- Please add the required input methods.
fcitx5 2> /dev/null & fcitx5-configtool
im-config -n fcitx5
# Snaps
remmina: snapd
sudo snap install remmina
sudo snap connect remmina:password-manager-service :password-manager-service
sudo snap connect remmina:ssh-keys :ssh-keys
sudo snap connect remmina:ssh-public-keys :ssh-public-keys
# More permissions can be toggled in the Remmina page of the Settings > Apps panel.
sublime-text: settings.sublime-text.json snapd
sudo snap install --classic sublime-text
install -DT $< $(HOME)/.config/sublime-text/Packages/User/Preferences.sublime-settings
vs-code: settings.vs-code.json snapd git docker
sudo snap install --classic code
install -DT $< $(HOME)/.config/Code/User/settings.json
# Flatpak apps
google-chrome: flatpak
sudo flatpak install -y com.google.Chrome
google-chrome.dual-profile: google-chrome.dual-profile.mk google-chrome
$(MAKE) -C $(HOME) -f $(abspath $<)
# GNOME extensions
gnome-extension/dash-to-panel: settings.dash-to-panel.ini
sh install-gnome-extension.sh dash-to-panel@jderose9.github.com
dconf load /org/gnome/shell/extensions/dash-to-panel/ < $<
gnome-extension/kimpanel:
sh install-gnome-extension.sh kimpanel@kde.org
[/]
appicon-margin=4
appicon-padding=8
multi-monitors=false
panel-element-positions='{"0":[{"element":"showAppsButton","visible":true,"position":"stackedTL"},{"element":"activitiesButton","visible":true,"position":"stackedTL"},{"element":"leftBox","visible":true,"position":"stackedTL"},{"element":"taskbar","visible":true,"position":"centerMonitor"},{"element":"centerBox","visible":true,"position":"stackedBR"},{"element":"rightBox","visible":true,"position":"stackedBR"},{"element":"dateMenu","visible":true,"position":"stackedBR"},{"element":"systemMenu","visible":true,"position":"stackedBR"},{"element":"desktopButton","visible":true,"position":"stackedBR"}]}'
showdesktop-button-width=2
tray-padding=2
window-preview-size=120
{
"line_padding_top": 4,
"line_padding_bottom": 4,
"draw_white_space": "all",
"show_encoding": true
}
{
"editor.lineHeight": 2,
"editor.renderWhitespace": "all",
"editor.rulers": [
80,
100
],
"git.blame.editorDecoration.enabled": true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment