Skip to content

Instantly share code, notes, and snippets.

@birgersp
Last active May 2, 2026 18:13
Show Gist options
  • Select an option

  • Save birgersp/c607fa3c7dc2ba9eec9f95300cf4fddb to your computer and use it in GitHub Desktop.

Select an option

Save birgersp/c607fa3c7dc2ba9eec9f95300cf4fddb to your computer and use it in GitHub Desktop.
Fedora Silverblue install script
#!/usr/bin/env bash
DNF_PACKAGES=(
git
zsh
gnome-tweaks
pipx
mosh
code
dbus-tools
yaru-theme
https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
https://desktop.docker.com/linux/main/amd64/docker-desktop-x86_64.rpm
)
FLATPAK_APPS=(
com.github.git_cola.git-cola
org.pgadmin.pgadmin4
com.spotify.Client
com.discordapp.Discord
io.github.Faugus.faugus-launcher
org.sqlitebrowser.sqlitebrowser
)
# Helper functions
tolower() {
echo "$1" | tr '[:upper:]' '[:lower:]'
}
log() {
printf "\n[setup] %s\n" "$1"
}
check_install_vscode_extension() {
local targetFolder="$(tolower "$1")"
targetFolder="$(echo $targetFolder | sed 's/@/-/g')"
echo $1 $targetFolder
if ! find "$HOME/.vscode/extensions" -maxdepth 1 -type d -name "$targetFolder*" | grep -q .; then
code --install-extension $1
fi
}
command_exists() {
if command -v "$1" >/dev/null 2>&1; then
# in bash code 0 means success
return 0
fi
return 1
}
get_state() {
if [ -f ~/.local/state/birgersp-setup/state ]; then
cat ~/.local/state/birgersp-setup/state
fi
}
set_state() {
mkdir -p ~/.local/state/birgersp-setup/
echo "$1" > ~/.local/state/birgersp-setup/state
}
# Setup steps
require_fedora() {
if [[ ! -f /etc/os-release ]]; then
echo "Cannot detect OS: /etc/os-release missing."
exit 1
fi
# shellcheck disable=SC1091
source /etc/os-release
if [[ "${ID:-}" != "fedora" ]]; then
echo "This script is for Fedora only. Detected: ${PRETTY_NAME:-unknown}."
exit 1
fi
}
install_packages() {
log "Installing missing dnf packages..."
# docker repo
dockerRepoFile="/etc/yum.repos.d/docker-ce.repo"
if [ ! -f "$dockerRepoFile" ]; then
sudo wget https://download.docker.com/linux/fedora/docker-ce.repo -O "$dockerRepoFile"
fi
# vscode repo
vscodeRepoFile="/etc/yum.repos.d/vscode.repo"
if [ ! -f "$vscodeRepoFile" ]; then
sudo tee "$vscodeRepoFile" > /dev/null <<-EOF
[vscode-yum]
name=vscode-yum
baseurl=https://packages.microsoft.com/yumrepos/vscode/
repo_gpgcheck=0
gpgcheck=0
enabled=1
gpgkey=https://packages.microsoft.com/yumrepos/vscode/repodata/repomd.xml.key
EOF
fi
# nautilus patch repo
nautilusTypeaheadRepoFile="/etc/yum.repos.d/nelsonaloysio-nautilus-typeahead-fedora-43.repo"
if [ ! -f "$nautilusTypeaheadRepoFile" ]; then
sudo wget "https://copr.fedorainfracloud.org/coprs/nelsonaloysio/nautilus-typeahead/repo/fedora-43/nelsonaloysio-nautilus-typeahead-fedora-43.repo" -O "$nautilusTypeaheadRepoFile"
fi
sudo rpm-ostree install -y "${DNF_PACKAGES[@]}"
sudo rpm-ostree override remove nautilus nautilus-extensions papers-nautilus --install nautilus-typeahead
# # insync
# sudo rpm --import https://d2t3ff60b2tol4.cloudfront.net/repomd.xml.key
# sudo tee /etc/yum.repos.d/insync.repo > /dev/null <<-EOF
# [insync]
# name=insync repo
# baseurl=http://yum.insync.io/fedora/\$releasever/
# gpgcheck=1
# gpgkey=https://d2t3ff60b2tol4.cloudfront.net/repomd.xml.key
# enabled=1
# metadata_expire=120m
# EOF
# # nvidia drivers
# if lspci | grep -i nvidia >/dev/null; then
# echo "NVIDIA GPU present"
# rpm-ostree install -y akmod-nvidia xorg-x11-drv-nvidia-cuda
# else
# echo "No NVIDIA GPU"
# fi
}
setup_flatpak() {
if ! command -v flatpak >/dev/null 2>&1; then
log "Installing flatpak..."
sudo dnf install -y flatpak
fi
sudo flatpak remote-add --if-not-exists \
flathub \
https://flathub.org/repo/flathub.flatpakrepo
log "Installing missing flatpak apps..."
flatpak install -y flathub "${FLATPAK_APPS[@]}"
}
install_nvm() {
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install 22
}
install_deno() {
if ! command -v deno >/dev/null 2>&1; then
log "Installing deno..."
curl -fsSL https://deno.land/install.sh | sh
fi
}
setup_vscode() {
check_install_vscode_extension AlexShen.classdiagram-ts
check_install_vscode_extension aljazsim.tsco@1.0.31
check_install_vscode_extension dbaeumer.vscode-eslint
check_install_vscode_extension denoland.vscode-deno
check_install_vscode_extension edonet.vscode-command-runner
check_install_vscode_extension eeyore.yapf
check_install_vscode_extension EnkelDigital.relative-goto
check_install_vscode_extension esbenp.prettier-vscode
check_install_vscode_extension fractalbrew.backticks
check_install_vscode_extension mhutchie.git-graph
check_install_vscode_extension ms-ossdata.vscode-pgsql
check_install_vscode_extension ms-python.python
check_install_vscode_extension ms-vscode-remote.vscode-remote-extensionpack
check_install_vscode_extension MylesMurphy.prettify-ts
check_install_vscode_extension Prisma.prisma
check_install_vscode_extension retepaskab.relativegoto
check_install_vscode_extension ryuta46.multi-command
check_install_vscode_extension YoavBls.pretty-ts-errors
}
install_gnome_extensions() {
pipx install gnome-extensions-cli
pipx ensurepath
if ! command -v gnome-extensions-cli >/dev/null 2>&1; then
echo "Command \"install gnome-extensions-cli\" not found. Try re-running in a new shell (where PATH is loaded)"
exit 1
fi
gnome-extensions-cli install\
switcher@landau.fi\
dash-to-panel@jderose9.github.com\
emoji-copy@felipeftn\
clipboard-indicator@tudmotu.com\
window-calls@domandoman.xyz
}
configure_gnome() {
dconf write "/org/gnome/desktop/interface/icon-theme" "'Yaru-blue'"
dconf write "/org/gnome/desktop/wm/preferences/resize-with-right-button" "true"
# key bindings
# disable Super+p key
dconf write "/org/gnome/mutter/keybindings/switch-monitor" "@as []"
# disable "open terminal" hotkey
dconf write "/org/gnome/settings-daemon/plugins/media-keys/terminal" "@as []"
# add a custom key binding for Control+Alt+t
dconf write "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings" "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']"
dconf write "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/binding" "'<Control><Alt>t'"
dconf write "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/command" "'bash $HOME/repo/tools/linux/hotkeys.sh --open-terminal'"
dconf write "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/name" "'open terminal'"
# use Control+Alt+h to open clipboard history
dconf write "/org/gnome/shell/extensions/clipboard-indicator/toggle-menu" "['<Control><Alt>h']"
# misc extension settings
dconf write "/org/gnome/shell/extensions/dash-to-panel/dot-size" "0"
dconf write "/org/gnome/shell/extensions/dash-to-panel/group-apps" "false"
dconf write "/org/gnome/shell/extensions/dash-to-panel/trans-bg-color" "'#3d3846'"
dconf write "/org/gnome/shell/extensions/dash-to-panel/trans-panel-opacity" "1.0"
dconf write "/org/gnome/shell/extensions/dash-to-panel/trans-use-custom-bg" "true"
dconf write "/org/gnome/shell/extensions/dash-to-panel/trans-use-custom-opacity" "false"
dconf write "/org/gnome/shell/extensions/emoji-copy/always-show" "false"
dconf write "/org/gnome/shell/extensions/emoji-copy/emoji-keybind" "['<Ctrl><Alt>period']"
dconf write "/org/gnome/shell/extensions/switcher/fade-enable" "true"
dconf write "/org/gnome/shell/extensions/switcher/font-size" "uint32 24"
dconf write "/org/gnome/shell/extensions/switcher/max-width-percentage" "uint32 50"
# enable window buttons
gsettings set org.gnome.desktop.wm.preferences button-layout ':minimize,maximize,close'
}
set_default_shell_to_zsh() {
local zsh_path
zsh_path="$(command -v zsh)"
if [[ "${SHELL:-}" == "$zsh_path" ]]; then
return
fi
log "Changing default shell to zsh for user '$USER'..."
chsh -s "$zsh_path"
log "Default shell updated. Re-login required."
}
main() {
set -e
if [ -z "$(get_state)" ]; then
set_state "1"
fi
require_fedora
sudo -v
if [ "$(get_state)" = "1" ]; then
install_packages
set_state "2"
fi
if [ "$(get_state)" = "2" ]; then
set_default_shell_to_zsh
set_state "3"
exit 0
fi
# we should be in zsh here
if [[ "${SHELL:-}" != "$(command -v zsh)" ]]; then
echo "Error: This script must be run with zsh" >&2
echo "Perhaps you need to do a re-login?"
exit 1
fi
setup_vscode
# TODO: finish
install_nvm
install_deno
setup_flatpak
install_gnome_extensions
configure_gnome
log "Done. Reboot/re-login is recommended."
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment