Alpine Linux 3.23 - 23mb ram | 71mb disk - guide
AnthonySmith
AdministratorProviderOG 




Minimising Alpine 3.23 on a KVM VPS ran on TierHive
This guide documents how to strip a freshly deployed Alpine 3.23 (should be fine on 3.22 also) VPS down to the minimum RAM and disk footprint without breaking it.
For those reading it running it outside of TierHive, please note this targets KVM-based VPS instances with a virtio-blk disk (/dev/vda), a single network interface, and a static IP assigned at deployment. If your disk is virtio-scsi (/dev/sda) there is one step that differs, noted inline.
Before
Fresh deploy, cloud-init has run, nothing changed yet, cant run apk, not enough free ram.
total used free shared buff/cache available
Mem: 91 38 25 2 28 47
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/vda 953.0M 164.4M 741.7M 18% /
Stage 1: Kernel Module Blacklist and Initramfs
The Alpine virt kernel loads modules that have no purpose on a headless KVM VPS: USB controllers, graphics drivers, cloud-specific network drivers for AWS and GCP, I2C buses, input devices, and more. Blacklisting them stops them loading on boot.
Some modules, however, are listed in the kernel modules= boot parameter and load before the blacklist is read. They also need removing from the initramfs features list. Do all three together so only one mkinitfs run is needed.
Create the blacklist:
cat > /etc/modprobe.d/blacklist-unnecessary.conf << 'EOF'
# Graphics (headless server)
blacklist drm
blacklist drm_kms_helper
blacklist simpledrm
blacklist virtio_gpu
blacklist fb
# KVM (not nesting VMs)
blacklist kvm
blacklist kvm_amd
blacklist kvm_intel
# Legacy devices
blacklist floppy
blacklist cdrom
blacklist sr_mod
blacklist isofs
# HID/input (headless)
blacklist hid
blacklist usbhid
blacklist hid_generic
blacklist psmouse
blacklist mousedev
# Wrong cloud drivers (not GCP/AWS)
blacklist gve
blacklist ena
# Force block DRM (blacklist alone does not work, ACPI triggers it)
install drm /bin/true
install drm_kms_helper /bin/true
install simpledrm /bin/true
install fb /bin/true
# USB (not needed on VPS)
blacklist usbcore
blacklist xhci_hcd
blacklist xhci_pci
blacklist usb_common
# I2C (not needed)
blacklist i2c_core
blacklist i2c_smbus
blacklist i2c_piix4
# Input (headless)
blacklist evdev
blacklist button
# Misc not needed
blacklist loop
blacklist ata_generic
blacklist i6300esb
blacklist qemu_fw_cfg
# Memory ballooning
blacklist virtio_balloon
# Hard block loop device (blacklist entry alone is not always sufficient)
install loop /bin/true
EOF
Strip the initramfs down to what a KVM virtio-blk instance actually needs. The default includes USB, CDROM, NVMe, RAID, SCSI, and cloud-specific drivers that will never be used:
sed -i 's/^features=.*/features="base ext4 virtio"/' /etc/mkinitfs/mkinitfs.conf
If your disk is virtio-scsi (
/dev/sda) keepscsiin the features list:features="base ext4 scsi virtio"
Fix the bootloader. The modules= parameter loads drivers early, before the blacklist runs. Remove usb-storage, ena, and gve from it. Also add the tuning parameters now so they are in place for the reboot at the end of this guide.
For /boot/extlinux.conf:
sed -i 's/,usb-storage,ext4,ena,gve/,ext4 ipv6.disable=1 audit=0 nowatchdog/' /boot/extlinux.conf
For /etc/update-extlinux.conf (persists the change across kernel updates):
sed -i 's/,usb-storage,ext4,ena,gve/,ext4/' /etc/update-extlinux.conf
sed -i 's/default_kernel_opts="/default_kernel_opts="ipv6.disable=1 audit=0 nowatchdog /' /etc/update-extlinux.conf
The parameters added:
ipv6.disable=1disables IPv6 at kernel level, removing the associated threads and memory allocations. Skip this if you use IPv6.audit=0disables the Linux audit subsystem. It serves no purpose on a VPS, runs a kernel thread, and pre-allocates slab memory.nowatchdogdisables the softlockup and hardlockup detectors.
Rebuild the initramfs:
mkinitfs
Stage 2: Replace OpenSSH with Dropbear
Dropbear is a minimal SSH server designed for low-resource systems. It is significantly smaller than OpenSSH and links against far fewer libraries. On a NAT VPS with a single exposed port, the switch must be done atomically: stop sshd and start dropbear in one command or you will lose access.
apk add dropbear
rc-service sshd stop && rc-service dropbear start
rc-update del sshd default
rc-update add dropbear default
apk del openssh openssh-client-common openssh-client-default openssh-keygen openssh-server openssh-server-common openssh-server-common-openrc openssh-server-pam openssh-sftp-server
Your session might drop. Reconnect on the same port as before.
Stage 3: Remove Cloud-Init and Python
Cloud-init runs once at first boot to configure the instance from the provider metadata. After that it does nothing. It pulls in Python 3 and a large set of dependencies. Since it has already run and the instance is configured, all of it can be removed, if you want to keep python, remove the '|py3-|python3|pyc' part in the command.
apk del $(grep "^P:" /lib/apk/db/installed | sed 's/^P://' | grep -E "^(cloud-init|cloud-utils|py3-|python3|pyc)")
Stage 4: Package Cleanup
Remove packages that serve no purpose on a running VPS. This covers NTP replacement, redundant shell and user management tools, hardware management utilities for hardware that does not exist, and network drivers for other cloud platforms.
Replace chrony with busybox ntpd. Chrony is a full-featured NTP implementation. Busybox includes a lightweight ntpd applet that requires no additional package:
rc-service chronyd stop
rc-update del chronyd default
rc-update add ntpd default
apk del chrony chrony-openrc
NTP is optional on KVM. The guest clock is disciplined by the hypervisor via
kvm-clock. On TierHive and similar platforms where the end user has no control over VM suspension or migration, the hypervisor keeps the clock accurate and ntpd adds no value. To skip NTP entirely, do not add the ntpd service.
Remove packages with no runtime use:
apk del bash sudo doas nvme-cli syslinux mtools numactl curl e2fsprogs-extra partx qemu-guest-agent qemu-guest-agent-openrc
qemu-guest-agentenables live snapshots and guest introspection from the hypervisor. If your hosting platform uses QEMU guest operations, keep it.
Remove orphaned libraries left behind by the packages above. Some will be retained by apk because the kernel package depends on them, which is expected:
apk del readline gdbm mpdecimal sqlite-libs yaml p11-kit libtasn1 gnutls nettle gmp libidn2 libunistring libexpat libedit libffi shadow tzdata libseccomp libncursesw libpanelw ncurses-terminfo-base
Remove dhcpcd. Once a VPS has a static IP assigned at deployment, the DHCP client is not needed:
apk del dhcpcd dhcpcd-openrc
Clear the package cache:
rm -rf /var/cache/apk/*
Stage 5: Service Cleanup
Disable services that have nothing to do on a KVM VPS:
rc-update del acpid boot
rc-update del hwclock boot
rc-update del swap boot
acpidhandles ACPI events such as power button presses. The hypervisor manages power state on a VPS, not the guest.hwclocksyncs the hardware clock at boot and shutdown. On KVM the RTC is virtualised and managed by the hypervisor.swapchecks for and activates swap devices. There is no swap.
Stage 6: System Tuning
Fix IPv6 sysctl errors
With ipv6.disable=1 set, the kernel no longer has IPv6 sysctl keys. The default Alpine sysctl file tries to set them anyway and produces errors at boot. Comment them out:
sed -i '/net\.ipv6/s/^/# /' /usr/lib/sysctl.d/00-alpine.conf
Prevent debugfs and tracefs from mounting
These kernel debug filesystems expose internal state and are not needed on a production VPS. Note that the memory for the tracing framework is allocated at kernel initialisation regardless; this only stops the filesystems from being accessible:
sed -i 's/mount -n -t debugfs/: #mount -n -t debugfs/' /etc/init.d/sysfs
sed -i 's/mount -n -t tracefs/: #mount -n -t tracefs/' /etc/init.d/sysfs
Sysctl tuning
The default network socket buffers are sized for servers under heavy load, not minimal VPS instances. Reduce them along with a few other settings:
cat > /etc/sysctl.d/10-minvps.conf << 'EOF'
# Reduce network socket buffers
net.core.rmem_default = 32768
net.core.wmem_default = 32768
net.core.rmem_max = 131072
net.core.wmem_max = 131072
net.core.netdev_max_backlog = 64
net.core.somaxconn = 128
# Reclaim inode and dentry caches more aggressively under memory pressure
vm.vfs_cache_pressure = 500
# Reduce PID table overhead
kernel.pid_max = 4096
# Dirty page writeback thresholds
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
# Disable watchdog
kernel.watchdog = 0
EOF
Switch syslogd to in-memory circular buffer
By default syslogd writes to /var/log/messages on disk. Switching to a circular buffer stores logs in memory instead. They remain accessible via logread. This removes the ongoing disk writes and the associated page cache overhead:
sed -i 's/SYSLOGD_OPTS="-t"/SYSLOGD_OPTS="-t -C64"/' /etc/conf.d/syslog
Reduce block device read-ahead
The kernel defaults to 8MB of read-ahead on the block device. On virtual storage this is wasted memory. 128KB is more than sufficient:
echo 128 > /sys/block/vda/queue/read_ahead_kb
cat > /etc/local.d/readahead.start << 'EOF'
#!/bin/sh
echo 128 > /sys/block/vda/queue/read_ahead_kb
EOF
chmod +x /etc/local.d/readahead.start
rc-update add local default
Reboot
reboot
After
total used free shared buff/cache available
Mem: 91 23 51 0 17 63
Swap: 0 0 0
Filesystem Size Used Available Use% Mounted on
/dev/vda 953.0M 71.9M 834.1M 8% /
RAM down from 38MB to 23MB. Disk down from 164.4MB to 71.9MB.
What Is Still Running
The only userspace processes after boot are syslogd (circular buffer mode), dropbear, and two getty processes: one on ttyS0 for serial console access and one on tty1 for the browser-based console panel.
The loaded kernel modules are exactly what the system requires: the virtio stack (virtio-blk, virtio-net, virtio-rng), the ext4 filesystem stack (ext4, jbd2, mbcache, crc16), hardware AES acceleration (aesni-intel, ghash-clmulni-intel, gf128mul), rng-core, net-failover, failover, and af-packet for raw socket support.
Notes for tinkerers:
Two kernel threads will appear in ps aux that look surprising: [scsi_eh_0] and [scsi_eh_1]. These are SCSI error handler threads compiled into the virt kernel. They are dormant and cannot be removed without a custom kernel.
Similarly, [watchdogd] persists despite nowatchdog in the cmdline. There is no /dev/watchdog device present and no watchdog module loaded. The thread does nothing.
I have done this on the VPS that runs https://backtogeek.com if you want to have a look as a performance indication, the whole thing runs on the 128mb, 1gb disk, low priority tier (the $0.10 /month $0.000135 /hour one) its a nothing site, just playing with rust to see how compact i can get a bespoke thingy running with tls support, it uses about 25mb in total to run that site, i will finish it one day and release it (open source) as a hackernews clone/micro blog platform
Anyway... hopefully that injects some low-end spirit into you!
More to come, its not meant to be a tierhive promotion, but it's what I have to work on, and it does not get much more low end than tierhive, this should work on pretty much any kvm host, if any hosts want to provide a VPS for me to test future crap on, I am happy to use your links instead!
version on the tierhive blog: https://tierhive.com/blog/tierhive-howto/how-to-run-alpine-with-just-23mb-ram
Coming soon, similar guide for Debian 13
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
Comments
Looks awesome!
Get some hosting at https://drserver.net .
Wow another level achieved ! Congrats
I believe in good luck. Harder that I work ,luckier i get.
This is genuinely impressive and excellent knowledge even if it's not on your host. Appreciate the effort here.
Amazing what the price of ram will do haha.
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
Completely unacceptable.
We accept Karma donations for the last flan. 🍮 affbrr
Also completely optional
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
Nobody cares about IPv6
Something good might come out of that situation in the end ;-)
Thank you for the dense write-up, not skimming on explanations.
One thing made me wonder,
What makes this useless for virtual storage? It is not that it does not interface with it while it is not a real block device (then 128 kB would not work either), so why is it beneficial on real storage, but not on virtual storage?
I guess I could have worded that better, you are right 128k does seem redundant also, but the problem is setting it to 0 does have a performance hit due to the guest<>host translation layer in KVM best guess, I sort of made an intuitive guess.
The seek latency problem read ahead solves doesn't really exist in a virtualized environment. It's just a kernel default relic for spinning disks I think that pre dates modern virtualization, but just overlooked because these days ... Who cares about 8mb, but it does need to exist it just is never likely to exceed 128k, you could probably go lower, but that seemed fair and safe.
For most hosts no one cares, but for TierHive if 100 customers use 8-16mb less, that can make a difference.
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
Established LES members can afford premium IPv4 connectivity and won't settle for cheaper, mass-market options
☰ VDS & Storage — Budget AMD EPYC VDS (ref) from $4/m / Big HDD VPS (ref) from $2/TB/mo / EPYC/Gold/Platinum dedis (ref) w/ GPU support
128mb remote desktop guide built on top of this should be finished tomorrow
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
Instructions unclear, d**k stuck in fan:
(Play more "Fallout" people!)
Waiting for debian version
Waiting for slax with GUI version.
I mean my first linux "love" was puppy linux as portable OS run from thumb-drive. And once they moved to debian, I found Porteus and used that as my new portable OS...
To be honest, this project and the state of the world gave me a bit of passion/lowend sprit back, everyone got to addicted to bloated software on cheap ram, and nice desktops.
I am frankly sad that even stripped to the BONE alpine needs 37mb for the kernel alone and 23mb userspace, thats outragious!
So I got my pen and notepad out (Yes I still use them), and started doing some research, I think I can PROBABLY (50/50) make my own custom kernel designed JUST for KVM with really norrow requirements, assume virtio only, dont even bother compiling in swap support etc, I think I can get the kernel down to about 6 - 8mb
Then the issue with alpine is its world groups are to broad, and I dont want to start recompiling stuff on a live os as a solution and then fighting working outside a package manager.
So, I came up with the concept of 'bone kvm linux' i think i can default to dropbear, rc-local, busybox, fine tune everything and get userspace within 2 - 4mb, the goal for cli mode actually being 8mb total if possible, then 16mb for a GUI using framebuffers only no full blown xorg, its assumed its running in kvm.
Then obviously it needs to be useful, so I need a repo, but it will ONLY support 1 thing for a thing, like 1 email client, 1 browser, 1 terminal, obviously add in support to compile your own stuff like old school bsd ports style, probably need to look at dillo+some sort of js proxy.
So yeah, my new passion project is about 5 sheets of A5 notes now, and I will probably never finish it, but I want a windows 98 style linux dstro that runs on a 6.x kernel and can be installed and run on KVM only. need to think hard about the package manager side of things I guess. obviously I dont want to maintain my own versions of php/node nginx etc and it needs to be useful.
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
It's called openbsd, Ant.
Here's my old kernel config that used about 8mb ram.
https://web.archive.org/web/20191019081859/http://bsd01.ny.bangpath.tech/TINY.txt
"It's a hard life- to be a stick insect." - Karl Pilkington
Nice, you can probably cut that back more, unless you were also using it on physical hardware.
While I get it, being a better Unix is a good thing, I suppose, but I want to make something that does not feel like a punishment to use
or scares people because "bsd"
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
I made it a bit agnostic- this version works on virtio and scsi/e1000 KVM builds. Never know if you can get a "pure" virtio unless you manage it yourself- and that's rare, because it requires effort.
Alpine with no tools, stripped bare, and IPv6 removed isn't punishment?
"It's a hard life- to be a stick insect." - Karl Pilkington
Yeah, I am talking about from scratch, not alpine, just borrowing rc-local, busybox and dropbear
Anyway I feel optimistic about it now, but I am only ever a news cycle or doctors letter away from a change of mind.
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
So, after a couple of years after burning out, then selling out, you've kind of come back and want to build a low resource distribution from scratch.
You might as well just break into the chronic alcoholism now and cut out the middleman.
"It's a hard life- to be a stick insect." - Karl Pilkington
@AnthonySmith @WSS @cmeerw @Hosteroid
The official NetBSD Guide, section 36.2. Creating custom live disk images describes how to create a custom NetBSD live image for embedded purposes.
I haven't followed the tiny BSD discussions, but I hear that crunchgen(1) typically plays a part.[^1]
If I understand right (doubtful) it seems like a BSD kernel plus a few desired parts of userland might get down to about 4 MB?
Someone might make small images on our Hosteroid LES Community Server?
Best wishes!
[^1] https://news.ycombinator.com/item?id=18780218
@Not_Oles netbsd ain't it. It's educational and bloated on purpose.
"It's a hard life- to be a stick insect." - Karl Pilkington
@AnthonySmith checkout microvm before you possibly reinvent the wheel. We think they did what you want to achieve.
DM us for private tracker invite.
Oh thanks, will do
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
@somik @AnthonySmith what's with the need/want for a GUI? Isn't that kinda superfluous in a VM?
Just a bit of fun, the art of the possible.
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
No init. Just DOS.
"It's a hard life- to be a stick insect." - Karl Pilkington
That's a good motivation. Please don't take this the wrong way, I'm in no way trying to rain on your parade, but how would this differ from Tiny Core Linux?
A few ways I suppose.
Virtio native / only.
Persistent as default not a live distro.
Email client availability.
Browser with js support.
Not designed to be compatible with a wide range of hardware.
Framebuffer only.
TCL is amazing but is designed to be live primarily and support a huge hardware set, so even tinycore got bloated and realistically, it struggles to be a meaningful desktop at 128mb
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
Is that even theoretically possible with 128 MB?
Ofcourse! As long as you dont open youtube
I have an idea or 2 on how to do it
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
It supports javascript!!!
Well yeah
I did just see a video of someone running powerfox on a really bad G4 Mac playing YouTube fine, quite impressive.
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
have you tried boot it up on 64mb ram vm?
yep, backtogeek.com is actually running on a 64mb VPS now.
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
Some people here running their public site on 64mb RAM while I'm running my private home server on 128GB DDR4 RAM...
Haha, well to be fair I have been spec'ing up a 1TB ram dual E5-2699v4 on eBay with a ton of spinners to have a local internet, software and repo cache and llm, because I think the internet as we know it is going in a very bad direction.
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
Hahaha, let's fork internet. Replace bulky servers with lean 48 MB half core variants while we're at it.
Mine is dual E5-2695v4 with 128GB DDR4 at 2400 Hz with a Chinese Machinist E-ATX motherboard. Got the cpu+ram+mobo combo at 500 SGD (about 400 USD?)
I didn't go for 2699s due to the absurd price and high TDP. I mean my main use case is idling and using it on and off for home use...
If it was still before the RAM price hike, I would go for 1TB for bragging rights, but can't afford it anymore... Don't really have a use case anyway.
Did the following on @Neoon's microlxc alpine container. Managed to bring down the usual 20mb to about 5mb
Free NAT KVM | Free NAT LXC
I bloody love containers (not docker)
I was officially the words biggest OpenVZ hater for a while, then I realised the power of the dark side.
Such a shame OpenVZ died.
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
Since I always had issues with OpenVZ configs, i avoided it. However ever since I started using proxmox and it's LXC containers, I've been using it for most of my deployments, except for VMs that need to be isolated...
As for docker, I am ashamed to admit that it is still the best way to distribute your program/app and be sure that it runs for everyone. I convert most of my script/programs/apps to docker and deploy them across my servers.
Cool!
Is there a specific project, or just the technology in general that you recommend?
So far the qemu microvm implementation is the most interesting to me.
DM us for private tracker invite.
@AnthonySmith sorry to revive this old thread~ I wanted to push it a step further by enabling Btrfs but I am getting this:
Is there any chance to get the block size of subsequent containers @ 4096 block size? (I didn't want to open a ticket for that, I thought it would be more appropriate here)
💩 VirCrap 💩
You will need to install alpine via netbooy.xyz if you want to do that, we use the official OS distro cloud images, alpine uses 1024 block size on the file system as standard on cloud images, not a lot I can do about it.
Maybe you can change it via rescue mode with a chroot and copy/write .. but it would be faster just to install from scratch tbh.
TierHive - Hourly VPS - NAT Native - /24 per customer - DE, UK, SG, CA, USA x4, FR x2, AU, PL, NL, JP
FREE tokens on sign up, try before you buy. | Static Hosting Free for life: https://tierhive.com/static-hosting/
Butthole
"It's a hard life- to be a stick insect." - Karl Pilkington