swf.wtf
Feb 26, 2026 guide arch virtualbox omarchy-style

Arch Linux on VirtualBox, Omarchy-style.
// command by command, no installer UI.

This mirrors the Omarchy ISO installer flow: 2 GiB EFI, LUKS, Btrfs subvolumes, and Limine via archinstall JSON files.

# pacman -Sy --noconfirm archinstall jq openssl
install tools in live ISO
# cat > user_configuration.json <
define Omarchy-style disk + boot + fs layout
# archinstall --config user_configuration.json --creds user_credentials.json
// contents
Before you start VirtualBox settings Boot live ISO and prep Set install variables Build credentials JSON Build archinstall config JSON Run install First boot checks Optional: install Omarchy layer Troubleshooting Sources

Before you start

// wipe warning
If DISK points to the wrong device, your data is gone. Confirm with lsblk every time.

VirtualBox settings


Boot live ISO and prep

live environment
timedatectl set-ntp true
ip link
ping -c 3 archlinux.org
lsblk -d -e 7,11 -o NAME,SIZE,MODEL

pacman -Sy --noconfirm archinstall jq openssl

# If keyring errors appear on an older ISO, reset keyring:
killall gpg-agent
rm -rf /etc/pacman.d/gnupg
pacman-key --init
pacman-key --populate archlinux
pacman -Sy archlinux-keyring

Set install variables

This is the data Omarchy's configurator normally asks for interactively.

replace values first
export DISK="/dev/sda"
export HOSTNAME="archbox"
export USERNAME="steven"
export TIMEZONE="America/New_York"
export KEYBOARD="us"

lsblk "$DISK"

printf "Set install password: "
stty -echo; read PASSWORD; stty echo; echo
PASSWORD_HASH=$(printf '%s' "$PASSWORD" | openssl passwd -6 -stdin)

Build credentials JSON

Omarchy passes plaintext encryption password + hashed login passwords to archinstall.

user_credentials.json
password_escaped=$(echo -n "$PASSWORD" | jq -Rsa)
password_hash_escaped=$(echo -n "$PASSWORD_HASH" | jq -Rsa)
username_escaped=$(echo -n "$USERNAME" | jq -Rsa)

cat > user_credentials.json <
{
  "encryption_password": $password_escaped,
  "root_enc_password": $password_hash_escaped,
  "users": [
    {
      "enc_password": $password_hash_escaped,
      "groups": [],
      "sudo": true,
      "username": $username_escaped
    }
  ]
}
EOF

Build archinstall config JSON

This matches the Omarchy disk layout: 2 GiB EFI + encrypted Btrfs root + subvolumes.

size math from Omarchy configurator
disk_size=$(lsblk -bdno SIZE "$DISK")
mib=$((1024 * 1024))
gib=$((mib * 1024))
disk_size_in_mib=$((disk_size / mib * mib))

gpt_backup_reserve=$mib
boot_partition_start=$mib
boot_partition_size=$((2 * gib))
main_partition_start=$((boot_partition_start + boot_partition_size))
main_partition_size=$((disk_size_in_mib - main_partition_start - gpt_backup_reserve))
user_configuration.json
cat > user_configuration.json <
{
  "archinstall-language": "English",
  "audio_config": { "audio": "pipewire" },
  "bootloader": "Limine",
  "disk_config": {
    "btrfs_options": {
      "snapshot_config": { "type": "Snapper" }
    },
    "config_type": "default_layout",
    "device_modifications": [
      {
        "device": "$DISK",
        "partitions": [
          {
            "flags": ["boot", "esp"],
            "fs_type": "fat32",
            "mountpoint": "/boot",
            "obj_id": "ea21d3f2-82bb-49cc-ab5d-6f81ae94e18d",
            "size": { "unit": "B", "value": $boot_partition_size, "sector_size": { "unit": "B", "value": 512 } },
            "start": { "unit": "B", "value": $boot_partition_start, "sector_size": { "unit": "B", "value": 512 } },
            "status": "create",
            "type": "primary"
          },
          {
            "btrfs": [
              { "mountpoint": "/", "name": "@" },
              { "mountpoint": "/home", "name": "@home" },
              { "mountpoint": "/var/log", "name": "@log" },
              { "mountpoint": "/var/cache/pacman/pkg", "name": "@pkg" }
            ],
            "flags": [],
            "fs_type": "btrfs",
            "mount_options": ["compress=zstd"],
            "mountpoint": null,
            "obj_id": "8c2c2b92-1070-455d-b76a-56263bab24aa",
            "size": { "unit": "B", "value": $main_partition_size, "sector_size": { "unit": "B", "value": 512 } },
            "start": { "unit": "B", "value": $main_partition_start, "sector_size": { "unit": "B", "value": 512 } },
            "status": "create",
            "type": "primary"
          }
        ],
        "wipe": true
      }
    ],
    "disk_encryption": {
      "encryption_type": "luks",
      "iter_time": 2000,
      "lvm_volumes": [],
      "partitions": ["8c2c2b92-1070-455d-b76a-56263bab24aa"],
      "encryption_password": $password_escaped
    }
  },
  "hostname": "$HOSTNAME",
  "kernels": ["linux"],
  "locale_config": {
    "kb_layout": "$KEYBOARD",
    "sys_enc": "UTF-8",
    "sys_lang": "en_US.UTF-8"
  },
  "mirror_config": {
    "custom_repositories": [],
    "custom_servers": [
      { "url": "https://geo.mirror.pkgbuild.com/\$repo/os/\$arch" },
      { "url": "https://mirror.rackspace.com/archlinux/\$repo/os/\$arch" }
    ],
    "mirror_regions": {},
    "optional_repositories": []
  },
  "network_config": { "type": "iso" },
  "ntp": true,
  "packages": ["base-devel", "git", "networkmanager", "snapper", "btrfs-progs"],
  "parallel_downloads": 8,
  "services": ["NetworkManager"],
  "swap": true,
  "timezone": "$TIMEZONE"
}
EOF

Run install

install
archinstall --config user_configuration.json --creds user_credentials.json

When it finishes, reboot and remove the ISO from the VM optical drive.

reboot
reboot

First boot checks

inside installed system
systemctl status NetworkManager
findmnt -n -o FSTYPE /
sudo btrfs subvolume list /
lsblk -f

If limine-update exists, run it once after first full update:

boot entries refresh
sudo pacman -Syu --noconfirm
command -v limine-update && sudo limine-update

Optional: install Omarchy layer

If you want full Omarchy after base Arch is up, run the official boot script:

optional
curl -fsSL https://raw.githubusercontent.com/basecamp/omarchy/master/boot.sh | bash
// note
This guide gives you the Omarchy installer disk/encryption/layout flow first. The optional command above adds the full Omarchy environment on top.

Troubleshooting


Sources