A Speed Run Installation of Arch Linux
I switched back to Arch Linux after a rocky, year long relationship with Ubuntu. The switch took longer than I thought it would. As usual, I forgot to multiply my initial estimate by three. To prevent such regressions in the future, I will document the rouch sketch of commands to get a minimal i3 system going.
Buyer beware, you should really follow the Arch installation guide and maybe steal a few tips from this. Doing it the other way around leads to ruin. Here are the specifics of my setup which may not apply to you:
- I need WiFi to work for 1-2 networks.
- I prefer wired ethernet if available.
- I boot into i3 via
startx
. I don’t want a desktop environment like Gnome, Unity or KDE. - Faster is always better. I will add complexity for speed.
- I will use EFI to boot Linux directly.
Initial Setup to Chroot
This is the initial setup from starting the Live USB to mounting the new system.
# Verify that EFI is enabled. ls /sys/firmware/efi/efivars # Do we have internet? ping www.google.com # Ensure system clock is accurate. timedatectl set-ntp true # Partition disks. cgdisk /dev/nvme0n1 # Create EFI partition of 512M with code EF00. # Create Linux partition of the rest with code 8300. # Swap, meh. # Format partitions. mkfs.fat -F32 /dev/nvme0n1p1 mkfs.ext4 /dev/nvme0n1p2 # Mount the file systems. mkdir -p /mnt/boot mount /dev/nvme0n1p2 /mnt mount /dev/nvme0n1p1 /mnt/boot # Rank Pacman mirrors before downloading the base packages. cp /mnt/etc/pacman.d/mirrorlist{,.bak} rankmirrors -n 6 /mnt/etc/pacman.d/mirrorlist.bak > /mnt/etc/pacman.d/mirrorlist # Install base packages and a passable editor. pacstrap /mnt base vim sudo genfstab -U /mnt >> /mnt/etc/fstab arch-chroot /mnt
Setup Base System
Now that we’re in our new system, get a minimal configuration going.
ln -sf /usr/share/zoneinfo/America/Los_Angeles /etc/localtime hwclock --systohc # Uncomment en_US.UTF-8 UTF-8. vim /etc/locale.gen locale-gen echo 'LANG=en_US.UTF-8' >> /etc/locale.conf echo 'home.d46.us' > /etc/hostname # Setup EFISTUB for UEFI to load Linux directly without a bootloader like grub. # Save this in a file for easy editing later. echo 'efibootmgr -d /dev/nvme0n1 -p 1 -c -L "Arch Linux" \ -l /vmlinuz-linux \ -u "root=/dev/nvme0n1p2 rw initrd=/initramfs-linux.img"' \ > /etc/make-efi.sh sh /etc/make-efi.sh # Verify EFI setup, make sure root drive is root partition and you spelled # everything correctly. efibootmgr # Set root password passwd dhcpcd visudo # Uncomment "%wheel ALL=(ALL) ALL" line # Uncomment the wheel NOPASSWD line # Make myself. useradd -m -g users -G audio,lp,optical,storage,video,wheel,power joe passwd joe # Login as joe su - joe
Install Important Packages and an AUR helper.
A few important packages.
pacman -S base-devel xorg # pick all pacman -S nvidia nvidia-libgl # pick the nvidia-340-xx pacman -S git open-ssh tree zsh # pick all
It’s not really an Arch installation until you have an AUR helper. The standard disclaimer about the evils of using AUR helpers applies to this case.
# Create a directory. AUR_DIR="~/.config/aur" mkdir -p $AUR_DIR # Cower is up first, because pacaur depends on it. git clone https://aur.archlinux.org/cower.git "$AUR_DIR/cower" cd $AUR_DIR/cower makepkg -si # If permission errors try this command: # gpg --recv-keys --keyserver hkp://pgp.mit.edu 1EB2638FF56C0C53 # Now, pacaur. git clone https://aur.archlinux.org/pacaur.git "$AUR_DIR/pacaur" cd $AUR_DIR/pacaur makepkg -si # You know what's better than i3, I3-WITH-GAPS pacaur -S i3-gaps-next-git rcm google-chrome cd
Setup Dotfiles
This would be so much easier if my dotfiles were public. Getting authentication working is a huge pain. One day I’ll scrape out the non-public stuff and publish my dotfiles again.
ssh-keygen GH_PASSWORD='MY_PASSWORD' # Use the OTP code from Google authenticator on the phone # Can't use single quotes because we're getting the public key in our data. curl -i -u "jschaf:$GH_PASSWORD" --header "X-GitHub-OTP: 123456" \ --data "{\"title\": \"Home Desktop\", \"key\": \"$(< ~/.ssh/id_rsa.pub)\"}"\ https://api.github.com/user/keys # Use git protocol to force SSH instead of HTTPS and avoid having to # reauthenticate. git clone git@github.com:jschaf/dotfiles.git ~/.dotfiles cd ~/.dotfiles git submodule update --init # Init dotfiles. cd ~ # Setup RCM config file before we invoke rcup so it knows which folders and # files to link. Otherwise it ignores the config. ln -s ~/.dotfiles/rcrc ~/.rcrc # Make it verbose so we know what it did and include our linux stuff. rcup -t linux -v # Verify .dotfiles look good. ls -al
Setup Auto Login to TTY1
Why waste precious seconds logging in, when systemd will do it for you?
WARNING: This is giant gaping security hole, but super convenient.
# Auto login to TTY1. # https://wiki.archlinux.org/index.php/Getty#Automatic_login_to_virtual_console echo "[Service] Type=Simple ExecStart= ExecStart=-/usr/bin/agetty --autologin $USER --noclear %I \$TERM" \ > /etc/systemd/system/getty@tty1.service.d/override.conf
Setup Networking
This networking setup will enable WiFi and wired with a preference for wired.
pacman -S wpa_supplicant systemctl start systemd-networkd.service systemctl enable systemd-networkd.service systemctl start systemd-resolved.service systemctl enable systemd-resolved.service rm /etc/resolv.conf ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf systemctl enable wpa_supplicant@wlp2s0.service
[Match] Name=enp1s0 [Network] DHCP=ipv4 [DHCP] RouteMetric=10
[Match] Name=wlp2s0 [Network] DHCP=ipv4 [DHCP] RouteMetric=20
# Run this command. # wpa_passphrase MYSSID passphrase > /etc/wpa_supplicant/wpa_supplicant-wlp2s0.conf ctrl_interface=/var/run/wpa_supplicant ctrl_interface_group=wheel update_config=1 fast_reauth=1 ap_scan=1 network={ ssid="MYSSID" # psk="passphrase" psk=HASHED_PASSWORD }
Bonus Steps
Useful Packages
sudo pacman -S xdg-utils xclip feh python pacaur -S ripgrep # Needed for Chrome u2f (Yubikey) to work. sudo pacman -S libu2f-host # Custom init functions. init-fonts init-tmux-plugin-manager init-wallpapers
Printing
# To enable printing from gtk apps and to enable finding printers on the # network. sudo pacman -S cups gtk3-print-backends avahi nss-mdns systemctl enable avahi-daemon.service systemctl start avahi-daemon.service systemctl enable org.cups.cupsd.service cups-browsed.service systemctl start org.cups.cupsd.service cups-browsed.service
# <snip. # Add `mdns_minimal [NOTFOUND=return]` before resolve. hosts: files mymachines mdns_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns myhostname # <snip>
# Add lp to allow users in lp group to administrate printers. # Probably not a good idea if you have a big network. SystemGroup sys root lp
Then visit http://localhost:631/ and “Add Printer”. Use your root username and password.
Improve TTY or Virtual Console.
The default color scheme for the virtual console is not pleasing on the eyes. Here’s how we fix that.
pacman -S terminus-fonts pacaur -S mkinitcpio-colors-git setcolors-git
KEYMAP=us # From terminus-fonts repository. Fonts at /usr/share/kbd/consolefonts # README for font name info: https://files.ax86.net/terminus-ttf/README.Terminus.txt # ter: Terminus # 1: Codepages ISO8859-1, ISO8859-15, Windows-1252 # 22: Font size # n: normal FONT=ter-122n FONT_MAP=8859-1 # Font Colors - Read by mkinitcpio colors hook which writes it to the initramfs # /consoloecolors to be loaded by setcolors. # mkinitcpio-colors: https://github.com/EvanPurkhiser/mkinitcpio-colors # setcolors: https://github.com/EvanPurkhiser/linux-vt-setcolors # Arch Forum: https://bbs.archlinux.org/viewtopic.php?pid=1313384 COLOR_0=171717 # black COLOR_8=2B2B2B # darkgrey COLOR_1=D75F5F # darkred COLOR_9=E33636 # red COLOR_2=87AF5F # darkgreen COLOR_10=98E34D # green COLOR_3=D7AF87 # brown COLOR_11=FFD75F # yellow COLOR_4=8787AF # darkblue COLOR_12=7373C9 # blue COLOR_5=BD53A5 # darkmagenta COLOR_13=D633B2 # magenta COLOR_6=5FAFAF # darkcyan COLOR_14=44C9C9 # cyan COLOR_7=C9C9C9 # lightgrey COLOR_15=CCCCCC # white
Docker
sudo pacman -S docker pacaur -S google-cloud-sdk sudo tee /etc/modules-load.d/loop.conf <<< "loop" systemctl enable docker.service systemctl start docker.service # WARNING: docker group is root equivalent. But sooo handy. sudo gpasswd -a "$USER" docker # Yes, really restart. sudo shutdown -r now # Verify that it worked. docker info