Arch Linux Setup

"Back in my day..."

...Linux was 50MB. The entire server. Today? Eleventy-billion GB.

Well, that's the story with what I call Noob Linux (aka Ubuntu). I wrote off RedHat for years because of the insanity of the size (multiple CDs in the 90s). Today Ubuntu is the new RedHat in that regard 1.

Debian didn't buy into the bloat entirely; it's still nice. Yet, for me, there's a new kid on the block that was able to release my Debian death-grip: Arch Linux.

It's powerful. It's simple to use. It has a proper level of complexity to allow customization. The levels of porcelain and plumbing are quite balanced. Modern "Microsoft stack" developers get this. This is what C# is all about. This is what Azure is all about.

Now, how does one setup Arch linux? Answer: manually. Once you get through this, you've effectively paid your dues.

I'll give some commentary along the way. I generally follow the motto: if you can't repeat it, you can't do it. "I did it once" means nothing (this is why skill > experience). Don't rely on luck or "HOLY CRAP IT WORKS. NOBODY TOUCH IT".


You're going to be in the console. Linux uses a console. A GUI on Linux is not Linux. It's heresy. So, know these:

  • CTRL-A : beginning of line

  • CTRL-E : end of line

  • ESC then left-arrow : go back one word

  • ESC then right-arrow: go forward one word

  • If backspace gives you weird characters, hold CTRL while hitting backspace.

  • For passwords, use the numbers above your letters, not on the keypad. This might (donno) be the case in a few places.

You are not ready to be awesome.

Core Installation

