Contents
Preliminaries
-
This guide is mainly intended for myself in case I ever need to rebuild the server, but I'm making it public in case it's useful to others.
-
I've provided the exact IP addresses and usernames for my server; if you're following along, you'll want to replace these with the appropriate values for your own server.
-
Commands that start with
$
are ran as themax
user on the server, while commands that start with%
are ran as some other user. -
This guide was tested with Fedora IoT 40.
Pre-installation
-
Download the Fedora IoT
.iso
installer. In the unlikely scenario that your hosting provider offers Fedora IoT images, you can skip until step 4. -
Upload and attach the
.iso
installer to the virtual machine. -
Configure the VM for UEFI boot.
-
Set the following DNS records:
The
CAA
records make sure that only Let's Encrypt and ZeroSSL can issue certificates for the domain, and theHTTPS
records can sometimes speed up the initial connection times.Type Hostname Value A
— 152.53.36.213
AAAA
— 2a0a:4cc0:2000:172::1
HTTPS
— 1 . alpn="h3,h2" ipv4hint="152.53.36.213" ipv6hint="2a0a:4cc0:2000:172::1"
CNAME
www
maxchernoff.ca.
CNAME
overleaf
maxchernoff.ca.
CNAME
woodpecker
maxchernoff.ca.
CAA
— 0 issue "letsencrypt.org"
CAA
— 0 issue "sectigo.com"
CAA
— 0 issuewild ";"
Installation
-
Start the installer.
-
Disable the
root
account and create an administratormax
. -
Partition as follows:
Index Mount Point Size Type 1 /boot/efi
500M EFI 2 /boot
4G ext4 3 [SWAP]
8G swap 4 /
remaining btrfs 4.1 /home/
— subvol -
Install the system.
-
Reboot into the installed system.
-
Install your SSH key:
% ssh-copy-id max@maxchernoff.ca # From your local machine
-
Log in to the server:
% ssh max@maxchernoff.ca
-
Enable IPv6:
$ sudo nmcli connection modify ens3 ipv6.method manual ipv6.addresses 2a0a:4cc0:2000:172::1/64 ipv6.gateway fe80::1 $ sudo nmcli connection up ens3
-
Reboot.
$ sudo systemctl reboot
Post-installation
-
Install the needed packages:
$ sudo rpm-ostree install borgbackup btrfs-progs fail2ban fish git goaccess htop snapper stow vim
-
Switch shell to
fish
:$ chsh -s /usr/bin/fish
-
Fix
/etc/fstab
:Change the options for
/
todefaults,compress=zstd:1
. -
Fix
/etc/passwd
: If not done,podman
will complain about a mismatched home location.Change the home for
max
to/var/home/max
. -
Adjust your home directory permissions: Needed for the unprivileged containers to access the Git files.
$ chmod -R g-rX,o-rX ~ $ chmod a+X ~
Installing TeX Live
-
Create the
tex
user:$ sudo useradd --create-home --shell /usr/sbin/nologin tex $ sudo loginctl enable-linger tex
-
Switch to the
tex
user:$ sudo -u tex fish
-
Create the necessary directories:
% mkdir -p ~/texlive # As the `tex` user
-
Download the installer:
% cd $(mktemp -d) % curl -O 'https://ftp.math.utah.edu/pub/ctan/tex-archive/systems/texlive/tlnet/install-tl-unx.tar.gz' % tar xf install-tl-unx.tar.gz
-
Install TeX Live:
% ./install-tl-*/install-tl \ > --repository=https://ftp.math.utah.edu/pub/ctan/tex-archive/systems/texlive/tlnet \ > --texdir=/var/home/tex/texlive --scheme=full --paper=letter
-
Set the Unix permissions:
% chmod -R g-rX,o-rX ~ % chmod a+X ~ % chmod -R a+rX ~/texlive
-
Add the SELinux rules: Needed for the containers to be able to access the TeX Live installation.
$ sudo semanage fcontext --add -t container_ro_file_t '/var/home/tex/texlive(/.*)?' $ sudo restorecon -R /var/home/tex/texlive
Web Server
-
Generate a new SSH key:
$ ssh-keygen -t ed25519
-
Add this new key as a single-repo deploy key on GitHub.
-
Clone the repository:
$ git clone git@github.com:gucci-on-fleek/maxchernoff.ca.git
-
Set the Unix permissions:
$ chmod -R a+rX /var/home/max/maxchernoff.ca/web $ chmod -R a=,u=rwX /var/home/max/maxchernoff.ca/.git
-
Create the
web
user:$ sudo useradd --create-home --shell /usr/sbin/nologin web
-
Allow the
web
user to run services:$ sudo loginctl enable-linger web
-
Switch to the
web
user:$ sudo -u web fish
-
Set the Unix permissions:
% chmod -R g-rX,o-rX ~ # As the `web` user % chmod a+X ~
-
Enable the analytics processor:
$ sudo touch ~web/caddy/access.log $ sudo chown $uid:web ~web/caddy/access.log $ sudo chmod a=,ug=rw ~web/caddy/access.log $ touch ~/maxchernoff.ca/web/caddy/static/analytics/{graphs,requests.tsv} $ chmod -R a=rX,ug=rwX ~/maxchernoff.ca/web/caddy/static/analytics $ chmod g+s ~/maxchernoff.ca/web/caddy/static/analytics $ sudo chgrp -R web ~/maxchernoff.ca/web/caddy/static/analytics
-
Start the services:
$ sudo systemctl --user -M web@ start overleaf-pod.service caddy.service
-
Reboot to make sure everything starts correctly.
Woodpecker CI
-
Switch to the
web
user:$ sudo -u web fish
-
Add the Woodpecker server Podman secrets:
% cat | tr -d '\n' | \ # Paste the secret, Enter, Ctrl+D > podman secret create woodpecker_github_secret - % head --bytes=36 /dev/urandom | basenc --z85 | tr -d '\n' | \ > tee /dev/stderr | \ # Copy this value for later > podman secret create woodpecker_agent_secret -
-
Create the
woodpecker
user:$ sudo useradd --create-home --shell /usr/sbin/nologin woodpecker $ sudo loginctl enable-linger woodpecker
-
Switch to the
woodpecker
user:$ sudo -u woodpecker fish
-
Set the Unix permissions:
% chmod -R g-rX,o-rX ~ # As the `woodpecker` user % chmod a+X ~
-
Add the Woodpecker agent Podman secrets:
% cat | tr -d '\n' | \ # Paste the secret, Enter, Ctrl+D > podman secret create woodpecker_agent_secret -
-
Start the services:
$ sudo systemctl --user -M web@ daemon-reload $ sudo systemctl --user -M web@ start woodpecker-server.service $ sudo systemctl --user -M woodpecker@ daemon-reload $ sudo systemctl --user -M woodpecker@ start woodpecker-agent.service
Snapshots
-
Mount the snapshot directory:
# /etc/fstab # This line was here originally UUID={uuid} /home/ btrfs subvol={subvol},compress=zstd:1 0 0 # Add this line UUID={uuid} /home/.snapshots btrfs subvol={subvol}/.snapshots,compress=zstd:1 0 0
$ sudo systemctl daemon-reload $ sudo mount -av