My uCore home server setup
So I don’t forget how to do this in the future, I am putting it in this guide. I do want to switch to quadlets instead of podman-compose systemd.
My butane setup for uCore
ucore-autorebase.butane
#Redacted password hash for security
variant: fcos
version: 1.5.0
passwd:
users:
- name: core
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFWZwOOpn6R4YUVemenq+HMrFHYKgwmJr5aLyUviyCwk
password_hash: **redacted**
boot_device:
mirror:
devices:
- /dev/sda
- /dev/sdb
storage:
disks:
- device: /dev/sda
partitions:
- label: root-1
size_mib: 10240
- label: var-1
- device: /dev/sdb
partitions:
- label: root-2
size_mib: 10240
- label: var-2
raid:
- name: md-var
level: raid1
devices:
- /dev/disk/by-partlabel/var-1
- /dev/disk/by-partlabel/var-2
filesystems:
- device: /dev/md/md-var
path: /var
format: btrfs
wipe_filesystem: true
with_mount_unit: true
directories:
- path: /etc/ucore-autorebase
mode: 0754
- path: /var/home/core/.config/systemd/user/sockets.target.wants
user:
name: core
group:
name: core
links:
- path: /var/home/core/.config/systemd/user/sockets.target.wants/podman.socket
user:
name: core
group:
name: core
target: /usr/lib/systemd/user/podman.socket
files:
- path: /etc/sysctl.d/net.conf
contents:
inline: net.ipv4.ip_unprivileged_port_start=53
- path: /etc/systemd/user/[email protected]
contents:
source: http://workstation/[email protected]
verification:
hash: sha256-f9d86c2f64c71315728640e7721c62fb3457ad685177e140912f293f13899c88
- path: /etc/modules-load.d/zfs.conf
contents:
inline: zfs
systemd:
units:
- name: ucore-unsigned-autorebase.service
enabled: true
contents: |
[Unit]
Description=uCore autorebase to unsigned OCI and reboot
ConditionPathExists=!/etc/ucore-autorebase/unverified
ConditionPathExists=!/etc/ucore-autorebase/signed
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
StandardOutput=journal+console
ExecStart=/usr/bin/rpm-ostree rebase --bypass-driver ostree-unverified-registry:ghcr.io/ublue-os/ucore-hci:stable-zfs
ExecStart=/usr/bin/touch /etc/ucore-autorebase/unverified
ExecStart=/usr/bin/systemctl disable ucore-unsigned-autorebase.service
ExecStart=/usr/bin/systemctl reboot
[Install]
WantedBy=multi-user.target
- name: ucore-signed-autorebase.service
enabled: true
contents: |
[Unit]
Description=uCore autorebase to signed OCI and reboot
ConditionPathExists=/etc/ucore-autorebase/unverified
ConditionPathExists=!/etc/ucore-autorebase/verified
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
StandardOutput=journal+console
ExecStart=/usr/bin/rpm-ostree rebase --bypass-driver ostree-image-signed:docker://ghcr.io/ublue-os/ucore-hci:stable-zfs
ExecStart=/usr/bin/touch /etc/ucore-autorebase/signed
ExecStart=/usr/bin/systemctl disable ucore-signed-autorebase.service
ExecStart=/usr/bin/systemctl reboot
[Install]
WantedBy=multi-user.target
- name: post-setup.service
enabled: true
contents: |
[Unit]
Description=uCore install software to overlay and reboot
ConditionPathExists=/etc/ucore-autorebase/unverified
ConditionPathExists=/etc/ucore-autorebase/signed
ConditionPathExists=!/etc/ucore-autorebase/setup
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
StandardOutput=journal+console
ExecStart=/usr/bin/chown core:core -R /var/home/core
ExecStart=/usr/bin/loginctl enable-linger core
ExecStart=/usr/bin/firewall-cmd --permanent --add-service=http --add-service=https --add-service=http3
ExecStart=/usr/bin/rpm-ostree install buildah
ExecStart=/usr/bin/systemctl enable cockpit.service podman.service podman.socket
ExecStart=/usr/bin/touch /etc/ucore-autorebase/setup
ExecStart=/usr/bin/systemctl disable post-setup.service
ExecStart=/usr/bin/systemctl reboot
[Install]
WantedBy=multi-user.target
# /etc/systemd/user/[email protected]
[Unit]
Description=%i rootless pod (podman-compose)
[Service]
Type=simple
EnvironmentFile=%h/.config/containers/compose/projects/%i.env
ExecStartPre=-/usr/bin/podman-compose --in-pod pod_%i up --no-start
ExecStartPre=/usr/bin/podman pod start pod_%i
ExecStart=/usr/bin/podman-compose wait
ExecStop=/usr/bin/podman pod stop pod_%i
ExecStopPost=/usr/bin/podman pod rm pod_%i
[Install]
WantedBy=default.target
Install brew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install bat borgbackup bottom dua-cli dysk fastfetch fd fish fzf ncdu neovim smartmontools tldr tree
Automatic updates
sudo nvim /etc/rpm-ostreed.conf
/etc/rpm-ostreed.conf
#Change to this
# By default, this system has its OS updates managed by
# `zincati.service`. Changes made to this file may
# conflict with the configuation of `zincati.service`.
# See https://github.com/coreos/zincati for additional
# information.
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# For option meanings, see rpm-ostreed.conf(5).
[Daemon]
AutomaticUpdatePolicy=apply
#IdleExitTimeout=60
#LockLayering=false
sudo cp /usr/lib/systemd/system/rpm-ostreed-automitic.timer /etc/systemd/system/rpm-ostreed-automatic.timer
sudo nvim /etc/systemd/system/rpm-ostreed-automatic.timer
/etc/systemd/system/rpm-ostreed-automatic.timer
#Change to this
[Unit]
Description=rpm-ostree Automatic Update Trigger
Documentation=man:rpm-ostree(1) man:rpm-ostreed.conf(5)
ConditionPathExists=/run/ostree-booted
[Timer]
# OnBootSec=1h
# OnUnitInactiveSec=1d
OnCalendar=Sun *-*-* 04:00:00
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now rpm-ostreed-automatic.timer
Configure sshd
sudo nvim /etc/ssh/sshd_config
/etc/ssh/sshd_config
#Change these lines
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
PermitUserEnvironment yes
ZFS Setup
Initialize the disks:
⚠️ If a disk needs to be reset use
sudo wipefs -a --no-act /dev/sdX
, which will preform a dry-run. Remove--no-act
to execute the command.
sudo gdisk /dev/sdc
gdisk>o #Create a new GPT partition table on the disk
gdisk>w #Write new data to the disk and close gdisk
sudo gdisk /dev/sdd
gdisk>o
gdisk>w
To create my 16TB mirror:
sudo zpool create -oashift=12 -Oxattr=sa -Ocompression=zstd -Oatime=off -Orecordsize=64K -m/var/lina lina mirror /dev/sdc /dev/sdd #ahisft=12 (4k sectors), xattr=sa (Sets Linux eXtended ATTRibutes directly in the inodes), atime=off (I don't care when things are opened), recordsize=64K (Default to smaller recordsize for the base dataset in case of VMs)
Using some of the suggestions from ZFS tuning cheat sheet
To create my library dataset:
sudo zfs create -orecordsize=1M lina/library #1M record size for larger files
Snapshot the old library:
sudo zfs snapshot library/shows@migrate
Send and Receive the dataset to dataset:
sudo sh -c 'zfs send -vR library/shows@migrate | zfs recv -d lina/library' #Send the snapshot of library/shows@migrate and create a new dataset of lina/library/shows with all the previous snapshots up to and including @migrate
Backups from other machines
Setting up ssh
Copy the ssh public key for the backup user into ~/.ssh/authorized_keys
.
Create an ssh enviroment file to use brew:
echo 'PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/bin:/var/home/core/.local/bin:/var/home/core/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin' > ~/.ssh/environment
chmod 600 ~/.ssh/environment
TMUX setup on server
~/.tmux.conf
set-option -g default-shell "/home/linuxbrew/.linuxbrew/bin/fish"
set -g mouse on
setw -g mode-keys vi