- Dockerfile 58.9%
- Shell 41.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| pkg-lists | ||
| rootfs-overlay/usr/local/bin | ||
| Containerfile | ||
| README.md | ||
🦭 walrus-arch
Bleeding-Edge, Immutable, Container-Delivered Arch Linux Distribution > Powered by Forgejo Actions, Podman / Buildah, Hyprland, and an All-AMD Hardware Engine.
📌 System Architecture & Vision
walrus-arch is an atomic, image-based Arch Linux operating system. Instead of performing traditional package upgrades directly on the host (pacman -Syu), the entire operating system root filesystem is built daily in an OCI container image via Forgejo CI/CD.
+-------------------------------------------------+ | Forgejo CI/CD Pipeline | | (Daily Buildah run on Arch Linux base image) | +-----------------------+-------------------------+ | v +-------------------------------------------------+ | Forgejo OCI Container Registry | | forgejo.example.com/frederikl/walrus-arch| +-----------------------+-------------------------+ | v (podman pull & export) +-------------------------------------------------+ | Physical AMD Host | | Unpacks to new BTRFS subvolume -> Reboots root | +-------------------------------------------------+
Key Pillars:
- Atomic OS Delivery: Updates are pulled as complete rootfs OCI containers and unpacked into atomic BTRFS subvolumes.
- Zero Host Drift: The core system remains identical to the committed
Containerfiledefinition. - Bleeding-Edge: Nightly Forgejo workflow rebuilds the image pulling upstream Arch Linux updates.
- Hardware Target: Tailored for AMD CPU (
amd-ucode) and AMD GPU (mesa,vulkan-radeon). - Desktop Environment: Wayland-native Hyprland compositor stack with PipeWire audio.
- Stateful Isolation: User data (
/home), Flatpaks, and Distrobox containers reside on independent BTRFS subvolumes, persisting across system updates.
📁 Repository Layout
walrus-arch/
├── README.md # This architecture and AI guidance document
├── Containerfile # Complete OS root blueprint
├── .forgejo/
│ └── workflows/
│ └── build-os.yml # Automated CI/CD pipeline
├── pkg-lists/
│ ├── native.txt # Official repository packages
│ └── aur.txt # AUR packages to compile/install
└── rootfs-overlay/ # Files overlayed directly onto OS root
├── etc/
│ ├── fstab # CIFS mounts & local partition table
│ └── systemd/system/ # Custom systemd services
└── usr/
└── local/bin/
└── os-update.sh # Host deployment script
🐳 1. The Container Blueprint (Containerfile)
Save this file as Containerfile in the repository root:
# ==============================================================================
# STAGE 1: AUR & Binary Build Layer
# ==============================================================================
FROM archlinux:latest AS builder
RUN pacman -Syu --noconfirm && \
pacman -S --noconfirm base base-devel git sudo wget
# Dedicated non-root user for building AUR packages
RUN useradd -m -G wheel -s /bin/bash builduser && \
echo "builduser ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
USER builduser
WORKDIR /home/builduser
# Install AUR Helper (yay)
RUN git clone [https://aur.archlinux.org/yay.git](https://aur.archlinux.org/yay.git) /tmp/yay && \
cd /tmp/yay && \
makepkg -si --noconfirm && \
rm -rf /tmp/yay
# ==============================================================================
# STAGE 2: Final OS Rootfs Base
# ==============================================================================
FROM archlinux:latest
# 1. Base Kernel, AMD Microcode, Drivers, Hyprland & Core Tools
RUN pacman -Syu --noconfirm && \
pacman -S --noconfirm \
# Bootloader, Kernel & Filesystems
linux linux-firmware amd-ucode btrfs-progs systemd systemd-sysvcompat mkinitcpio efibootmgr \
# AMD Graphics & Vulkan Stack
mesa vulkan-radeon lib32-mesa lib32-vulkan-radeon \
# Desktop Environment & Wayland Stack
hyprland waybar rofi kitty wl-clipboard xdg-desktop-portal-hyprland \
# Sound & Networking
pipewire pipewire-pulse pipewire-alsa wireplumber networkmanager cifs-utils \
# Containerization & App Layering
podman flatpak distrobox \
# Essential CLI Utilities
neovim git zsh sudo openssh rsync curl wget fastfetch
# 2. Inject Configuration Overlay
COPY rootfs-overlay/ /
# 3. User Setup (frederikl)
RUN useradd -m -G wheel,video,audio,input -s /bin/zsh frederikl && \
echo "frederikl ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
# Pre-create network mount points
mkdir -p /home/frederikl/Mnt/Libellulanas/home \
/home/frederikl/Mnt/Libellulanas/video \
/home/frederikl/Mnt/Infrastructure && \
chown -R frederikl:frederikl /home/frederikl/Mnt
# 4. System Services Initialization
RUN systemctl enable NetworkManager sshd systemd-networkd systemd-resolved
# 5. Generate Kernel Initramfs
RUN mkinitcpio -P
# 6. Cleanup Package Cache to Compress OCI Image Size
RUN pacman -Scc --noconfirm && \
rm -rf /var/cache/pacman/pkg/* /tmp/* /var/tmp/*
# Target systemd as the primary PID 1 process
CMD ["/sbin/init"]
⚡ 2. Forgejo CI/CD Pipeline (.forgejo/workflows/build-os.yml)
Save this file as .forgejo/workflows/build-os.yml:
name: Build Bleeding-Edge walrus-arch
on:
push:
branches:
- main
paths-ignore:
- '**.md'
schedule:
- cron: '0 4 * * *' # Daily at 04:00 UTC
env:
REGISTRY: forgejo.example.com # Update to your Forgejo domain
IMAGE_NAME: ${{ github.repository_owner }}/walrus-arch
jobs:
build-and-push-os:
runs-on: ubuntu-latest
steps:
- name: 📥 Checkout Code
uses: actions/checkout@v4
- name: 🛠️ Install Buildah & Podman
run: |
sudo apt-get update
sudo apt-get install -y podman buildah
- name: 🏗️ Build Immutable OS Image
run: |
buildah build --pull-always \
-t $REGISTRY/$IMAGE_NAME:latest \
-t $REGISTRY/$IMAGE_NAME:${{ github.sha }} \
-f Containerfile .
- name: 🔑 Registry Authentication
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | podman login $REGISTRY -u${{ github.repository_owner }} --password-stdin
- name: 🚀 Push OS Image to Forgejo Registry
run: |
podman push $REGISTRY/$IMAGE_NAME:latest
podman push $REGISTRY/$IMAGE_NAME:${{ github.sha }}
🛠️ 3. Host System Network Mounts (rootfs-overlay/etc/fstab)
Store this file at rootfs-overlay/etc/fstab. It handles local boot mounts and SMB/CIFS network storage:
# /etc/fstab: Static file system information for walrus-arch
# --- Local Root & Boot Partitions ---
UUID=47E8-6487 /boot vfat fmask=0137,dmask=0027 0 2
UUID=bb13045e-4f26-4097-96b6-175aca29d076 / btrfs subvol=@root,defaults,noatime,compress=zstd 0 1
UUID=096ddfd4-4b1c-4711-80cd-f4a3a194c58a swap swap defaults 0 0
tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0
# --- SMB/CIFS Network Drives ---
//10.11.12.4/home /home/frederikl/Mnt/Libellulanas/home cifs credentials=/root/.smb/libellulanas,uid=1000,gid=1000,iocharset=utf8,vers=3.1.1,soft,serverino,x-systemd.automount,_netdev,nofail,noatime 0 0
//10.11.12.4/video /home/frederikl/Mnt/Libellulanas/video cifs credentials=/root/.smb/libellulanas,uid=1000,gid=1000,iocharset=utf8,vers=3.1.1,soft,serverino,x-systemd.automount,_netdev,nofail,noatime 0 0
//10.11.12.100/Infrastructure /home/frederikl/Mnt/Infrastructure cifs credentials=/root/.smb/infrastructure,uid=1000,gid=1000,iocharset=utf8,vers=3.1.1,soft,serverino,x-systemd.automount,_netdev,nofail,noatime 0 0
🔄 4. Atomic Deployment Script (os-update.sh)
Save this file as rootfs-overlay/usr/local/bin/os-update.sh (ensure execute permissions chmod +x):
#!/bin/bash
# os-update.sh: Pulls latest walrus-arch container and deploys it to a new BTRFS subvolume
set -euo pipefail
REGISTRY="[forgejo.example.com/frederikl/walrus-arch:latest](https://forgejo.example.com/frederikl/walrus-arch:latest)"
MOUNT_POINT="/mnt/walrus-update"
NEW_SUBVOL_NAME="@root_update_$(date +%Y%m%d_%H%M%S)"
TARGET_DEV="/dev/disk/by-uuid/bb13045e-4f26-4097-96b6-175aca29d076"
echo "🚀 Starting atomic update for walrus-arch..."
# 1. Pull latest image from Forgejo Registry
echo "📥 Fetching latest container image from $REGISTRY..."
podman pull "$REGISTRY"
# 2. Prepare BTRFS target space
echo "💽 Creating new BTRFS subvolume: $NEW_SUBVOL_NAME..."
mkdir -p "$MOUNT_POINT"
mount -o subvolid=5 "$TARGET_DEV" "$MOUNT_POINT"
btrfs subvolume create "$MOUNT_POINT/$NEW_SUBVOL_NAME"
# 3. Export container rootfs into the new subvolume
echo "📦 Extracting root filesystem to target subvolume..."
CONTAINER_ID=$(podman create "$REGISTRY")
podman export "$CONTAINER_ID" | tar -x -C "$MOUNT_POINT/$NEW_SUBVOL_NAME"
podman rm "$CONTAINER_ID"
# 4. Copy persistent machine secrets/IDs
if [ -f /etc/machine-id ]; then
cp /etc/machine-id "$MOUNT_POINT/$NEW_SUBVOL_NAME/etc/machine-id"
fi
# 5. Update Bootloader Pointer
echo "⚙️ Re-pointing systemd-boot to target subvolume..."
if [ -f /boot/loader/entries/arch.conf ]; then
sed -i "s/subvol=[^ ]*/subvol=$NEW_SUBVOL_NAME/" /boot/loader/entries/arch.conf
fi
# 6. Unmount and Clean
umount "$MOUNT_POINT"
rmdir "$MOUNT_POINT"
echo "✅ Update staged successfully."
echo "🔄 Reboot to enter the updated walrus-arch environment."
🤖 Context & Instructions for Future AI Assistants
Notice to AI Models editing this repository: > Read this section carefully before making suggestions or modifying any code in this repository.
- System Paradigm:
- This project is NOT a standard docker workspace or application container.
- This project IS a bootable OS image deployment system wrapping an entire Arch Linux OS root into an OCI container for distribution.
- Hardware Constraints:
- Target platform is AMD CPU + AMD GPU.
- Drivers must remain enabled in
Containerfile:amd-ucode,mesa,vulkan-radeon,lib32-vulkan-radeon. - Display server is Hyprland (Wayland). Do not introduce X11 display managers (like SDDM/LightDM) unless explicitly requested.
- Execution Rules:
- Do NOT remove
mkinitcpio -Por the kernel installation (linux) from theContainerfile. They are necessary for bare-metal bootability. - Do NOT execute active block device mounts (
mount /dev/...) inside theContainerfilebuild stage. Buildah runs in a containerized sandbox without hardware privileges. - User application state (browsers, IDE configs, gaming) must be relegated to
/home/frederiklor Flatpaks/Distrobox. Core packages belong inContainerfile.