When you first mount your disc and start your VM (it's a good assumption), you'll get a screen...

Arch Linux boot

...then a prompt. Let's run with that...

Arch Linux boot

First, let's setup our disk. This is the same thing you're going to do in Windows, but Linux is all about more control:

What disk do you want to play with? Let's find out:

# fdisk -l

Arch Linux fdisk -l

Note: this is for MBR. For GUID partitions, use gdisk.

See the /dev/sda and /dev/sdb stuff? Those are your disks: a and b (and c and d, etc...).

Look at the sizes deduce which one to use. You have to do the same on Windows. I've many disks. My boot SSD is much smaller than the others; that's how I know which disk to use.

Now, get into fdisk (it's a cli).

# fdisk /dev/sda

I'm going to demonstrate two different methods for the swap space. So skim both before playing with anything.

We want to create three partitions:

Regarding the 4GB swap partition, don't do the typical Microsoft developer "lol guidelines are for noooooooooooooooobs ima do what feels goodz. nobody has eeeeeeeever done this before so ima be a pioneerz" nonsense. Reference the size recommendations to see if 4G was right for you. RTFM! (that's reference the freggin manual-- nobody should ever read a manual like it's a Tolstoy novel)

Here are the commands in series: n, +500M, n, +4G, t, 2, 82, n, w.

You're going to use a lot of the defaults (e.g. partition number and start sector). Reference the following image sample:

Arch Linux create swap

Honestly, it's better if you play with this until it makes sense. Holding your hand won't help you in the long run. Learning comes from mistakes. Make those mistakes... and create VM snapshots.


  #(MBR; use gdisk for GUID paritions)
  (250 to 500M for boot, then RAM-sized swap, then /)
    (new partition)
    (change type)
    (82 swap)

Alternatively, you could use gdisk (for GUID partitions). Same idea.

Now... let's format these (ext3 is fine too):

# format partition 3    
mkfs.ext4 /dev/sda3

# format partition 1
mkfs.ext4 /dev/sda1

We are skipping partition 2 for now. That's a swap partition. That a different paradigm entirely.

Next, we will mount these.

The big partition first...

mount /dev/sda3 /mnt

We mount this as /mnt not / because are currently in a system that using /. Windows splits the world up into separate drives via letter whereas Unix/Linux (hereafter just "Linux") systems use a unified naming system. In Windows you can change drive letters; in Linux you change mount points.

With this mounted, we will create a place for boot partition to mount:

mkdir /mnt/boot

Then mount the boot partition:

mount /dev/sda1 /mnt/boot

What about the 4GB partition? That's the swap partition. We treat it differently. We create the swap area then use it.

mkswap /dev/sda2
swapon /dev/sda2

Havinag said this, there's another way to handle swap space, a more modern-world / VM / dev environment compatible method: don't create an entire swap partition.

The alternative to a swap partition is a swap file. In this paradigm, don't create a swap partition. Just create your 500M boot partition and your *MB data partition.

This works here because we are using ext4. Do not try this with btrfs.

Then, instead of creating a 4G monster swap partition, let's create a smaller 512M swap file:

fallocate -l 512M /swp

Let's make it so that only the file owner (in this case, the file creator: root) can read and write it:

chmod 600 /swp

Now we can do our other commands:

mkswap /swp
swapon /swp

See for more information.

We are now at the point where we install the base system. This is where it's really cool: you choose what to install. Personally, I've a few things I want to install right away so I don't have to deal with them later:

Here's my full command 2 3:

pacstrap -i /mnt base base-devel grub-bios openssh sudo

This command also tell you something important: whether you are on the Internet or not.

This is:

  • Base system
  • Basic dev tools
  • Kernely stuff
  • Boot manager
  • OpenSSH server
  • sudo (to run commands as root)

In case you're curious, here's what's inside base:

Arch Linux pacstrap base

We're almost done with the system setup.

We need to tell the system about our mount points. There's a tool for that.

genfstab -U -p /mnt >> /mnt/etc/fstab

The -U is important. Instead of mapping to /dev/sda1, you're telling the system to use a GUID. This removes the risk of things moving around. See SOF for more information.

If you did did the swap file method instead of the swap partition method: you also need to run the following:

echo "/swp none swap defaults 0 0" >> /mnt/etc/fstab

This will save make sure that /swp is used on boot.

General Linux advice: during any setup always ask yourself if it needs to be something that starts on boot. Different different Linux distros will have different setups. As you'll see in a moment, Arch Linux follows the "systemctl enable X" method.

Now we need to do some stuff that presupposes your system is mounted at /. So, we need to change our root:

arch-chroot /mnt

Now /mnt is /.

Change your password:


Let's create a boot optimizer:

mkinitcpio -p linux

Magic voodoo? No. That doesn't exist. That's fiction. Well, ok, a technology advanced enough... is magic... or something.

So, you've special drivers needed to use your disk. Where are the drivers? On... the... disk. Lovely. Well... computer architecture to the rescue:

Note: this is only for MBR. More modern systems use entirely different mechanics.

When you turn on a computer, at some point the bios is going to know what disk you want to boot from (you know, that setting you set in the F2/F10/del screen). When it gives to your hard drive, it will look in the first 512 bytes for some type of instruction of what to do. This 512 byte area is the Master Boot Record.

It's a fun activity to play with this 512 byte area. You can write a quick assembler tool to have your own mini-OS. Here's a fun tutorial... Its uses 16-bit registers (e.g. AX, BX), so it's a fun flashback for many of us.

Anyway... Linux has this little image that mkinitcpio creates that contains the drivers 'n stuff needed to boot your system. See reddit for more info.

OK, let's use the boot loader to tell it how to boot:

grub-install /dev/sda

Now to save the related config:

grub-mkconfig -o /boot/grub/grub.cfg

We're done. Let's exit chroot, unmount, and reboot. Remember to unmount your ISO / remove disc.

umount -R /mnt

Phase 2 Installation

Done? No. Sure you can boot, but you're about to login as root. Dude... no.

There's more to do, but I hate the idea of doing it on a console. In Hyper-V, you're not at a place where you can copy/paste. So, let's turn on networking and SSH into the server.

First, get the DHCP client doing something:


You'll probably see some scary looking "no carrier" nonsense. Ignore it.

Wait a few seconds. Then try ip addr. No IP yet? Wait longer and run ip addr again.

Now what? Well, we SSH into our server. But... we never made a user. Yeah, so, I cheat...

Edit your /etc/ssh/sshd_config. Add PermitRootLogin yes.

You can do this one in command with the following:

echo "
PermitRootLogin yes
" >> /etc/ssh/sshd_config

This will allow root to SSH into your server.

We'll remove this a little later. Chill out.

Anyway, now to start OpenSSH:

systemctl restart sshd

Just so we don't forget, let's set OpenSSH to auto start on boot:

systemctl enable sshd

You can now SSH into your server as root. Do it.

How? Answer: get an SSH client. The popular one is putty. I can't stand putty. I do keep it in my Windows folder for quick access from Win-R, but only as a backup. I personally prefer SecureCRT. I definitely find it worth the money.

The rest of this is mostly copy/paste.

Let's create a user with the appropriate groups:

useradd -m -g users -G wheel,storage,power -s /bin/bash user01

Change password:

passwd user01

That command asks you for a password, so you're not going to be able to simply paste it with a bunch of other subsequent commands into SSH.

However, the rest of this can be copy/pasted in:

# sudo users
echo "%wheel ALL=(ALL) ALL" >> /etc/sudoers

# hostname
echo "arch" > /etc/hostname

# localization
echo LANG="en_US.UTF-8" >> /etc/locale.conf
echo LC_COLLATE="C" >> /etc/locale.conf
echo LC_TIME="en_US.UTF-8" >> /etc/locale.conf
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
export LANG=en_US.UTF-8

# clock
ln -sf /usr/share/zoneinfo/America/Chicago /etc/localtime
hwclock --systohc --utc

# name servers
echo "nameserver
nameserver" > /etc/resolv.conf

# makeflags; 8 cores
echo "export MAKEFLAGS='-j 8'" >> /etc/bash.bashrc

The first command tells sudo to allow anyone in the wheel group to be able to run root commands. What's with the wheel name? SOF has an answer/theory for that one.

The only other command that probably requires commentary is the MAKEFLAGS line. This tells gcc the system how many cores to use. Many installations require gcc, including modules installed with Python's pip. So, don't think you're off the hook.

Almost done. Exit SSH. Reconnect. Login as the new user.

If that works, you can disable root for SSH.

Don't skip this step.

I don't like to prefix all my commands with sudo, so I just run bash as root:

sudo bash

The following command will remove the ssh-as-root line:

sed -i '/PermitRootLogin yes/d' /etc/ssh/sshd_config

For more info on the awesome tool called sed, there's a great compilation called USEFUL ONE-LINE SCRIPTS FOR SED that you should definitely bookmark. Also, visit the parent site. It's mostly art nonsense, but the docs section has good things.

Then restart OpenSSH:

systemctl restart sshd

At this point I like to install a bunch of other stuff. We do this with pacman. This is like apt-get in the Debian world. Actually, it's more like a merger of apt-get, apt-cache, and other things.

Here's what's in my usual toolbox:

pacman -S mlocate wget gcc openssh make mercurial git bc curl vim dnsutils whois net-tools lsof --noconfirm 

Some of that is already installed (e.g. openssh), but nobody cares. The list is more for my memory than for pacman.

Networking (dhcp)

The main thing left to do is to get DHCP to run automatically on boot.

Let's see what our interfaces are:

ip link

You could also use the following to get your interfaces:

ls /sys/class/net

You'll find that various parts of the file-system aren't really files, but very similar to the Windows WMI interfaces.

I've lo and eth0, yours might be enp3s0.

Now to enable DHCP for that interface:

systemctl enable dhcpcd@eth0.service

You could simply do this for everything, but let's be specific (you might want to play with static on a different interface).

systemctl enable dhcpcd.service

Networking (static)

Let's try static IPs now. It's actually a bit easier than you read in the docs:

echo "Description='A basic static ethernet connection'
Address=('' '' '' '')
" > /etc/netctl/home-static

netctl enable home-static

RedHat is the new Windows for many people; e.g. enterprise-class $$. CentOS (think of it as a free version of RedHat), though, is pretty sweet. I'd recommend CentOS for production servers.
You might not need base-devel. Most of it is already in base. Whatever.
You might see pacstrap -i /mnt base base-devel linux in some docs. The linux package is in the base package. If you ran the command with "base base-devel", then ran it with "linux", you'd see a 0MB net upgrade.