It always seems impossible until its done, Theodor Seuss Geisel

Welcome back to the Arch Linux Post-Installation series. In this chapter, we move from the basic shell environment to setting up a powerful graphical workspace and network connectivity.
First, we automate the deployment of Alacritty, a modern, GPU-accelerated terminal emulator, and Neovim, a highly extensible editor. We will install necessary dependencies like FiraCode Nerd Fonts and Python/Node providers, and utilize lazy.nvim to bootstrap our plugin configuration automatically.
Next, we establish a local area network (LAN) file server using Samba. We will automate the creation of a secure, public share accessible from Windows, macOS, and Linux. Finally, we will demonstrate how to connect to this share from a NixOS client using cifs-utils and systemd automount, ensuring a seamless cross-platform workflow.
#!/usr/bin/env bash
# ── 13-alacritty-nvim.sh ──────────────────────────────────────────────────────
# Install and configure Alacritty terminal, Neovim, and essential dependencies.
#
# What it installs:
# - Alacritty (GPU‑accelerated terminal)
# - FiraCode Nerd Font (iconic font for Alacritty/Neovim)
# - Neovim (modern Vim fork)
# - pynvim (Python host for Neovim)
# - neovim npm package (for Node‑based plugins)
# - Common Neovim dependencies: ripgrep, fd, lazygit, tree-sitter-cli
# - Symlinks Alacritty and Neovim configs from ~/dotfiles/myArch/config/
# Run: bash 13-alacritty-nvim.sh
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail
DOTFILES="$HOME/dotfiles"
_link() {
local src="$1" tgt="$2"
[[ ! -e "$src" ]] && { echo " ⚠️ Source not found: $src"; return; }
mkdir -p "$(dirname "$tgt")"
[[ -e "$tgt" || -L "$tgt" ]] && mv "$tgt" "${tgt}.bak" && echo " 📦 Backed up: $tgt"
ln -s "$src" "$tgt"
echo " 🔗 $tgt → $src"
}
# ── Alacritty ─────────────────────────────────────────────────────────────────
echo "── Installing Alacritty..."
sudo pacman -S --needed --noconfirm alacritty
# Install FiraCode Nerd Font (it is used in alacritty.toml)
echo "── Installing FiraCode Nerd Font ──"
sudo pacman -S --needed --noconfirm ttf-firacode-nerd ttf-nerd-fonts-symbols
echo "── Linking Alacritty config..."
_link "$DOTFILES/myArch/config/alacritty/alacritty.toml" "$HOME/.config/alacritty/alacritty.toml"
echo " ✅ Alacritty $(alacritty --version)"
# ── Neovim ────────────────────────────────────────────────────────────────────
echo "── Installing Neovim & Core Dependencies ──"
sudo pacman -S --needed --noconfirm neovim ripgrep fd
# pynvim: Python host for Neovim — required for Python-based plugins.
# Installed into the user's pip (not a venv) so Neovim can always find it.
echo "── Installing pynvim (Python host for Neovim)..."
pip install --user --break-system-packages pynvim
# Also install neovim npm package for Node-based plugins (e.g. copilot)
if command -v npm &>/dev/null; then
npm install -g neovim 2>/dev/null || true
fi
echo "── Linking Neovim config..."
_link "$DOTFILES/myArch/config/nvim" "$HOME/.config/nvim"
# Attempt to install plugins via lazy.nvim (headless)
echo "── Installing Neovim plugins (headless, first run only)..."
nvim --headless "+Lazy! sync" +qa 2>/dev/null && echo " ✅ Plugins installed" \
|| echo " ⚠️ Plugin Installation Failed. Open nvim and run :Lazy sync manually"
echo
echo "✅ 13-alacritty-nvim: done"
echo " Next: bash 14-samba.sh"
#!/usr/bin/env bash
# ── 14-samba.sh ───────────────────────────────────────────────────────────────
# Install and configure Samba — SMB/CIFS file sharing for Windows/macOS/Linux.
#
# Run: bash 14-samba.sh
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail
# Configuration – change these variables to suit your environment
USERNAME="${SUDO_USER:-$(whoami)}"
SHARE_PATH="/mnt/data/share"
SHARE_NAME="datashare"
echo "── 14-samba: installing and configuring Samba..."
# ── Install ───────────────────────────────────────────────────────────────────
# Install samba and utilities
# inetutils provides the `hostname` command — not installed by default on Arch.
sudo pacman -S --needed --noconfirm samba inetutils
# ── Create the shared directory ───────────────────────────────────────────────
echo "── Creating shared directory: $SHARE_PATH"
sudo mkdir -p "$SHARE_PATH"
# Ensure correct ownership and permissions
sudo chown "${USERNAME}:${USERNAME}" "$SHARE_PATH"
sudo chmod 775 "$SHARE_PATH"
echo " ✅ $SHARE_PATH created with permissions 775"
# ── Resolve IP ──────────────
MACHINE_NAME=$(cat /etc/hostname 2>/dev/null || echo "archlinux")
# ip route get 1 asks the kernel "which interface, gateway, and source IP would I use to send a packet to 1.0.0.0?
# Example output: 1.0.0.0 via 192.168.1.1 dev enp42s0 src 192.168.1.46 uid 1000
# dev enp42s0 → the interface the kernel would use
# src 192.168.1.46 → the local IP the kernel would choose for that route. In other words, the main LAN IP
# Because 1.0.0.0 is guaranteed to be routed via your default gateway.
# So this trick reliably returns your primary LAN IP, even on multi‑interface systems.
# awk '/src/ {print $7; exit}' → extract the src field
LOCAL_IP=$(ip route get 1 2>/dev/null | awk '/src/ {print $7; exit}' || echo "127.0.0.1")
# ── Write smb.conf ────────────────────────────────────────────────────────────
# Variables ARE expanded inside the heredoc (no single-quotes around SMBCONF).
# We use the already-resolved $MACHINE_NAME so the heredoc doesn't need `hostname`.
echo "── Writing /etc/samba/smb.conf..."
sudo tee /etc/samba/smb.conf > /dev/null << SMBCONF
# ── /etc/samba/smb.conf ───────────────────────────────────────────────────────
# Samba configuration for a simple home/office LAN share.
# After editing: sudo testparm && sudo systemctl restart smb
# ─────────────────────────────────────────────────────────────────────────────
[global]
server string = ${MACHINE_NAME} Samba Server
# Disable SMB1 (insecure, XP-era only). SMB2/3 required.
server min protocol = SMB2
server max protocol = SMB3
log level = 1
log file = /var/log/samba/log.%m
max log size = 1000
# Map unknown Unix users to the guest account (required for guest ok = yes)
map to guest = bad user
passdb backend = tdbsam
wins support = yes
dns proxy = no
[${SHARE_NAME}]
comment = Data share on ${MACHINE_NAME}
path = ${SHARE_PATH}
# Map all connecting clients to this Unix user for consistent file ownership
force user = ${USERNAME}
browseable = yes
writable = yes
read only = no
# Public share: no password required from LAN clients
# If you want to be more restrictive: set guest ok = no and add users with smbpasswd -a
public = yes
guest ok = yes
create mask = 0664
directory mask = 0775
SMBCONF
echo " ✅ /etc/samba/smb.conf written"
# ── Validate config syntax ────────────────────────────────────────────────────
# testparm output goes to stderr; we capture both streams.
# "Loaded services file OK" always appears on a valid config.
# The "Weak crypto is allowed by GnuTLS" line is a harmless notice, not an error.
echo "── Validating smb.conf..."
TESTPARM_OUT=$(sudo testparm -s 2>&1)
if echo "$TESTPARM_OUT" | grep -q "Loaded services file OK"; then
echo " ✅ smb.conf syntax OK"
else
echo "$TESTPARM_OUT"
echo " ❌ smb.conf has syntax errors — fix before continuing"
exit 1
fi
# ── Set Samba password (if not guest‑only) ────────────────────────────────────────────────────────
echo "── Setting Samba password for $USERNAME"
echo " (prompted below — press Ctrl+C to skip for guest-only access)"
sudo smbpasswd -a "$USERNAME" || echo " ⚠️ Samba password not set — guest access still works"
# ── Enable and start services ─────────────────────────────────────────────────
sudo systemctl enable --now smb nmb
echo " ✅ smb and nmb enabled and started"
# ── Firewall ──────────────────────────────────────────────────────────────────
if command -v ufw &>/dev/null; then
sudo ufw allow from 192.168.1.0/24 to any app Samba
echo " ✅ ufw: Samba allowed from 192.168.1.0/24"
fi
# ── Verify ────────────────────────────────────────────────────────────────────
echo
echo "── Share status:"
sudo systemctl status smb --no-pager | head -6
echo
echo "── Accessible shares:"
smbclient -L localhost -N 2>/dev/null | grep -A10 "Sharename" || true
echo
echo "── Access from Windows:"
echo " Open Explorer → \\\\${LOCAL_IP}\\${SHARE_NAME}"
echo "── Access from macOS:"
echo " Finder → Go → Connect to Server → smb://${LOCAL_IP}/${SHARE_NAME}"
echo "── Access from Linux:"
echo " Files app → Other locations → smb://${LOCAL_IP}/${SHARE_NAME}"
echo " Or CLI: smbclient //${LOCAL_IP}/${SHARE_NAME} -N"
echo
echo "✅ 14-samba: done"
echo " Next: bash 15-nfs.sh"
This configuration integrates your NixOS client seamlessly with the Samba server you set up earlier.
# Ensures the kernel includes support for CIFS (Common Internet File System), the protocol used by Samba.
boot.supportedFilesystems = [ "cifs" ];
# Install CIFS Utilities (mount.cifs, smbclient, and smbumount)
environment.systemPackages = [ pkgs.cifs-utils ];
# Mount Point Definition. This declares a mount point at /home/nmaximo7/samba.
fileSystems."/home/nmaximo7/samba" = {
# The Samba share location on the network: IP address of the Samba server + the share name defined in your server’s smb.conf
device = "//192.168.1.46/datashare";
# Filesystem Type
fsType = "cifs";
# Mount Options
options = [
"x-systemd.automount" # Instructs systemd to mount the share on‑demand (lazy mounting).
"_netdev" # The system waits for network connectivity before attempting to mount it.
"username=nmaximo7" # Samba username on the server.
"password=yourPassword" # The plain‑text password for that user. Warning: Storing passwords in the configuration is not secure.
"uid=1000" # Maps all files on the share to local user ID 1000 (typically the primary user). This ensures you own the files locally.
"gid=100" # Maps files to group ID 100 (often the users group on NixOS).
"dir_mode=0775" # Sets permissions for directories on the mount to drwxrwxr-x (owner and group read/write/execute, others read/execute).
"file_mode=0664" # Sets permissions for files on the mount to -rw-rw-r-- (owner and group read/write, others read).
"vers=3.0" # Forces the use of SMB protocol version 3.0. This is more secure and feature‑rich than older versions.
"noserverino"
];
};