installing nixos on oracle free tier
don't care about the writeup? skip to the installation instructions
always free
at the time of writing this oracle cloud offers a suprisingly generous always free tier. you get:
- AMD: 2 VMs with 1/8 OCPU and 1GB RAM each
- Arm (Ampere A1): 24GB RAM and 4 OCPU, which can be split across 1-4 VMs
in total that is 26GB of RAM and 4.25 OCPUs - completely free! (assuming you can get a spot. as you might expect, this offering is extremely popular.)
that's awesome - what's the catch?
there's no real catch - but one major limitation is that nixos isn't available as a default image.
not to worry though - i've written a few simple scripts that lets you install nixos from just about any other os that has a bash shell.
installation
step 1
ssh into your vm and run the following command:
curl -sSL https://salad.newty.dev/guides/oracle/kexec.sh | sudo bash
this will download and run a script that installs a nixos installation environment matching your vm's architecture, then reboots into it using kexec.
warning
you'll be disconnected from ssh once the system reboots.
step 2
ssh back into your machine, this time as the root
user. run the following commands:
curl -sSL https://salad.newty.dev/guides/oracle/install.sh -o install.sh
bash install.sh "<ssh key>" "<swap size>"
replace <ssh key>
with your public ssh key and <swap size>
with the swap size you'd like (e.g. 1G
or 512M
).
this script will:
- partition and format the disk
- configure and install a minimal nixos system
- setup networking and ssh access
- enable your specified ssh key
- reboot into your fresh nixos installation
conclusion
once you've followed the steps above, you'll have a fully functional nixos installation running on oracle cloud.
from here, you can configure it just like any other nixos system.
appendix: script contents
just for transparency, here are all of the files installed to your virtual machine when running the scripts:
kexec.sh
#!/bin/bash
ARCH=$(uname -m)
echo "Detected architecture: $ARCH"
case $ARCH in
aarch64)
INSTALLER="https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-aarch64-linux.tar.gz"
;;
x86_64)
INSTALLER="https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz"
;;
esac
sudo bash -c "
curl -L '$INSTALLER' | tar -xzf- -C /root
/root/kexec/run
"
install.sh
#!/bin/bash
# check if ssh key and swap size are provided
if [ $# -lt 2 ]; then
echo "Usage: $0 '<ssh-public-key>' '<swap-size>'"
echo "Example: $0 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGm... user@host' '1G'"
echo "Swap size examples: 1G, 2G, 512M"
exit 1
fi
SSH_KEY="$1"
SWAP_SIZE="$2"
# --- partition ---
# see: https://mdleom.com/blog/2021/03/09/nixos-oracle/
# uses 1G swap by default
fdisk /dev/sda << EOF
g
n
1
+512M
n
2
-${SWAP_SIZE}
n
3
t
1
uefi
p
w
EOF
fdisk -l /dev/sda
# --- format ---
mkfs.fat -F 32 -n boot /dev/sda1
mkfs.ext4 -L nixos /dev/sda2
mkswap -L swap /dev/sda3
# --- mount ---
mkdir -p /mnt
mount /dev/disk/by-label/nixos /mnt
mkdir -p /mnt/boot
mount /dev/disk/by-label/boot /mnt/boot
swapon /dev/sda3
# --- configuration ---
nix-channel --add https://nixos.org/channels/nixos-unstable nixpkgs
nix-channel --update
nixos-generate-config --root /mnt
curl -L https://salad.newty.dev/guides/oracle/configuration.nix -o /mnt/etc/nixos/configuration.nix
sed -i "s|<ssh key>|$SSH_KEY|g" /mnt/etc/nixos/configuration.nix
# --- installation ---
nixos-install
reboot
configuration.nix
{
pkgs,
...
}:
{
imports = [
./hardware-configuration.nix
];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "nixos";
networking.networkmanager.enable = true;
time.timeZone = "Europe/London";
users.users.newt = {
isNormalUser = true;
extraGroups = [ "wheel" ];
};
environment.systemPackages = with pkgs; [
curl
git
];
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = [
"<ssh key>"
];
system.stateVersion = "25.11";
}