Skip to content

Instantly share code, notes, and snippets.

@ishad0w
Last active September 3, 2026 10:13
Show Gist options
  • Select an option

  • Save ishad0w/10a536f82c79d3b890d04243634df806 to your computer and use it in GitHub Desktop.

Select an option

Save ishad0w/10a536f82c79d3b890d04243634df806 to your computer and use it in GitHub Desktop.
Debian 12 on Oracle Cloud (Free Tier) - (AMD64/ARM64)

Requirements:

⚠️ Only FRESH and CLEAN instances are supported. Ubuntu 22.04 (Minimal) images ONLY ⚠️

⚠️ Also you NEED to temporarily open the connection to the 1022 port in Security List / Ingress Rules for your VCN ⚠️

⚠️ After transformation YOU get a clean Debian 12 instance. All other data will be lost. ⚠️

The tmpfs partition is limited to 700m for x86_64 (free tier) compatibility.

Transformation from Ubuntu to Debian (x86_64/arm64) steps:

  1. Download the script (to YOUR local machine with SSH (public key) access to a remote Oracle Cloud Instance)
wget https://gist.githubusercontent.com/ishad0w/10a536f82c79d3b890d04243634df806/raw/oci_ubuntu_to_debian.multiarch.sh
  1. Make it executable.
chmod +x oci_ubuntu_to_debian.multiarch.sh
  1. Replace '1.1.1.1' with your OCI Instance DNS name or IP address:
./oci_ubuntu_to_debian.multiarch.sh 1.1.1.1
  1. Profit.
#!/bin/bash
trap "exit" INT
echo -e "\nHost:"
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -p 22 ubuntu@$1 \
'uname -a && arch && uptime && sudo touch /home/ubuntu/.hushlogin /root/.hushlogin'
echo -e "\nAdding temporary SSH-key for Ubuntu root user..."
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -p 22 ubuntu@$1 \
'sudo cat /home/ubuntu/.ssh/authorized_keys | sudo tee /root/.ssh/authorized_keys'
echo -e "\nSystem trimming..."
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -p 22 root@$1 -T <<'EOL'
export DEBIAN_FRONTEND=noninteractive
snap remove --purge oracle-cloud-agent && snap remove --purge core18
apt-get purge -y linux-* lxc* lxd* vim* snapd* python*
apt-get update && apt-get install -y lsof
apt-get -y autoremove --purge
apt-get -y autoclean
rm -rf /var/log/* /var/lib/apt/* /var/cache/apt/*
df -h
EOL
echo "Check free space! for "/" mountpoint. <=700mb"
waittime=15
while [ $waittime -gt 0 ]; do
echo -ne "$waittime\033[0K\r"
sleep 1
: $((waittime--))
done
echo -e "\nPreparing system..."
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -p 22 root@$1 -T <<'EOL'
cd /
echo "Mounting tmpfs..."
mount -t tmpfs -o size=700m tmpfs mnt && tar --one-file-system -c . | tar -C /mnt -x
mount --make-private -o remount,rw /
mount --move dev mnt/dev && mount --move proc mnt/proc
mount --move run mnt/run && mount --move sys mnt/sys
sed -i "/^[^#]/d;" mnt/etc/fstab
echo "tmpfs / tmpfs defaults 0 0" >> mnt/etc/fstab
cd mnt && mkdir old_root
mount --make-private /
sleep 2
echo "Changing the root mount..."
unshare -m
pivot_root . old_root
sleep 5
echo "Starting SSH on 1022..."
iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 1022 -j ACCEPT
nohup /usr/sbin/sshd -D -p 1022 > /dev/null 2>&1 &
EOL
echo -e "\nFlashing the Debian image..."
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -p 1022 root@$1 -T <<'EOL'
echo "Arch is $(arch)..."
IMAGEMIRROR="https://cloud.debian.org/images/cloud/bookworm"
IMAGEVERSION="debian-12-genericcloud"
IMAGEBUILD="20240701-1795"
for i in agetty dbus-daemon atd iscsid rpcbind unattended-upgrades; do pkill $i; done; kill 1; umount -l /dev/sda1
if [ $(arch) = "x86_64" ]
then curl -L $IMAGEMIRROR/$IMAGEBUILD/$IMAGEVERSION-amd64-$IMAGEBUILD.tar.xz | tar -OJxvf - disk.raw | dd of=/dev/sda bs=1M;
elif [ $(arch) = "aarch64" ]
then curl -L $IMAGEMIRROR/$IMAGEBUILD/$IMAGEVERSION-arm64-$IMAGEBUILD.tar.xz | tar -OJxvf - disk.raw | dd of=/dev/sda bs=1M;
else
echo Unsported architecture!
fi
sleep 5
echo "Syncing changes to the block storage..."
sync
sleep 5
echo "Rebooting into Debian!"
nohup sh -c 'echo "1" > /proc/sys/kernel/sysrq && sleep 5 && echo "b" > /proc/sysrq-trigger' > /dev/null 2>&1 &
EOL
echo -e "\nWaiting until Debian starts... (3 min)"
waittime=180
while [ $waittime -gt 0 ]; do
echo -ne "$waittime\033[0K\r"
sleep 1
: $((waittime--))
done
echo -e "\nAdding temporary SSH-key for Debian root user..."
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -p 22 debian@$1 \
'sudo cat /home/debian/.ssh/authorized_keys | sudo tee /root/.ssh/authorized_keys'
echo -e "\nDebian inititialisation..."
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -p 22 root@$1 -T <<'EOL'
export DEBIAN_FRONTEND=noninteractive
echo "deb http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
deb http://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
deb http://deb.debian.org/debian/ bookworm-backports main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security/ bookworm-security main contrib non-free non-free-firmware" > /etc/apt/sources.list
apt-get update && apt-get install -y locales-all
rm -rf /root/.ssh/
sync
reboot
EOL
sleep 10
echo -e "\nDone!"
@cosmicdan

Copy link
Copy Markdown

For those who come across this in 2026, this doesn't work anymore with the available Ubuntu 22.04 images. I managed to get Debian 12 installed by instead uploading a custom image, specifically the Debian 12 "genericcloud" qcow image. You can find guides online about how to upload the image to block storage first and then creating a custom image from it. Note that for Arm64 instances, I also had to change the Custom Image settings to use UEFI 64 (disable BIOS completely) and also disable all hardware options except PARAVIRTUALIZED, otherwise the instance wasn't accessible. Might also require the default OCI agents enabled too to ensure your custom ssh key is imported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment