Recipe: Set up an Arch Linux virtual workstation with VirtualBox on any x86_64 system

/docs/other/developer-workstation/arch-x86_64/virtualbox/

Note

In our experience, VirtualBox on ARM is currently not mature enough yet to be used, so use this recipe for on x86_64 hosts only. It should work on all x86_64 platforms supported by VirtualBox, including Linux, Mac and Windows.

Install VirtualBox

  1. Download and install VirtualBox if you have not done so already.

Note

On some Linux distros, VirtualBox may be available through package repositories, which might make installation and management easier.

Obtain an Arch Linux image

  1. Download an ISO from a mirror listed on https://archlinux.org/download/ (e.g. archlinux-2024.11.01-x86_64.iso)

Run the Arch Linux ISO as the virtual machine to create the development VM with

  1. In VirtualBox, create a new virtual machine:

    • Click “New”.

    • In section “Name and Operating System”:

      • Enter a suitable name, such as “ubosdev”.

      • ISO Image: select the ISO image you downloaded.

      • Type: select “Linux”.

      • Subtype: select “ArchLinux”

      • Version: select “Arch Linux (64 bit)”.

    • In section “Hardware”:

      • A suitable amount of base memory and CPUs, depending on your needs, such as 8192MB and 2 CPUs.

      • Leave “Enable EFI (special OSes only)” unchecked.

    • Section “Hard Disk”:

      • “Create a Virtual Hard Disk Now”…

      • …with a size suitable for your needs, such as 60 GB. This only means the disk may grow up to 60GB, not that it starts out that large.

      • Disk type: “VDI (VirtualBox Disk Image)”

      • Do not check “Pre-allocate Full Size”

    • Click “Finish”

  2. Click “Start” to start the virtual machine, accept the defaults in the boot loader (or just wait) and wait until the boot sequence ends and the root shell appears.

Install Arch on the empty disk and configure it

  1. Update the bootstrap VM and install some packages we need:

    # pacman -Sy
    # pacman -S archlinux-keyring
    # pacman -Su
    # pacman -S btrfs-progs gptfdisk parted dosfstools arch-install-scripts vi
    
  2. Zero out the first bytes on the disk for extra robustness:

    # dd if=/dev/zero of=/dev/sda bs=1M count=8 conv=notrunc
    
  3. Clear the partition table:

    # sgdisk --clear /dev/sda
    
  4. Create the partitions (UEFI, /boot and /) and change them to the right types:

    # sgdisk --new=1::+1M /dev/sda
    # sgdisk --new=2::+512M /dev/sda
    # sgdisk --new=3:: /dev/sda
    # sgdisk --typecode=1:EF02 /dev/sda
    # sgdisk --typecode=2:EF00 /dev/sda
    
  5. Make sure changes are in effect:

    # sync
    # partprobe /dev/sda
    
  6. Create filesystems for partitions other than the UEFI partition:

    # mkfs.vfat  /dev/sda2
    # mkfs.btrfs /dev/sda3
    
  7. Mount the partitions so we can install:

    # mount /dev/sda3 /mnt
    # mkdir /mnt/boot
    # mount /dev/sda2 /mnt/boot
    
  8. Perform the actual install of the base packages:

    # pacstrap /mnt base
    
  9. Generate the right fstab:

    # genfstab -U -p /mnt >> /mnt/etc/fstab
    
  10. Chroot into your future root disk and continue the installation:

    # arch-chroot /mnt
    
    1. Install more packages:

      # pacman -Sy
      # pacman -S linux grub mkinitcpio sudo vim btrfs-progs virtualbox-guest-utils \
        gdm gnome-console gnome-control-center gnome-session gnome-settings-daemon \
        gnome-shell gnome-keyring nautilus
      

      If asked which alternatives to install, choose the defaults.

    2. Check that the auto-generated content of /etc/pacman.d/mirrorlist makes sense. Edit accordingly.

    3. Create a ramdisk:

      # mkinitcpio -p linux
      
    4. Configure the UEFI boot loader:

      # bootctl --path /boot install
      
    5. Configure grub. This is redundant given we also have a UEFI boot loader, but some people prefer a setup in which to boot from legacy BIOS.

      # grub-install --target=i386-pc --boot-directory=/boot --recheck /dev/sda
      # grub-mkconfig -o /boot/grub/grub.cfg
      
    6. Install a locale:

      # perl -pi -e 's!#en_US.UTF-8 UTF-8!en_US.UTF-8 UTF-8!' /etc/locale.gen
      # locale-gen
      
    7. Set up networking:

      # echo '[Match]' > /etc/systemd/network/wired.network
      # echo 'Name=en*' >> /etc/systemd/network/wired.network
      # echo '' >> /etc/systemd/network/wired.network
      # echo '[Network]' >> /etc/systemd/network/wired.network
      # echo 'DHCP=ipv4' >> /etc/systemd/network/wired.network
      # echo 'IPv4Forwarding=1' >> /etc/systemd/network/wired.network
      # echo 'IPv6Forwarding=1' >> /etc/systemd/network/wired.network
      
      # systemctl enable systemd-networkd systemd-resolved systemd-timesyncd
      
    8. Create a user with the right permissions and no password:

      # useradd -m ubosdev
      # chmod 755 ~ubosdev
      # passwd -d ubosdev
      # echo ubosdev ALL = NOPASSWD: ALL > /etc/sudoers.d/ubosdev
      # chmod 600 /etc/sudoers.d/ubosdev
      
    9. No root password:

      # passwd -d root
      
    10. Exit from the arch-chroot shell with ^D.

  11. Remainder of networking setup:

    # rm /mnt/etc/resolv.conf
    # ln -s /run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf
    
  12. Configure UEFI:

    • Loader configuration:

      # echo timeout 4 > /mnt/boot/loader/loader.conf
      # echo default arch >> /mnt/boot/loader/loader.conf
      
    • Boot entry configuration:

      # echo title Arch > /mnt/boot/loader/entries/arch.conf
      # echo linux /vmlinuz-linux >> /mnt/boot/loader/entries/arch.conf
      # echo initrd /initramfs-linux.img >> /mnt/boot/loader/entries/arch.conf
      # echo options root=PARTUUID=$(lsblk -o PARTUUID /dev/sda3 | tail -1 ) rw >> /mnt/boot/loader/entries/arch.conf
      
  13. Power off the virtual machine:

    # systemctl poweroff
    
  14. Remove the ISO file from the VM by clicking on the “[Optical Drive]” in “Storage” and selecting “Remove Disk From Virtual Drive”.

Note

IMPORTANT: Now set Settings / System / “Enable EFI (special OSes only)”, otherwise the newly installed VM won’t boot.

Note

As of February 2025, the Gnome UI may not come up with the default virtual graphics controller “VMSVGA”. That appears to be an upstream bug. So change the value for “graphics controller” to “VBoxSVGA”, which should work. Ignore the warning “Invalid settings detected”.

Remaining configuration

  1. Start the “ubosdev” VM again.

  2. At the console, log in as ubosdev. There is no password.

  3. Fix the locale (command won’t run earlier)

    % sudo localectl set-locale LANG=en_US.UTF-8
    
  4. Enable Gnome:

    % sudo systemctl enable gdm
    
  5. Power off the virtual machine:

    % sudo systemctl poweroff